Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mpim-sw
libcdi
Commits
22d106a5
Commit
22d106a5
authored
Apr 27, 2011
by
Uwe Schulzweida
Browse files
Added support for FILETYPE_NC4C (netcdf4 classic)
parent
fd282195
Changes
10
Hide whitespace changes
Inline
Side-by-side
ChangeLog
View file @
22d106a5
2011-04-27 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
* Added support for FILETYPE_NC4C (netcdf4 classic)
* netcdf: Skiped time dependent variables if number of time steps is zero
2011-03-15 Uwe Schulzweida <Uwe.Schulzweida@zmaw.de>
...
...
app/cdi.c
View file @
22d106a5
...
...
@@ -92,7 +92,7 @@ void usage(void)
fprintf
(
stderr
,
"
\n
"
);
fprintf
(
stderr
,
" Options:
\n
"
);
fprintf
(
stderr
,
" -d Print debugging information
\n
"
);
fprintf
(
stderr
,
" -f <format> Format of the output file. (grb, grb2, nc, nc2, nc4, src, ext or ieg)
\n
"
);
fprintf
(
stderr
,
" -f <format> Format of the output file. (grb, grb2, nc, nc2, nc4,
nc4c,
src, ext or ieg)
\n
"
);
fprintf
(
stderr
,
" -s give short information if ofile is missing
\n
"
);
fprintf
(
stderr
,
" -t <table> Parameter table name/file
\n
"
);
fprintf
(
stderr
,
" Predefined tables: "
);
...
...
@@ -586,6 +586,7 @@ void setDefaultFileType(char *filetypestr)
else
if
(
memcmp
(
filetypestr
,
"grb1"
,
4
)
==
0
)
{
ftstr
+=
4
;
DefaultFileType
=
FILETYPE_GRB
;
}
else
if
(
memcmp
(
filetypestr
,
"grb"
,
3
)
==
0
)
{
ftstr
+=
3
;
DefaultFileType
=
FILETYPE_GRB
;
}
else
if
(
memcmp
(
filetypestr
,
"nc2"
,
3
)
==
0
)
{
ftstr
+=
3
;
DefaultFileType
=
FILETYPE_NC2
;
}
else
if
(
memcmp
(
filetypestr
,
"nc4c"
,
4
)
==
0
)
{
ftstr
+=
4
;
DefaultFileType
=
FILETYPE_NC4C
;}
else
if
(
memcmp
(
filetypestr
,
"nc4"
,
3
)
==
0
)
{
ftstr
+=
3
;
DefaultFileType
=
FILETYPE_NC4
;
}
else
if
(
memcmp
(
filetypestr
,
"nc"
,
2
)
==
0
)
{
ftstr
+=
2
;
DefaultFileType
=
FILETYPE_NC
;
}
else
if
(
memcmp
(
filetypestr
,
"srv"
,
3
)
==
0
)
{
ftstr
+=
3
;
DefaultFileType
=
FILETYPE_SRV
;
}
...
...
@@ -594,7 +595,7 @@ void setDefaultFileType(char *filetypestr)
else
{
fprintf
(
stderr
,
"Unsupported filetype %s!
\n
"
,
filetypestr
);
fprintf
(
stderr
,
"Available filetypes: grb, grb2, nc, nc2, nc4, srv, ext and ieg
\n
"
);
fprintf
(
stderr
,
"Available filetypes: grb, grb2, nc, nc2, nc4,
nc4c,
srv, ext and ieg
\n
"
);
exit
(
EXIT_FAILURE
);
}
...
...
@@ -610,8 +611,8 @@ void setDefaultFileType(char *filetypestr)
{
fprintf
(
stderr
,
"Unexpected character >%c< in file type >%s<!
\n
"
,
*
ftstr
,
filetypestr
);
fprintf
(
stderr
,
"Use format[_nbits] with:
\n
"
);
fprintf
(
stderr
,
" format = grb, grb2, nc, nc2, nc4, srv, ext or ieg
\n
"
);
fprintf
(
stderr
,
" nbits = 32/64 for nc
, nc2, nc4
, srv, ext, ieg; 1 -
3
2 for grb
, grb2
\n
"
);
fprintf
(
stderr
,
" format = grb, grb2, nc, nc2, nc4,
nc4c,
srv, ext or ieg
\n
"
);
fprintf
(
stderr
,
" nbits = 32/64 for nc
*
, srv, ext, ieg; 1 - 2
4
for grb
*
\n
"
);
exit
(
EXIT_FAILURE
);
}
}
...
...
app/printinfo.h
View file @
22d106a5
...
...
@@ -52,6 +52,9 @@ void printFiletype(int streamID, int vlistID)
case
FILETYPE_NC4
:
printf
(
"netCDF4"
);
break
;
case
FILETYPE_NC4C
:
printf
(
"netCDF4 classic"
);
break
;
case
FILETYPE_SRV
:
printf
(
"SERVICE"
);
break
;
...
...
@@ -78,7 +81,7 @@ void printFiletype(int streamID, int vlistID)
}
}
if
(
filetype
==
FILETYPE_GRB
||
filetype
==
FILETYPE_NC4
)
if
(
filetype
==
FILETYPE_GRB
||
filetype
==
FILETYPE_NC4
||
filetype
==
FILETYPE_NC4C
)
{
int
nvars
,
varID
;
int
ztype
;
...
...
src/cdf.c
View file @
22d106a5
...
...
@@ -89,11 +89,11 @@ void cdfComment(int ncid)
}
int
cdfOpenFile
(
const
char
*
filename
,
const
char
*
mode
,
int
version
)
int
cdfOpenFile
(
const
char
*
filename
,
const
char
*
mode
,
int
*
filetype
)
{
int
ncid
=
-
1
;
#if defined (HAVE_LIBNETCDF)
int
fmode
;
int
fmode
=
tolower
(
*
mode
)
;
int
writemode
=
NC_CLOBBER
;
int
readmode
=
NC_NOWRITE
;
int
status
;
...
...
@@ -102,43 +102,35 @@ int cdfOpenFile(const char *filename, const char *mode, int version)
ncid
=
CDI_EINVAL
;
else
{
switch
(
*
mode
)
switch
(
f
mode
)
{
case
'r'
:
case
'R'
:
fmode
=
'r'
;
status
=
cdf_open
(
filename
,
readmode
,
&
ncid
);
if
(
status
>
0
&&
ncid
<
0
)
ncid
=
CDI_ESYSTEM
;
#if defined (NC_NETCDF4)
/*
else
{
int
format
;
(
void
)
nc_inq_format
(
ncid
,
&
format
);
if ( format == NC_FORMAT_NETCDF4 )
if
(
format
==
NC_FORMAT_NETCDF4
_CLASSIC
)
{
cdf_close(ncid);
ncid = CDI_EUNC4;
*
filetype
=
FILETYPE_NC4C
;
}
}
*/
#endif
break
;
case
'w'
:
case
'W'
:
fmode
=
'w'
;
#if defined (NC_64BIT_OFFSET)
if
(
version
==
2
)
writemode
=
NC_CLOBBER
|
NC_64BIT_OFFSET
;
if
(
*
filetype
==
FILETYPE_NC
2
)
writemode
=
NC_CLOBBER
|
NC_64BIT_OFFSET
;
#endif
#if defined (NC_NETCDF4)
if
(
version
==
4
)
writemode
=
NC_CLOBBER
|
NC_NETCDF4
/*| NC_CLASSIC_MODEL*/
;
if
(
*
filetype
==
FILETYPE_NC4
)
writemode
=
NC_CLOBBER
|
NC_NETCDF4
;
else
if
(
*
filetype
==
FILETYPE_NC4C
)
writemode
=
NC_CLOBBER
|
NC_NETCDF4
|
NC_CLASSIC_MODEL
;
#endif
cdf_create
(
filename
,
writemode
,
&
ncid
);
cdfComment
(
ncid
);
break
;
case
'a'
:
case
'A'
:
fmode
=
'a'
;
cdf_open
(
filename
,
NC_WRITE
,
&
ncid
);
break
;
default:
...
...
@@ -154,14 +146,15 @@ int cdfOpenFile(const char *filename, const char *mode, int version)
int
cdfOpen
(
const
char
*
filename
,
const
char
*
mode
)
{
int
fileID
=
0
;
int
filetype
=
FILETYPE_NC
;
if
(
CDF_Debug
)
Message
(
"
o
pen %s with mode %c"
,
filename
,
*
mode
);
Message
(
"
O
pen %s with mode %c"
,
filename
,
*
mode
);
fileID
=
cdfOpenFile
(
filename
,
mode
,
1
);
fileID
=
cdfOpenFile
(
filename
,
mode
,
&
filetype
);
if
(
CDF_Debug
)
Message
(
"
f
ile %s opened with id %d"
,
filename
,
fileID
);
Message
(
"
F
ile %s opened with id %d"
,
filename
,
fileID
);
return
(
fileID
);
}
...
...
@@ -170,44 +163,59 @@ int cdfOpen(const char *filename, const char *mode)
int
cdfOpen64
(
const
char
*
filename
,
const
char
*
mode
)
{
int
fileID
=
-
1
;
int
open_file
=
TRUE
;
int
filetype
=
FILETYPE_NC2
;
if
(
CDF_Debug
)
Message
(
"
o
pen %s with mode %c"
,
filename
,
*
mode
);
Message
(
"
O
pen %s with mode %c"
,
filename
,
*
mode
);
#if defined (HAVE_LIBNETCDF)
#if ! defined (NC_64BIT_OFFSET)
fileID
=
CDI_ELIBNAVAIL
;
return
(
fileID
);
open_file
=
FALSE
;
#endif
#endif
fileID
=
cdfOpenFile
(
filename
,
mode
,
2
);
if
(
open_file
)
{
fileID
=
cdfOpenFile
(
filename
,
mode
,
&
filetype
);
if
(
CDF_Debug
)
Message
(
"file %s opened with id %d"
,
filename
,
fileID
);
if
(
CDF_Debug
)
Message
(
"File %s opened with id %d"
,
filename
,
fileID
);
}
else
{
fileID
=
CDI_ELIBNAVAIL
;
}
return
(
fileID
);
}
int
cdf4Open
(
const
char
*
filename
,
const
char
*
mode
)
int
cdf4Open
(
const
char
*
filename
,
const
char
*
mode
,
int
*
filetype
)
{
int
fileID
=
-
1
;
int
open_file
=
TRUE
;
if
(
CDF_Debug
)
Message
(
"
o
pen %s with mode %c"
,
filename
,
*
mode
);
Message
(
"
O
pen %s with mode %c"
,
filename
,
*
mode
);
#if defined (HAVE_LIBNETCDF)
#if ! defined (NC_NETCDF4)
fileID
=
CDI_ELIBNAVAIL
;
return
(
fileID
);
open_file
=
FALSE
;
#endif
#endif
fileID
=
cdfOpenFile
(
filename
,
mode
,
4
);
if
(
open_file
)
{
fileID
=
cdfOpenFile
(
filename
,
mode
,
filetype
);
if
(
CDF_Debug
)
Message
(
"file %s opened with id %d"
,
filename
,
fileID
);
if
(
CDF_Debug
)
Message
(
"File %s opened with id %d"
,
filename
,
fileID
);
}
else
{
fileID
=
CDI_ELIBNAVAIL
;
}
return
(
fileID
);
}
...
...
src/cdf.h
View file @
22d106a5
...
...
@@ -8,7 +8,7 @@ const char *hdfLibraryVersion(void);
int
cdfOpen
(
const
char
*
filename
,
const
char
*
mode
);
int
cdfOpen64
(
const
char
*
filename
,
const
char
*
mode
);
int
cdf4Open
(
const
char
*
filename
,
const
char
*
mode
);
int
cdf4Open
(
const
char
*
filename
,
const
char
*
mode
,
int
*
filetype
);
void
cdfClose
(
int
fileID
);
#endif
/* _CDF_H */
src/cdi.h
View file @
22d106a5
...
...
@@ -42,10 +42,11 @@ extern "C" {
#define FILETYPE_GRB2 2
/* File type GRIB version 2 */
#define FILETYPE_NC 3
/* File type netCDF */
#define FILETYPE_NC2 4
/* File type netCDF version 2 (64-bit) */
#define FILETYPE_NC4 5
/* File type netCDF version 4 (classic) */
#define FILETYPE_SRV 6
/* File type SERVICE */
#define FILETYPE_EXT 7
/* File type EXTRA */
#define FILETYPE_IEG 8
/* File type IEG */
#define FILETYPE_NC4 5
/* File type netCDF version 4 */
#define FILETYPE_NC4C 6
/* File type netCDF version 4 (classic) */
#define FILETYPE_SRV 7
/* File type SERVICE */
#define FILETYPE_EXT 8
/* File type EXTRA */
#define FILETYPE_IEG 9
/* File type IEG */
/* Compress types */
...
...
src/stream.c
View file @
22d106a5
...
...
@@ -340,7 +340,7 @@ The function @func{streamInqFiletype} returns the filetype of a stream.
@func{streamInqFiletype} returns the type of the file format,
one of the set of predefined CDI file format types.
The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC}, @func{FILETYPE_NC2},
@func{FILETYPE_NC4}, @func{FILETYPE_SRV}, @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
@func{FILETYPE_NC4},
@func{FILETYPE_NC4C},
@func{FILETYPE_SRV}, @func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
@EndFunction
*/
...
...
@@ -558,6 +558,7 @@ int cdiInqContents(int streamID)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
status
=
cdfInqContents
(
streamID
);
break
;
...
...
@@ -651,8 +652,9 @@ int streamOpen(const char *filename, const char *filemode, int filetype)
break
;
}
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
fileID
=
cdf4Open
(
filename
,
filemode
);
fileID
=
cdf4Open
(
filename
,
filemode
,
&
filetype
);
break
;
}
#endif
...
...
@@ -767,8 +769,9 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
break
;
}
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
fileID
=
cdf4Open
(
filename
,
"r"
);
fileID
=
cdf4Open
(
filename
,
"r"
,
&
filetype
);
break
;
}
#endif
...
...
@@ -839,6 +842,7 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
cdfClose
(
fileID
);
break
;
...
...
@@ -896,8 +900,9 @@ int streamOpenA(const char *filename, const char *filemode, int filetype)
break
;
}
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
fileID
=
cdf4Open
(
filename
,
filemode
);
fileID
=
cdf4Open
(
filename
,
filemode
,
&
filetype
);
streamptr
->
ncmode
=
2
;
break
;
}
...
...
@@ -1028,7 +1033,7 @@ int streamOpenAppend(const char *filename)
@Item path The name of the new dataset
@Item filetype The type of the file format, one of the set of predefined CDI file format types.
The valid CDI file format types are @func{FILETYPE_GRB}, @func{FILETYPE_GRB2}, @func{FILETYPE_NC},
@func{FILETYPE_NC2}, @func{FILETYPE_NC4}, @func{FILETYPE_SRV},
@func{FILETYPE_NC2}, @func{FILETYPE_NC4},
@func{FILETYPE_NC4C},
@func{FILETYPE_SRV},
@func{FILETYPE_EXT} and @func{FILETYPE_IEG}.
@Description
...
...
@@ -1139,6 +1144,7 @@ void streamClose(int streamID)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
cdfClose
(
fileID
);
break
;
...
...
@@ -1249,6 +1255,7 @@ void streamSync(int streamID)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
void
cdf_sync
(
int
ncid
);
if
(
streamptr
->
ncmode
==
2
)
cdf_sync
(
fileID
);
...
...
@@ -1318,7 +1325,8 @@ int streamDefTimestep(int streamID, int tsID)
if
(
(
streamptr
->
filetype
==
FILETYPE_NC
||
streamptr
->
filetype
==
FILETYPE_NC2
||
streamptr
->
filetype
==
FILETYPE_NC4
)
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
&&
vlistHasTime
(
vlistID
)
)
cdfDefTimestep
(
streamID
,
tsID
);
...
...
@@ -1416,6 +1424,7 @@ int streamInqTimestep(int streamID, int tsID)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
nrecs
=
cdfInqTimestep
(
streamID
,
tsID
);
break
;
...
...
@@ -1504,6 +1513,7 @@ void streamReadVar(int streamID, int varID, double *data, int *nmiss)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
cdfReadVarDP
(
streamID
,
varID
,
data
,
nmiss
);
break
;
...
...
@@ -1584,6 +1594,7 @@ void streamWriteVar(int streamID, int varID, const double *data, int nmiss)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
if
(
streamptr
->
accessmode
==
0
)
cdfEndDef
(
streamID
);
cdfWriteVarDP
(
streamID
,
varID
,
data
,
nmiss
);
...
...
@@ -1664,6 +1675,7 @@ void streamReadVarSlice(int streamID, int varID, int levelID, double *data, int
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
ierr
=
cdfReadVarSliceDP
(
streamID
,
varID
,
levelID
,
data
,
nmiss
);
break
;
...
...
@@ -1744,6 +1756,7 @@ void streamWriteVarSlice(int streamID, int varID, int levelID, const double *dat
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
if
(
streamptr
->
accessmode
==
0
)
cdfEndDef
(
streamID
);
ierr
=
cdfWriteVarSliceDP
(
streamID
,
varID
,
levelID
,
data
,
nmiss
);
...
...
@@ -1982,7 +1995,8 @@ void streamDefVlist(int streamID, int vlistID)
{
if
(
streamptr
->
filetype
==
FILETYPE_NC
||
streamptr
->
filetype
==
FILETYPE_NC2
||
streamptr
->
filetype
==
FILETYPE_NC4
)
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
{
cdfDefVars
(
streamID
);
}
...
...
src/stream_cdf.c
View file @
22d106a5
...
...
@@ -2724,7 +2724,7 @@ int cdfDefVar(int streamID, int varID)
cdf_def_var
(
fileID
,
name
,
(
nc_type
)
xtype
,
ndims
,
dims
,
&
ncvarid
);
#if defined (NC_NETCDF4)
if
(
lchunk
&&
streamptr
->
filetype
==
FILETYPE_NC4
)
if
(
lchunk
&&
(
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
)
{
if
(
(
retval
=
nc_def_var_chunking
(
fileID
,
ncvarid
,
0
,
chunks
))
)
Error
(
"nc_def_var_chunking failed, status = %d"
,
retval
);
...
...
@@ -2733,7 +2733,7 @@ int cdfDefVar(int streamID, int varID)
if
(
streamptr
->
ztype
==
COMPRESS_ZIP
)
{
if
(
lchunk
&&
streamptr
->
filetype
==
FILETYPE_NC4
)
if
(
lchunk
&&
(
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
)
{
cdfDefVarDeflate
(
fileID
,
ncvarid
,
streamptr
->
zlevel
);
}
...
...
@@ -2751,7 +2751,7 @@ int cdfDefVar(int streamID, int varID)
if
(
streamptr
->
ztype
==
COMPRESS_SZIP
)
{
if
(
lchunk
&&
streamptr
->
filetype
==
FILETYPE_NC4
)
if
(
lchunk
&&
(
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
)
{
#if defined (NC_SZIP_NN_OPTION_MASK)
cdfDefVarSzip
(
fileID
,
ncvarid
);
...
...
src/stream_history.c
View file @
22d106a5
...
...
@@ -16,7 +16,8 @@ void streamDefHistory(int streamID, int length, const char *history)
if
(
streamptr
->
filetype
==
FILETYPE_NC
||
streamptr
->
filetype
==
FILETYPE_NC2
||
streamptr
->
filetype
==
FILETYPE_NC4
)
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
{
char
*
histstring
;
size_t
len
;
...
...
@@ -43,7 +44,8 @@ int streamInqHistorySize(int streamID)
if
(
streamptr
->
filetype
==
FILETYPE_NC
||
streamptr
->
filetype
==
FILETYPE_NC2
||
streamptr
->
filetype
==
FILETYPE_NC4
)
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
{
size
=
cdfInqHistorySize
(
streamID
);
}
...
...
@@ -60,7 +62,8 @@ void streamInqHistoryString(int streamID, char *history)
if
(
streamptr
->
filetype
==
FILETYPE_NC
||
streamptr
->
filetype
==
FILETYPE_NC2
||
streamptr
->
filetype
==
FILETYPE_NC4
)
streamptr
->
filetype
==
FILETYPE_NC4
||
streamptr
->
filetype
==
FILETYPE_NC4C
)
{
cdfInqHistoryString
(
streamID
,
history
);
}
...
...
src/stream_record.c
View file @
22d106a5
...
...
@@ -182,6 +182,7 @@ void streamInqRecord(int streamID, int *varID, int *levelID)
case FILETYPE_NC:
case FILETYPE_NC2:
case FILETYPE_NC4:
case FILETYPE_NC4C:
{
rec = cdfInqRecord(streamID, varID, levelID);
break;
...
...
@@ -273,6 +274,7 @@ void streamDefRecord(int streamID, int varID, int levelID)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
if
(
streamptr
->
accessmode
==
0
)
cdfEndDef
(
streamID
);
status
=
cdfDefRecord
(
streamID
);
...
...
@@ -337,6 +339,7 @@ void streamReadRecord(int streamID, double *data, int *nmiss)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
status
=
cdfReadRecord
(
streamID
,
data
,
nmiss
);
break
;
...
...
@@ -398,6 +401,7 @@ void streamWriteRecord(int streamID, const double *data, int nmiss)
case
FILETYPE_NC
:
case
FILETYPE_NC2
:
case
FILETYPE_NC4
:
case
FILETYPE_NC4C
:
{
cdfWriteRecord
(
streamID
,
data
,
nmiss
);
break
;
...
...
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