NVIDIA / VisRTX

NVIDIA OptiX based implementation of ANARI

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Windows: missing #include <algorithm>

oroppas opened this issue · comments

Build fails on Windows because std::clamp, std::transform, and std::for_each cannot be found.
Theses functions are defined in <algorithm>. One possible solution is to #include <algorithm> in Object.h:

diff --git a/device/Object.h b/device/Object.h
index 49004aa..36ed78e 100644
--- a/device/Object.h
+++ b/device/Object.h
@@ -40,6 +40,7 @@
 #include "gpu/gpu_math.h"
 #include "gpu/gpu_objects.h"
 // std
+#include <algorithm>
 #include <map>
 #include <memory>
 #include <string_view>

The followings are the details of the failed compilations.

std::clamp

[1/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\light\Point.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/scene/light/Point.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\scene\light\Point.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\scene\light\Point.cpp
D:\packages\visrtx\VisRTX\device\scene\light\Point.cpp(40): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\functional(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\light\Point.cpp(40): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\scene\light\Point.cpp(42): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'
[2/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\light\Directional.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/scene/light/Directional.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\scene\light\Directional.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\scene\light\Directional.cpp
D:\packages\visrtx\VisRTX\device\scene\light\Directional.cpp(41): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\functional(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\light\Directional.cpp(41): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\scene\light\Directional.cpp(43): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'
[9/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\array\Array1D.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/array/Array1D.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\array\Array1D.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\array\Array1D.cpp
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(59): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(59): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(59): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(61): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(61): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\array\Array1D.cpp(61): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'

std::transform

[5/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\surface\geometry\Spheres.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/scene/surface/geometry/Spheres.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\scene\surface\geometry\Spheres.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\scene\surface\geometry\Spheres.cpp
D:\packages\visrtx\VisRTX\device\scene\surface\geometry\Spheres.cpp(85): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\array(20): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\surface\geometry\Spheres.cpp(85): error C3861: 'transform': identifier not found
[7/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\Group.cpp.obj
[7/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\Group.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/scene/Group.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\scene\Group.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\scene\Group.cpp
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(277): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(277): error C3861: 'transform': identifier not found
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(287): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(287): error C3861: 'transform': identifier not found
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(299): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(299): error C3861: 'transform': identifier not found
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(308): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\Group.cpp(308): error C3861: 'transform': identifier not found

std::for_each

[8/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\array\ObjectArray.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/array/ObjectArray.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\array\ObjectArray.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(74): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(74): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(75): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(75): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(85): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(85): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(85): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(87): error C2039: 'clamp': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(87): error C2672: 'visrtx::clamp': no matching overloaded function found
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(87): error C2780: 'range_t<T>::element_t visrtx::clamp(const range_t<T>::element_t &,const visrtx::range_t<T> &)': expects 2 arguments - 3 provided
D:\packages\visrtx\VisRTX\device\gpu/gpu_math.h(107): note: see declaration of 'visrtx::clamp'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(186): error C2039: 'transform': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(202): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(202): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(203): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\array\ObjectArray.cpp(203): error C3861: 'for_each': identifier not found
[13/35] Building CXX object device\CMakeFiles\anari_library_visrtx.dir\scene\World.cpp.obj
FAILED: device/CMakeFiles/anari_library_visrtx.dir/scene/World.cpp.obj
C:\PROGRA~1\MIB055~1\2022\COMMUN~1\VC\Tools\MSVC\1431~1.311\bin\Hostx64\x64\cl.exe  /nologo /TP -DVISRTX_VERSION_MAJOR=0 -DVISRTX_VERSION_MINOR=4 -DVISRTX_VERSION_PATCH=0 -Danari_library_visrtx_EXPORTS -Dvisrtx_EXPORTS -ID:\packages\visrtx\VisRTX\device -ID:\packages\visrtx\build\device -external:I D:\local\include -external:I D:\packages\visrtx\VisRTX\external\glm\include -external:I "C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0\include" -external:I "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.6\include" -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /Zi /Ob0 /Od /RTC1 -MDd -std:c++17 /showIncludes /Fodevice\CMakeFiles\anari_library_visrtx.dir\scene\World.cpp.obj /Fddevice\CMakeFiles\anari_library_visrtx.dir\ /FS -c D:\packages\visrtx\VisRTX\device\scene\World.cpp
D:\packages\visrtx\VisRTX\device\scene\World.cpp(256): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(256): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\scene\World.cpp(289): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(289): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\scene\World.cpp(317): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(317): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\scene\World.cpp(332): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(332): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\scene\World.cpp(349): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(349): error C3861: 'for_each': identifier not found
D:\packages\visrtx\VisRTX\device\scene\World.cpp(364): error C2039: 'for_each': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.31.31103\include\memory_resource(31): note: see declaration of 'std'
D:\packages\visrtx\VisRTX\device\scene\World.cpp(364): error C3861: 'for_each': identifier not found

I've got potential fixes for #29, #30, and this one on the jda/windows_fixes branch. Would you mind giving it a try to verify your build environment?

Note that this will require the current main branch of the ANARI-SDK to build. Both the SDK and VisRTX have releases coming up very soon!

Thanks for the fixes! I had to incorporate one minor fix:

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 58f1032..b3eb8f0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -66,7 +66,7 @@ mark_as_advanced(glm_DIR)
 add_library(glm_visrtx INTERFACE IMPORTED)
 target_link_libraries(glm_visrtx INTERFACE glm::glm)
 if(WIN32)
-  target_compile_definitions(glm_visrtx _USE_MATH_DEFINES NOMINMAX)
+  target_compile_definitions(glm_visrtx INTERFACE _USE_MATH_DEFINES NOMINMAX)
 endif()

 # Other included dependencies

Otherwise, I've got

CMake Error at CMakeLists.txt:70 (target_compile_definitions):
  target_compile_definitions called with invalid arguments

or full log

D:\packages\visrtx>cmake   -G Ninja   -B build   -S windows_fixes   -DVISRTX_BUILD_INTERACTIVE_EXAMPLE=OFF   -DVISRTX_BUILD_TESTS=ON   -Danari_DIR="D:\local\lib\cmake\anari-0.2.0"   -Dglfw3_DIR="D:\packages\glfw\lib\cmake\glfw3"   -DOptiX7_ROOT_DIR="C:\ProgramData\NVIDIA Corporation\OptiX SDK 7.5.0"
-- CMake version: 3.22.22022201-MSVC_2
CMake Error at CMakeLists.txt:69 (target_compile_definitions):
  target_compile_definitions called with invalid arguments


CMake Error at CMakeLists.txt:70 (target_compile_definitions):
  target_compile_definitions called with invalid arguments


-- CMake version: 3.22.22022201-MSVC_2
-- Configuring incomplete, errors occurred!
See also "D:/packages/visrtx/build/CMakeFiles/CMakeOutput.log".
See also "D:/packages/visrtx/build/CMakeFiles/CMakeError.log".

D:\packages\visrtx>cmake --build build
ninja: error: loading 'build.ninja': The system cannot find the file specified.

Yup, that was a silly typo on my part, thanks for all the help! I amended the commit with these fixes and merged them to next_release. I'll take your bug reports as reason to prioritize CI on our side, but for now it looks like you're good to go?

Yes! The one last remaining issue is Visual C++'s internal bug :)
We're good to go as far as VisRTX is concerned.
Thanks for the quick fixes!