diff options
5 files changed, 294 insertions, 69 deletions
diff --git a/var/spack/repos/builtin/packages/paraview/package.py b/var/spack/repos/builtin/packages/paraview/package.py index bd763c15d1..4b7f77e216 100644 --- a/var/spack/repos/builtin/packages/paraview/package.py +++ b/var/spack/repos/builtin/packages/paraview/package.py @@ -149,6 +149,9 @@ class Paraview(CMakePackage, CudaPackage): # Broken H5Part with external parallel HDF5 patch('h5part-parallel.patch', when='@5.7:5.7.999') + # Broken downstream FindMPI + patch('vtkm-findmpi-downstream.patch', when='@5.9.0') + def url_for_version(self, version): _urlfmt = 'http://www.paraview.org/files/v{0}/ParaView-v{1}{2}.tar.{3}' """Handle ParaView version-based custom URLs.""" diff --git a/var/spack/repos/builtin/packages/paraview/vtkm-findmpi-downstream.patch b/var/spack/repos/builtin/packages/paraview/vtkm-findmpi-downstream.patch new file mode 100644 index 0000000000..31356ea51a --- /dev/null +++ b/var/spack/repos/builtin/packages/paraview/vtkm-findmpi-downstream.patch @@ -0,0 +1,51 @@ +From 5bf0eff1563820d7c997649da372ab003fd4af81 Mon Sep 17 00:00:00 2001 +From: Chuck Atkins <chuck.atkins@kitware.com> +Date: Mon, 15 Feb 2021 13:59:50 -0500 +Subject: [PATCH] CMake: Fix FindMPI getting consumed by newer CMake versions + +--- + CMake/patches/FindMPI.cmake | 11 +++++++++++ + CMakeLists.txt | 7 ++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + create mode 100644 CMake/patches/FindMPI.cmake + +diff --git a/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake b/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake +new file mode 100644 +index 000000000..a4ed44f04 +--- /dev/null ++++ b/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake +@@ -0,0 +1,11 @@ ++#------------------------------------------------------------------------------# ++# Distributed under the OSI-approved Apache License, Version 2.0. See ++# accompanying file Copyright.txt for details. ++#------------------------------------------------------------------------------# ++ ++# This module is already included in new versions of CMake ++if(CMAKE_VERSION VERSION_LESS 3.15) ++ include(${CMAKE_CURRENT_LIST_DIR}/3.15/FindMPI.cmake) ++else() ++ include(${CMAKE_ROOT}/Modules/FindMPI.cmake) ++endif() +diff --git a/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt b/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt +index e907495f3..fa464ab8d 100644 +--- a/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt ++++ b/VTK/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt +@@ -277,9 +277,14 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES) + FILES + ${VTKm_SOURCE_DIR}/CMake/VTKmCMakeBackports.cmake + ${VTKm_SOURCE_DIR}/CMake/FindTBB.cmake +- ${VTKm_SOURCE_DIR}/CMake/patches/3.15/FindMPI.cmake ++ ${VTKm_SOURCE_DIR}/CMake/patches/FindMPI.cmake + DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR} + ) ++ install( ++ FILES ++ ${VTKm_SOURCE_DIR}/CMake/patches/3.15/FindMPI.cmake ++ DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}/3.15 ++ ) + + # Install support files. + install( +-- +2.24.2 + diff --git a/var/spack/repos/builtin/packages/sensei/package.py b/var/spack/repos/builtin/packages/sensei/package.py index e379aed3e2..703b854c5c 100644 --- a/var/spack/repos/builtin/packages/sensei/package.py +++ b/var/spack/repos/builtin/packages/sensei/package.py @@ -18,7 +18,9 @@ class Sensei(CMakePackage): git = "https://gitlab.kitware.com/sensei/sensei.git" maintainers = ['sshudler'] - version('master', branch='master') + version('develop', branch='develop') + version('3.2.1', sha256='8cde9ac5313e6c03fd793d24a6f285b60cca14cacfc83931f11d878163ee9d5b') + version('3.2.0', sha256='fe4fe294c17e469bfd1824130648a7d25b1fa771904b5c5edc37b820d090e224') version('3.1.0', sha256='9a3e6d0d5bb6170ee666586435434da1708b3876fd448b9d41142571ed9da939') version('3.0.0', sha256='0aabbea03ade9947c88fc0aa6d3cbaf3c8267e8504e384a041445678a95e58eb') version('2.1.1', sha256='8a27ebf133fef00a59e4b29433762e6560bf20214072de7808836eb668bb5687') @@ -27,12 +29,15 @@ class Sensei(CMakePackage): version('1.1.0', sha256='e5a4ba691573ff6c7b0d4793665e218ee5868ebcc0198915d1f16a4b7b92a368') version('1.0.0', sha256='bdcb03c56b51f2795ec5a7e85a5abb01d473d192fac50f2a8bf2608cc3564ff8') + variant('shared', default=True, description='Enables shared libraries') variant('sencore', default=True, description='Enables the SENSEI core library') - variant('catalyst', default=True, description='Build with ParaView-Catalyst support') + variant('ascent', default=False, description='Build with ParaView-Catalyst support') + variant('catalyst', default=False, description='Build with ParaView-Catalyst support') variant('libsim', default=False, description='Build with VisIt-Libsim support') - variant('vtkio', default=True, description='Enable adaptors to write to VTK XML format') - variant('adios', default=False, description='Enable ADIOS adaptors and endpoints') + variant('vtkio', default=False, description='Enable adaptors to write to VTK XML format') + variant('adios2', default=False, description='Enable ADIOS2 adaptors and endpoints') variant('hdf5', default=False, description='Enables HDF5 adaptors and endpoints') + variant('vtkm', default=False, description='Enable VTKm adaptors and endpoints') variant('python', default=False, description='Enable Python bindings') variant('miniapps', default=True, description='Enable the parallel 3D and oscillators miniapps') variant('cxxstd', default='11', values=('11', '14', '17'), multi=False, description='Use the specified C++ standard when building.') @@ -40,20 +45,34 @@ class Sensei(CMakePackage): # All SENSEI versions up to 2.1.1 support only Python 2, so in this case # Paraview 6 cannot be used since it requires Python 3. Starting from # version 3, SENSEI supports Python 3. - depends_on("paraview@5.5.0:5.5.2+python+mpi+hdf5", when="@:2.1.1 +catalyst") - depends_on("paraview@5.6:+python3+mpi+hdf5", when="@3: +catalyst") - depends_on("visit", when="+libsim") - depends_on("vtk", when="+libsim") + depends_on("paraview@5.5.0:5.5.2+mpi+hdf5", when="@:2.1.1 +catalyst") + depends_on("paraview@5.5.0:5.5.2+python+mpi+hdf5", when="@:2.1.1 +catalyst+python") + depends_on("paraview@5.6:5.7+mpi+hdf5", when="@3:3.2.1 +catalyst") + depends_on("paraview@5.6:5.7+python3+mpi+hdf5", when="@3:3.2.1 +catalyst+python") + depends_on("paraview+mpi+hdf5", when="+catalyst") + depends_on("paraview+python3+mpi+hdf5", when="+catalyst+python") + depends_on("visit~gui~python", when="+libsim") + depends_on("vtk@8.1.0:8.1.2", when="+libsim") depends_on("vtk", when="~libsim ~catalyst") - depends_on("adios", when="+adios") - depends_on("hdf5", when="+hdf5") + depends_on("vtk+python", when="~libsim ~catalyst+python") + depends_on("adios2", when="+adios2") + depends_on("ascent", when="+ascent") + + # VTK needs +hl and currently spack cannot resolve +hl and ~hl + depends_on("hdf5+hl", when="+hdf5") # SENSEI 3 supports Python 3, earlier versions upport only Python 2 depends_on("python@:2.7.16", when="@:2.1.1 +python", type=('build', 'run')) depends_on("python@3:", when="@3: +python", type=('build', 'run')) + extends('python', when='+python') depends_on("py-numpy", when="+python", type=('build', 'run')) depends_on("py-mpi4py", when="+python", type=('build', 'run')) depends_on("swig", when="+python", type='build') depends_on('cmake@3.6:', when="@3:", type='build') + depends_on('pugixml') + + # Since sensei always has a VTK dependency, either directly or indirectly, + # VTKm will also always be available via VTK so there's no scenario to + # have a directl dependency on VTK, # Can have either LibSim or Catalyst, but not both conflicts('+libsim', when='+catalyst') @@ -65,70 +84,34 @@ class Sensei(CMakePackage): # -Ox flags are set by default in CMake based on the build type args = [ - '-DCMAKE_CXX_STANDARD={0}'.format(spec.variants['cxxstd'].value), - '-DCMAKE_C_STANDARD=11', - '-DCMAKE_POSITION_INDEPENDENT_CODE=ON', - '-DENABLE_SENSEI:BOOL={0}'.format( - 'ON' if '+sencore' in spec else 'OFF') + self.define_from_variant('BUILD_SHARED_LIBS', 'shared'), + self.define_from_variant('CMAKE_CXX_STANDARD', 'cxxstd'), + self.define('CMAKE_C_STANDARD', 11), + self.define('SENSEI_USE_EXTERNAL_pugixml', True), + self.define('CMAKE_POSITION_INDEPENDENT_CODE', True), + self.define_from_variant('ENABLE_SENSEI', 'sencore'), + self.define_from_variant('ENABLE_ASCENT', 'ascent'), + self.define_from_variant('ENABLE_VTKM', 'vtkm'), + self.define_from_variant('ENABLE_CATALYST', 'catalyst'), + self.define_from_variant('ENABLE_LIBSIM', 'libsim'), + self.define_from_variant('ENABLE_VTK_IO', 'vtkio'), + self.define_from_variant('ENABLE_PYTHON', 'python'), + self.define_from_variant('ENABLE_ADIOS2', 'adios2'), + self.define_from_variant('ENABLE_HDF5', 'hdf5'), + self.define_from_variant('ENABLE_PARALLEL3D', 'miniapps'), + self.define_from_variant('ENABLE_OSCILLATORS', 'miniapps') ] - vtk_dir_needed = True - - if '+catalyst' in spec: - args.extend([ - '-DENABLE_CATALYST:BOOL=ON', - '-DENABLE_CATALYST_PYTHON:BOOL=ON', - '-DParaView_DIR:PATH={0}'.format(spec['paraview'].prefix) - ]) - vtk_dir_needed = False - else: - args.append('-DENABLE_CATALYST:BOOL=OFF') - if '+libsim' in spec: - args.extend([ - '-DENABLE_LIBSIM:BOOL=ON', - '-DVISIT_DIR:PATH={0}'.format(spec['visit'].prefix), - '-DVTK_DIR:PATH={0}'.format(spec['vtk'].prefix) - ]) - vtk_dir_needed = False - else: - args.append('-DENABLE_LIBSIM:BOOL=OFF') - - vtkio_switch = 'ON' if '+vtkio' in spec else 'OFF' - args.append('-DENABLE_VTK_IO:BOOL={0}'.format(vtkio_switch)) + args.append( + '-DVISIT_DIR:PATH={0}/current/{1}-{2}'.format( + spec['visit'].prefix, spec.platform, spec.target.family) + ) - python_switch = 'OFF' if '+python' in spec: - python_switch = 'ON' - python_path = spec['python'].command.path - args.append('-DPYTHON_EXECUTABLE:FILEPATH={0}'.format(python_path)) + args.append(self.define('PYTHON_EXECUTABLE', spec['python'].command.path)) if spec.satisfies('@3:'): - args.append('-DSENSEI_PYTHON_VERSION=3') - args.append('-DENABLE_PYTHON:BOOL={0}'.format(python_switch)) - - if '+adios' in spec: - if spec.satisfies('@3:'): - args.append('-DENABLE_ADIOS1:BOOL=ON') - else: - args.append('-DENABLE_ADIOS:BOOL=ON') - args.append('-DADIOS_DIR:PATH={0}'.format(spec['adios'].prefix)) - else: - args.append('-DENABLE_ADIOS:BOOL=OFF') - - if '+hdf5' in spec: - args.extend([ - '-DENABLE_HDF5:BOOL=ON', - '-DHDF5_DIR:PATH={0}'.format(spec['hdf5'].prefix) - ]) - - if vtk_dir_needed: - args.append('-DVTK_DIR:PATH={0}'.format(spec['vtk'].prefix)) - - args.extend([ - '-DENABLE_PARALLEL3D:BOOL={0}'.format( - 'ON' if '+miniapps' in spec else 'OFF'), - '-DENABLE_OSCILLATORS:BOOL={0}'.format( - 'ON' if '+miniapps' in spec else 'OFF') - ]) + args.append(self.define('SENSEI_PYTHON_VERSION', 3)) + args.append(self.define_from_variant('ENABLE_CATALYST_PYTHON', 'catalyst')) return args diff --git a/var/spack/repos/builtin/packages/vtk/package.py b/var/spack/repos/builtin/packages/vtk/package.py index d7a7126830..ebfc060c8f 100644 --- a/var/spack/repos/builtin/packages/vtk/package.py +++ b/var/spack/repos/builtin/packages/vtk/package.py @@ -63,6 +63,9 @@ class Vtk(CMakePackage): # https://gitlab.kitware.com/vtk/vtk/commit/706f1b397df09a27ab8981ab9464547028d0c322 patch('python3.7-const-char.patch', when='@7.0.0:8.1.1 ^python@3.7:') + # Broken downstream FindMPI + patch('vtkm-findmpi-downstream.patch', when='@9.0.0') + # The use of the OpenGL2 backend requires at least OpenGL Core Profile # version 3.2 or higher. depends_on('gl@3.2:', when='+opengl2') diff --git a/var/spack/repos/builtin/packages/vtk/vtkm-findmpi-downstream.patch b/var/spack/repos/builtin/packages/vtk/vtkm-findmpi-downstream.patch new file mode 100644 index 0000000000..de36d9e099 --- /dev/null +++ b/var/spack/repos/builtin/packages/vtk/vtkm-findmpi-downstream.patch @@ -0,0 +1,185 @@ +From 0510b87018815781da34566a57f35caaf01fc822 Mon Sep 17 00:00:00 2001 +From: Robert Maynard <robert.maynard@kitware.com> +Date: Thu, 18 Jun 2020 15:48:48 -0400 +Subject: [PATCH] Make sure we don't leak our findmpi module + +Consumers of VTK-m shouldn't use VTK-m find mpi module unless +they explicitly want to. This makes sure that by default only +VTK-m uses it. +--- + CMake/VTKmCMakeBackports.cmake | 23 +++++++++++++++++++++++ + CMake/VTKmMPI.cmake | 24 ------------------------ + CMake/VTKmWrappers.cmake | 6 +++++- + CMake/{ => patches/3.15}/FindMPI.cmake | 0 + CMake/patches/FindMPI.cmake | 18 ++++++++++++++++++ + CMake/patches/README.md | 7 +++++++ + CMakeLists.txt | 11 ++++++++--- + 7 files changed, 61 insertions(+), 28 deletions(-) + create mode 100644 CMake/VTKmCMakeBackports.cmake + delete mode 100644 CMake/VTKmMPI.cmake + rename CMake/{ => patches/3.15}/FindMPI.cmake (100%) + create mode 100644 CMake/patches/FindMPI.cmake + create mode 100644 CMake/patches/README.md + +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmCMakeBackports.cmake b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmCMakeBackports.cmake +new file mode 100644 +index 000000000..2d286fb16 +--- /dev/null ++++ b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmCMakeBackports.cmake +@@ -0,0 +1,23 @@ ++##============================================================================ ++## Copyright (c) Kitware, Inc. ++## All rights reserved. ++## See LICENSE.txt for details. ++## ++## This software is distributed WITHOUT ANY WARRANTY; without even ++## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ++## PURPOSE. See the above copyright notice for more information. ++##============================================================================ ++ ++file(GLOB cmake_version_backports ++ LIST_DIRECTORIES true ++ RELATIVE "${CMAKE_CURRENT_LIST_DIR}/patches" ++ "${CMAKE_CURRENT_LIST_DIR}/patches/*") ++ ++foreach (cmake_version_backport IN LISTS cmake_version_backports) ++ if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/patches/${cmake_version_backport}") ++ continue () ++ endif () ++ if (CMAKE_VERSION VERSION_LESS "${cmake_version_backport}") ++ list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_LIST_DIR}/patches/${cmake_version_backport}") ++ endif () ++endforeach () +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmMPI.cmake b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmMPI.cmake +deleted file mode 100644 +index 4c06369ec..000000000 +--- a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmMPI.cmake ++++ /dev/null +@@ -1,24 +0,0 @@ +-##============================================================================ +-## Copyright (c) Kitware, Inc. +-## All rights reserved. +-## See LICENSE.txt for details. +-## +-## This software is distributed WITHOUT ANY WARRANTY; without even +-## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +-## PURPOSE. See the above copyright notice for more information. +-##============================================================================ +- +-if(VTKm_ENABLE_MPI AND NOT TARGET MPI::MPI_CXX) +- if(CMAKE_VERSION VERSION_LESS 3.15) +- #While CMake 3.10 introduced the new MPI module. +- #Fixes related to MPI+CUDA that VTK-m needs are +- #only found in CMake 3.15+. +- find_package(MPI REQUIRED MODULE) +- else() +- #clunky but we need to make sure we use the upstream module if it exists +- set(orig_CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}) +- set(CMAKE_MODULE_PATH "") +- find_package(MPI REQUIRED MODULE) +- set(CMAKE_MODULE_PATH ${orig_CMAKE_MODULE_PATH}) +- endif() +-endif() +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmWrappers.cmake b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmWrappers.cmake +index 08c359053..a79b72338 100644 +--- a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmWrappers.cmake ++++ b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/VTKmWrappers.cmake +@@ -10,9 +10,13 @@ + + include(CMakeParseArguments) + ++include(VTKmCMakeBackports) + include(VTKmDeviceAdapters) + include(VTKmCPUVectorization) +-include(VTKmMPI) ++ ++if(VTKm_ENABLE_MPI AND NOT TARGET MPI::MPI_CXX) ++ find_package(MPI REQUIRED MODULE) ++endif() + + #----------------------------------------------------------------------------- + # INTERNAL FUNCTIONS +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/FindMPI.cmake b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/3.15/FindMPI.cmake +similarity index 100% +rename from CMake/FindMPI.cmake +rename to CMake/patches/3.15/FindMPI.cmake +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake +new file mode 100644 +index 000000000..192c280fd +--- /dev/null ++++ b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/FindMPI.cmake +@@ -0,0 +1,18 @@ ++##============================================================================= ++## ++## Copyright (c) Kitware, Inc. ++## All rights reserved. ++## See LICENSE.txt for details. ++## ++## This software is distributed WITHOUT ANY WARRANTY; without even ++## the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ++## PURPOSE. See the above copyright notice for more information. ++## ++##============================================================================= ++ ++# This module is already included in new versions of CMake ++if(CMAKE_VERSION VERSION_LESS 3.15) ++ include(${CMAKE_CURRENT_LIST_DIR}/3.15/FindMPI.cmake) ++else() ++ include(${CMAKE_ROOT}/Modules/FindMPI.cmake) ++endif() +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/README.md b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/README.md +new file mode 100644 +index 000000000..405016904 +--- /dev/null ++++ b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMake/patches/README.md +@@ -0,0 +1,7 @@ ++# CMake backports ++ ++This directory contains backports from newer CMake versions to help support ++actually using older CMake versions for building VTK-m. The directory name is the ++minimum version of CMake for which the contained files are no longer necessary. ++For example, the files under the `3.15` directory are not needed for 3.15 or ++3.16, but are for 3.14. +diff --git a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt +index 7695384d4..e40063b3d 100644 +--- a/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt ++++ b/ThirdParty/vtkm/vtkvtkm/vtk-m/CMakeLists.txt +@@ -247,11 +247,17 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES) + # Install helper configure files. + install( + FILES ++ ${VTKm_SOURCE_DIR}/CMake/VTKmCMakeBackports.cmake + ${VTKm_SOURCE_DIR}/CMake/FindTBB.cmake +- ${VTKm_SOURCE_DIR}/CMake/FindMPI.cmake + ${VTKm_SOURCE_DIR}/CMake/FindOpenGL.cmake ++ ${VTKm_SOURCE_DIR}/CMake/patches/FindMPI.cmake + DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR} + ) ++ install( ++ FILES ++ ${VTKm_SOURCE_DIR}/CMake/patches/3.15/FindMPI.cmake ++ DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR}/3.15 ++ ) + + # Install support files. + install( +@@ -260,7 +266,6 @@ if(NOT VTKm_INSTALL_ONLY_LIBRARIES) + ${VTKm_SOURCE_DIR}/CMake/VTKmDetectCUDAVersion.cu + ${VTKm_SOURCE_DIR}/CMake/VTKmDeviceAdapters.cmake + ${VTKm_SOURCE_DIR}/CMake/VTKmExportHeaderTemplate.h.in +- ${VTKm_SOURCE_DIR}/CMake/VTKmMPI.cmake + ${VTKm_SOURCE_DIR}/CMake/VTKmRenderingContexts.cmake + ${VTKm_SOURCE_DIR}/CMake/VTKmWrappers.cmake + DESTINATION ${VTKm_INSTALL_CMAKE_MODULE_DIR} +@@ -294,7 +299,7 @@ endif () + #----------------------------------------------------------------------------- + #add the benchmarking folder + if(VTKm_ENABLE_BENCHMARKS) +- add_subdirectory(benchmarking) ++ add_subdirectory(benchmarking) + endif() + + #----------------------------------------------------------------------------- +-- +2.24.2 + |