Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pulse Physiology Suite
engine
Commits
432ffafc
Commit
432ffafc
authored
Nov 27, 2020
by
Aaron Bray
Browse files
Merge branch '3.x'
parents
92b8313b
4d9f64c1
Changes
583
Hide whitespace changes
Inline
Side-by-side
CMakeLists.txt
View file @
432ffafc
...
...
@@ -77,7 +77,7 @@ if(${PROJECT_NAME}_SUPERBUILD)
option
(
USE_SYSTEM_
${
extProj
}
"Exclude
${
extProj
}
from superbuild and use an existing build."
OFF
)
mark_as_advanced
(
USE_SYSTEM_
${
extProj
}
)
endmacro
()
define_dependency
(
Eigen3
)
if
(
WIN32
)
# *nix systems have this already
...
...
@@ -92,7 +92,7 @@ if(${PROJECT_NAME}_SUPERBUILD)
message
(
FATAL_ERROR
"Unable to support Python API, cannot find Python3"
)
endif
()
endif
()
if
(
${
PROJECT_NAME
}
_DEPENDENCIES
)
if
(
MSVC OR XCode
)
if
(
NOT
${
PROJECT_NAME
}
_SLAVE_BUILD
)
...
...
@@ -122,7 +122,7 @@ endif()
# INNERBUILD
#-----------------------------------------------------------------------------
if
(
MSVC
)
if
(
MSVC
)
# Using MD as that seems to be what I run into alot, you could change these to /MT and /MTd if you want...
set
(
CMAKE_CXX_FLAGS_DEBUG
"/D_DEBUG /MDd /Zi /Ob2 /Oi /Od /RTC1 /MP /EHsc"
CACHE STRING INTERNAL FORCE
)
set
(
CMAKE_CXX_FLAGS_RELEASE
"/MD /MP /EHsc"
CACHE STRING INTERNAL FORCE
)
...
...
@@ -153,19 +153,29 @@ if(WIN32)
# *nix systems have this already
find_package
(
Dirent REQUIRED
)
endif
()
# Use the config written by protobuf
set
(
protobuf_MODULE_COMPATIBLE ON CACHE BOOL
""
FORCE
)
find_package
(
protobuf REQUIRED NO_DEFAULT_PATH
)
# Tell protobuf-config.cmake to try to be compatible with FindProtobuf.cmake;
# this makes it easier for us to work with either one
set
(
protobuf_MODULE_COMPATIBLE ON CACHE BOOL
"CMake built-in FindProtobuf.cmake module compatible"
FORCE
)
mark_as_advanced
(
protobuf_MODULE_COMPATIBLE
)
# Try to use the config written by protobuf
find_package
(
protobuf QUIET CONFIG NO_DEFAULT_PATH
)
if
(
protobuf_DIR AND protobuf_FOUND
)
# Success; set flag so we will reexport protobuf for our users
set
(
Pulse_USING_PROTOBUF_DIR ON
)
elseif
(
NOT protobuf_FOUND
)
# Nope; fall back on FindProtobuf.cmake
find_package
(
Protobuf REQUIRED
)
endif
()
# Ensure protobuf exported target exists
get_target_property
(
PROTOBUF_LIBRARY_RELEASE protobuf::libprotobuf LOCATION_RELEASE
)
get_target_property
(
PROTOBUF_LIBRARY_DEBUG protobuf::libprotobuf LOCATION_DEBUG
)
#message(STATUS "PROTOBUF_LIBRARY_RELEASE ${PROTOBUF_LIBRARY_RELEASE}")
#message(STATUS "PROTOBUF_LIBRARY_DEBUG ${PROTOBUF_LIBRARY_DEBUG}")
install
(
FILES
${
PROTOBUF_LIBRARY_RELEASE
}
DESTINATION
${
CMAKE_INSTALL_PREFIX
}
/lib OPTIONAL
)
install
(
FILES
${
PROTOBUF_LIBRARY_DEBUG
}
DESTINATION
${
CMAKE_INSTALL_PREFIX
}
/lib OPTIONAL
)
get_filename_component
(
PROTOBUF_LIBRARY_DEBUG
${
PROTOBUF_LIBRARY_DEBUG
}
NAME
)
get_filename_component
(
PROTOBUF_LIBRARY_RELEASE
${
PROTOBUF_LIBRARY_RELEASE
}
NAME
)
#message(STATUS "PROTOBUF_LIBRARY_RELEASE ${PROTOBUF_LIBRARY_RELEASE}")
#message(STATUS "PROTOBUF_LIBRARY_DEBUG ${PROTOBUF_LIBRARY_DEBUG}")
set
(
SCHEMA_SRC
"
${
CMAKE_SOURCE_DIR
}
/schema"
)
set
(
SCHEMA_DST
"
${
CMAKE_SOURCE_DIR
}
/schema/bind"
)
...
...
@@ -228,7 +238,7 @@ export(
# Configure '${PROJECT_NAME}Config.cmake' for a build tree
set
(
build_config
${
CMAKE_BINARY_DIR
}
/
${
PROJECT_NAME
}
Config.cmake
)
configure_package_config_file
(
cmake/
${
PROJECT_NAME
}
Config.cmake.in
cmake/
${
PROJECT_NAME
}
Config
Build
.cmake.in
${
build_config
}
INSTALL_DESTINATION
"
${
PROJECT_BINARY_DIR
}
"
)
...
...
@@ -244,7 +254,7 @@ install(
set
(
install_config
${
PROJECT_BINARY_DIR
}
/CMakeFiles/
${
PROJECT_NAME
}
Config.cmake
)
configure_package_config_file
(
cmake/
${
PROJECT_NAME
}
Config.cmake.in
cmake/
${
PROJECT_NAME
}
Config
Install
.cmake.in
${
install_config
}
INSTALL_DESTINATION
${${
PROJECT_NAME
}
_INSTALL_CONFIG_DIR
}
)
...
...
bin/run.bat
View file @
432ffafc
:: Refer to the Running and Testing Section in the ReadMe.md for %1 options
cmake
-DTYPE
:STRING
=
%
1
-DARG
1
:STRING
=
%
2
-P
run
.cmake
\ No newline at end of file
cmake
-DTYPE
:STRING
=
%
1
-DARG
1
:STRING
=
%
2
-DARG
2
:STRING
=
%
3
-P
run
.cmake
\ No newline at end of file
bin/run.cmake.in
View file @
432ffafc
...
...
@@ -98,9 +98,9 @@ elseif(TYPE STREQUAL "protoc")
-DPulse_PYTHON_API:BOOL=@Pulse_PYTHON_API@
-P "@CMAKE_SOURCE_DIR@/src/schema/GenerateBindings.cmake")
elseif(TYPE STREQUAL "updateBaselines")
execute_process(COMMAND ${CMAKE_COMMAND} --build "@CMAKE_CURRENT_BINARY_DIR@" --target UpdateVerification)
execute_process(COMMAND ${CMAKE_COMMAND} --build "@CMAKE_CURRENT_BINARY_DIR@
/data
" --target UpdateVerification)
elseif(TYPE STREQUAL "jar")
execute_process(COMMAND ${CMAKE_COMMAND} --build "@CMAKE_CURRENT_BINARY_DIR@" --target PulseJava)
execute_process(COMMAND ${CMAKE_COMMAND} --build "@CMAKE_CURRENT_BINARY_DIR@
/src/java
" --target PulseJava)
elseif(TYPE STREQUAL "rebase")
# find Git and if available set GIT_HASH variable
find_package(Git QUIET)
...
...
@@ -119,8 +119,25 @@ elseif(TYPE STREQUAL "FullReport")
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.cdm.testing.SEReportResults)
elseif(TYPE STREQUAL "plotter")
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.utilities.csv.plots.CSVPlotTool ${ARG1})
elseif(${TYPE} MATCHES "compare")
# If ARG2 is empty, assume ARG1 is a directory with 2 csv files
if(NOT ARG2)
file(GLOB _csv_files "${ARG1}/*.csv")
list(LENGTH _csv_files _num_csv_files)
if(_num_csv_files EQUAL 2)
list(GET _csv_files 0 _csv_0)
list(GET _csv_files 1 _csv_1)
message(STATUS "CSV 0 : ${_csv_0}")
message(STATUS "CSV 1 : ${_csv_1}")
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.utilities.csv.plots.CSVComparePlotter ${_csv_0} ${_csv_1})
else()
message(FATAL_ERROR "Could not find 2 csv files in provided directory ${ARG1}")
endif()
else()
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.utilities.csv.plots.CSVComparePlotter ${ARG1} ${ARG2})
endif()
else()
if(${TYPE} MATCHES "
P
lot")
if(${TYPE} MATCHES "
p
lot")
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.utilities.csv.plots.PlotDriver ${TYPE}.config)
else()
execute_process(COMMAND "${Java_JAVA_EXECUTABLE}" -classpath "${JAVA_CLASSPATH}" com.kitware.pulse.cdm.testing.SETestDriver ${TYPE}.config)
...
...
bin/run.sh
View file @
432ffafc
# Refer to the Running and Testing Section in the ReadMe.md for %1 options
cmake
-DTYPE
:STRING
=
$1
-P
run.cmake
cmake
-DTYPE
:STRING
=
$1
-DARG1
:STRING
=
$2
-DARG2
:STRING
=
$3
-P
run.cmake
cmake/PulseConfigBuild.cmake.in
0 → 100644
View file @
432ffafc
@PACKAGE_INIT@
set(export_config_name "@export_config_name@")
set_and_check(${export_config_name}Targets "${CMAKE_CURRENT_LIST_DIR}/${export_config_name}Targets.cmake")
include(${${export_config_name}Targets})
set(Pulse_ROOT ${PACKAGE_PREFIX_DIR})
if(@Pulse_USING_PROTOBUF_DIR@)
set(protobuf_DIR "@protobuf_DIR@")
find_package(protobuf REQUIRED CONFIG NO_DEFAULT_PATH)
else()
find_package(protobuf QUIET CONFIG NO_DEFAULT_PATH)
if(NOT protobuf_FOUND)
find_package(Protobuf REQUIRED)
endif()
endif()
cmake/PulseConfig.cmake.in
→
cmake/PulseConfig
Install
.cmake.in
View file @
432ffafc
...
...
@@ -10,8 +10,8 @@ include(${${export_config_name}Targets})
set(Pulse_ROOT ${PACKAGE_PREFIX_DIR})
# Pulse uses protobuf, but only distributes/needs its libraries
if (NOT protobuf::libprotobuf
_FOUND
)
add_library(protobuf::libprotobuf INTERFACE IMPORTED)
target_link_libraries(protobuf::libprotobuf INTERFACE debug ${PACKAGE_PREFIX_DIR}/lib/@PROTOBUF_LIBRARY_DEBUG@)
target_link_libraries(protobuf::libprotobuf INTERFACE optimized ${PACKAGE_PREFIX_DIR}/lib/@PROTOBUF_LIBRARY_RELEASE@)
if (NOT
TARGET
protobuf::libprotobuf)
add_library(protobuf::libprotobuf INTERFACE IMPORTED)
target_link_libraries(protobuf::libprotobuf INTERFACE debug ${PACKAGE_PREFIX_DIR}/lib/@PROTOBUF_LIBRARY_DEBUG@)
target_link_libraries(protobuf::libprotobuf INTERFACE optimized ${PACKAGE_PREFIX_DIR}/lib/@PROTOBUF_LIBRARY_RELEASE@)
endif()
cmake/external/CMakeLists.txt
View file @
432ffafc
...
...
@@ -121,7 +121,8 @@ if (${PROJECT_NAME}_JAVA_API)
add_dependencies
(
PulseData Pulse
)
add_custom_command
(
TARGET PulseData POST_BUILD
COMMAND
${
CMAKE_COMMAND
}
-DTYPE:STRING=genData -P run.cmake
WORKING_DIRECTORY
${
CMAKE_INSTALL_PREFIX
}
/bin
)
WORKING_DIRECTORY
${
CMAKE_INSTALL_PREFIX
}
/bin
BYPRODUCTS
"
${
CMAKE_INSTALL_PREFIX
}
/bin/patients/StandardMale.json"
)
# Don't genStates if in Debug, takes way too long
string
(
APPEND _genStates
"$<IF:$<CONFIG:Debug>,"
...
...
@@ -131,7 +132,8 @@ if (${PROJECT_NAME}_JAVA_API)
add_custom_command
(
TARGET PulseData POST_BUILD
COMMAND
"
${
_genStates
}
"
COMMAND_EXPAND_LISTS
WORKING_DIRECTORY
${
CMAKE_INSTALL_PREFIX
}
/bin
)
WORKING_DIRECTORY
${
CMAKE_INSTALL_PREFIX
}
/bin
BYPRODUCTS
"
${
CMAKE_INSTALL_PREFIX
}
/bin/states/StandardMale@0s.json"
)
set_target_properties
(
PulseData PROPERTIES FOLDER
${
PROJECT_NAME
}
)
else
()
message
(
STATUS
"!!! Without Java Utils, this build will not generate required data files needed for Pulse to execute !!!"
)
...
...
cmake/external/External_Dirent.cmake
View file @
432ffafc
...
...
@@ -4,10 +4,10 @@
include
(
AddExternalProject
)
define_external_dirs_ex
(
Dirent
)
add_external_project_ex
(
Dirent
URL
"https://github.com/tronkko/dirent/archive/1.22.zip"
URL_HASH MD5=
cf5b4499d163604732f4dc91654056be
URL
"https://github.com/tronkko/dirent/archive/1.2
3.
2.zip"
URL_HASH MD5=
43514791ab73ef5ac7c490afc7c3bab2
CMAKE_CACHE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=
${
CMAKE_INSTALL_PREFIX
}
-DDIRENT_BUILD_TESTS:BOOL=OFF
RELATIVE_INCLUDE_PATH
""
DEPENDENCIES
""
#VERBOSE
...
...
cmake/external/External_Eigen3.cmake
View file @
432ffafc
...
...
@@ -7,8 +7,7 @@ add_external_project_ex( Eigen3
URL
"https://gitlab.com/libeigen/eigen/-/archive/3.3.7/eigen-3.3.7.tar.gz"
URL_HASH MD5=9e30f67e8531477de4117506fe44669b
CMAKE_CACHE_ARGS
-DCMAKE_INSTALL_PREFIX:PATH=
${
Eigen3_PREFIX
}
/install
-DBUILD_TESTING:BOOL=OFF
-DBUILD_TESTING:BOOL=OFF
RELATIVE_INCLUDE_PATH
""
DEPENDENCIES
""
#VERBOSE
...
...
cmake/external/External_protobuf.cmake
View file @
432ffafc
...
...
@@ -38,5 +38,5 @@ if (NOT USE_SYSTEM_protobuf)
set
(
protobuf_DIR
${
protobuf_PREFIX
}
/install/lib/cmake/protobuf
)
endif
()
message
(
STATUS
"protobuf_DIR :
${
protobuf_DIR
}
"
)
set
(
protobuf_SRC
${
protobuf_PREFIX
}
/src
)
endif
()
set
(
protobuf_SRC
${
protobuf_PREFIX
}
/src
)
data/CMakeLists.txt
View file @
432ffafc
# External Data
include
(
ExternalData
)
set
(
ExternalData_URL_TEMPLATES
"https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
)
# Putting in the same URL to ensure bad connections retry a few times
set
(
ExternalData_URL_TEMPLATES
"https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
"https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
"https://data.kitware.com/api/v1/file/hashsum/%(algo)/%(hash)/download"
)
message
(
STATUS
"Looking for zip shas"
)
file
(
GLOB_RECURSE _VERIFICATION_SHA RELATIVE
${
CMAKE_CURRENT_SOURCE_DIR
}
"*.sha512"
)
...
...
@@ -22,7 +25,7 @@ endforeach()
ExternalData_Add_Target
(
ExternalData
)
set
(
ExternalData_LINK_CONTENT SHA512
)
set
(
ExternalData_TIMEOUT_ABSOLUTE 300
)
set
(
ExternalData_TIMEOUT_INACTIVITY
6
0
)
set
(
ExternalData_TIMEOUT_INACTIVITY
15
0
)
set
(
INC_DOWNLOAD
)
if
(
PULSE_DOWNLOAD_BASELINES
)
...
...
data/config/CDMUnitTests.config
View file @
432ffafc
...
...
@@ -136,14 +136,17 @@ FluidCircuit = CDMUnitTest
ThermalCircuit
=
CDMUnitTest
ElectricalCircuit
=
CDMUnitTest
CombinedCircuit
=
CDMUnitTest
InterCircuitComparison
=
CDMUnitTest
InterCircuitIndividual
=
CDMUnitTest
Results
=
InterCircuitIndividual1
,
InterCircuitIndividual2
DynamicallyChangingCircuit
=
CDMUnitTest
NonZeroReferenceNegative
=
CDMUnitTest
NonZeroReferencePositive
=
CDMUnitTest
PolarizedCapacitor
=
CDMUnitTest
PreChargeComplianceZeroVolume
=
CDMUnitTest
PreChargeComplianceNonZeroVolume
=
CDMUnitTest
#BasicBlackBoxComparisonTest = CDMUnitTest
#BasicBlackBoxTest = CDMUnitTest
#SimpleBlackBoxTest = CDMUnitTest
#WindkesselBlackBoxTest = CDMUnitTest
#This test is not flushed out, and that's ok
#CircuitErrorTest = CDMUnitTest
CircuitLockingTest
=
CDMUnitTestDriver
NoCompare
Computed
=./
test_results
/
unit_tests
/
cdm
/
...
...
data/config/DebugRun.config
View file @
432ffafc
...
...
@@ -32,4 +32,3 @@ Macro EngineUnitTestFull=EngineUnitTestDriver FullPlot Baseline=unit_tests/pulse
Macro
ScenarioTest
=
ScenarioTestDriver
FastPlot
Baseline
=
scenarios
/
Computed
=./
test_results
/
scenarios
patient
/
BasicStandard
.
json
=
ScenarioTest
data/config/ScenarioVerification.config
View file @
432ffafc
...
...
@@ -52,6 +52,7 @@ patient/CPRForce.json = ScenarioTest
patient
/
DyspneaVaried
.
json
=
ScenarioTest
patient
/
EffusionCondition
.
json
=
ScenarioTest
patient
/
EffusionConditionPlus
.
json
=
ScenarioTest
patient
/
HemorrhageClass1Femoral
.
json
=
ScenarioTest
patient
/
HemorrhageClass2Blood
.
json
=
ScenarioTest
patient
/
HemorrhageClass2BrachialArtery
.
json
=
ScenarioTest
patient
/
HemorrhageClass2InternalMultiple
.
json
=
ScenarioTest
...
...
@@ -60,13 +61,19 @@ patient/HemorrhageClass2NoFluid.json = ScenarioTest
patient
/
HemorrhageClass2Saline
.
json
=
ScenarioTest
patient
/
HemorrhageClass3NoFluid
.
json
=
ScenarioTest
patient
/
HemorrhageClass3PackedRBC
.
json
=
ScenarioTest
patient
/
HemorrhageClass4NoFluid
.
json
=
ScenarioTest
patient
/
HemorrhageGroup1
.
json
=
ScenarioTest
patient
/
HemorrhageGroup2
.
json
=
ScenarioTest
patient
/
HemorrhageGroup3
.
json
=
ScenarioTest
patient
/
HemorrhageGroup4
.
json
=
ScenarioTest
patient
/
HemorrhageGroup5
.
json
=
ScenarioTest
patient
/
HemorrhageGroup6
.
json
=
ScenarioTest
patient
/
HemorrhageInternalSeverity
.
json
=
ScenarioTest
patient
/
HemorrhageSeverity1
.
json
=
ScenarioTest
patient
/
HemorrhageSeverityMultipleCompartments
.
json
=
ScenarioTest
patient
/
HemorrhageSeverityToFlowToSeverity
.
json
=
ScenarioTest
patient
/
HemorrhageToShock
.
json
=
ScenarioTest
patient
/
HemorrhageVaryingSeverity
.
json
=
ScenarioTest
patient
/
LobarPneumoniaExacerbation
.
json
=
ScenarioTest
patient
/
LobarPneumoniaModerateBothLungs
.
json
=
ScenarioTest
patient
/
LobarPneumoniaSevereLeftLobe
.
json
=
ScenarioTest
...
...
data/human/adult/baselines/scenarios/combined/Cynthia.zip.sha512
View file @
432ffafc
aee907f81221bf66243954c0329c326e0957441b34b9b7a4a7e397041161747306ce2ac8de52b2fee5e6cbb85c88d3fc22f075e4d91d6cbca5221b0066135689
\ No newline at end of file
a94475d457ebd784e93c80c2537854b05a798bc31359ccbffdfadbbb14f717f80f2043df52735c0c896e00c34cb5dfe833ccfdad65f3dd5ab43d312589c7125f
\ No newline at end of file
data/human/adult/baselines/scenarios/combined/Gus.zip.sha512
View file @
432ffafc
dfd6c4f17d68a238a97eef9c046c77e6431023d04d03bce0246c1e2eea882e2ebf73ab0e46cd2e1f31c7b34a7c80014ed3466541bfa78d559c6306706c1cdd76
\ No newline at end of file
aa5c58d9e461d48ac53f26ec010fc0e54cc2938215e97c305d85c1be5c61f26172d0d07a3c513185379317fc4ea0b939094b737f31bb51326e0b16269e36db4d
\ No newline at end of file
data/human/adult/baselines/scenarios/combined/Hassan.zip.sha512
View file @
432ffafc
ddaa3c3e98f6aba700d31bdbc314f63db1c72c4f5f576ef5a0ee3803ad9e580969af846619eb5f72f8868c5333fc922b2d763cca1746cdfcbff0c6cbd5d4f0d2
\ No newline at end of file
1f03a5e697c054474caa454cf5f94baba5d5df431885ac08415ab3ba10dd2c630ae1db73c2d2621fc4082380cce672b0d4731cd04eea019f25fce86b4a30b1b9
\ No newline at end of file
data/human/adult/baselines/scenarios/combined/Joel.zip.sha512
View file @
432ffafc
4e3825860e1add6bee1fe0aaf1c21ae7483b67ceb403ba3fe2815623bd92736ea5592cf412e19e553fae1ea008c37107cc307dc78d69ef584de0b2250fab2459
\ No newline at end of file
17e6c49a7640b21a795f3a23e291e4ef68abf462bcffd355db10909a194ef60e7b71534571a017dc8a1f0b6a55e9ab3010f8c898a109e8a3b66e38e83ff37aa1
\ No newline at end of file
data/human/adult/baselines/scenarios/combined/Nathan.zip.sha512
View file @
432ffafc
5aaa92c67d1090bc37f29e2be027e9dfcbe22b5a0bd2152d0dfe7f990cd35c23eb8733bcb194a47f4105479a1330084fa89f40a3b988d7a65d8261b1c0a5c4bc
\ No newline at end of file
59baa74120c2e40bc84cdc043e0370d8bc1c07bfaff8b5a91c43aa944e485b908069dec708f3a09bd27bff85443cb8411d0ef288cbdc958f4e058d77628f4717
\ No newline at end of file
data/human/adult/baselines/scenarios/compartments/AnesthesiaMachineCompartments.zip.sha512
View file @
432ffafc
ab52d83d0b0833184cda7d5dd50bb6019e4acf59fb1431e6dd68b281dca16c32c04a0b455c79f9d60988deaf055f6f100eb89b71ff38ac5218c31176b78f8d61
\ No newline at end of file
977722162892f4463667b38178b99a854db4c790e92b97b7bfb0a3e2f1ae35d76cf74b9373de6fbdc77d9295774edf111e348494e3315c3ba9df5647a5c05d53
\ No newline at end of file
Prev
1
2
3
4
5
…
30
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment