Commit 6d05a80c authored by Uwe Schulzweida's avatar Uwe Schulzweida
Browse files

Changed interface to zaxisInqLevels().

parent 6e8bb16f
......@@ -987,7 +987,7 @@ int main(int argc, char *argv[])
varID, param, gridID, zaxisID, levelID);
*/
gridsize = gridInqSize(gridID);
level = zaxisInqLevel(zaxisID, levelID);
level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
missval = vlistInqVarMissval(vlistID1, varID);
if ( Info )
......@@ -1029,7 +1029,7 @@ int main(int argc, char *argv[])
levelsize = zaxisInqSize(zaxisID);
for ( levelID = 0; levelID < levelsize; levelID++ )
{
level = zaxisInqLevel(zaxisID, levelID);
level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
streamReadVarSlice(streamID1, varID, levelID, data, &nmiss);
if ( Info )
......
......@@ -522,36 +522,39 @@ void printZaxisInfo(int vlistID)
my_reset_text_color(stdout);
fprintf(stdout, "\n");
double *levels = (double*) malloc((size_t)levelsize*sizeof(double));
zaxisInqLevels(zaxisID, levels);
if ( !(zaxistype == ZAXIS_SURFACE && levelsize == 1 && !(fabs(levels[0]) > 0)) )
if ( zaxisInqLevels(zaxisID, NULL) )
{
double zfirst = levels[0];
double zlast = levels[levelsize-1];
if ( levelsize > 2 )
{
zinc = (levels[levelsize-1] - levels[0]) / (levelsize-1);
for ( int levelID = 2; levelID < levelsize; ++levelID )
if ( fabs(fabs(levels[levelID] - levels[levelID-1]) - zinc) > 0.001*zinc )
{
zinc = 0;
break;
}
}
double *levels = (double*) malloc((size_t)levelsize*sizeof(double));
zaxisInqLevels(zaxisID, levels);
fprintf(stdout, "%33s : %.*g", zname, dig, zfirst);
if ( levelsize > 1 )
if ( !(zaxistype == ZAXIS_SURFACE && levelsize == 1 && !(fabs(levels[0]) > 0)) )
{
fprintf(stdout, " to %.*g", dig, zlast);
if ( IS_NOT_EQUAL(zinc, 0) )
fprintf(stdout, " by %.*g", dig, zinc);
double zfirst = levels[0];
double zlast = levels[levelsize-1];
if ( levelsize > 2 )
{
zinc = (levels[levelsize-1] - levels[0]) / (levelsize-1);
for ( int levelID = 2; levelID < levelsize; ++levelID )
if ( fabs(fabs(levels[levelID] - levels[levelID-1]) - zinc) > 0.001*zinc )
{
zinc = 0;
break;
}
}
fprintf(stdout, "%33s : %.*g", zname, dig, zfirst);
if ( levelsize > 1 )
{
fprintf(stdout, " to %.*g", dig, zlast);
if ( IS_NOT_EQUAL(zinc, 0) )
fprintf(stdout, " by %.*g", dig, zinc);
}
fprintf(stdout, " %s", zunits);
fprintf(stdout, "\n");
}
fprintf(stdout, " %s", zunits);
fprintf(stdout, "\n");
}
free(levels);
free(levels);
}
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
......
......@@ -960,7 +960,7 @@ void zaxisPrint(int zaxisID, int index);
void zaxisDefLevels(int zaxisID, const double levels[]);
/* zaxisInqLevels: Get all levels of a Z-axis */
void zaxisInqLevels(int zaxisID, double levels[]);
int zaxisInqLevels(int zaxisID, double levels[]);
/* zaxisDefLevel: Define one level of a Z-axis */
void zaxisDefLevel(int zaxisID, int levelID, double levels);
......
......@@ -1637,7 +1637,10 @@ void cdf_def_zaxis_hybrid_cf(stream_t *streamptr, int type, int *ncvaridp, int z
double lbounds[dimlen], ubounds[dimlen], levels[dimlen];
zaxisInqLevels(zaxisID, levels);
if ( zaxisInqLevels(zaxisID, NULL) )
zaxisInqLevels(zaxisID, levels);
else
for ( size_t i = 0; i < dimlen; ++i ) levels[i] = i+1;
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
......@@ -1804,76 +1807,82 @@ void cdfDefZaxis(stream_t *streamptr, int zaxisID)
if ( ndims && dimID == UNDEFID ) cdf_def_dim(fileID, dimname, dimlen, &dimID);
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
if ( zaxisInqLevels(zaxisID, NULL) )
{
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims, &dimID, &ncvarid);
cdfPutGridStdAtts(fileID, ncvarid, zaxisID, 'Z', &gridInqsZ);
cdfPutGridStdAtts(fileID, ncvarid, zaxisID, 'Z', &gridInqsZ);
{
int positive = zaxisInqPositive(zaxisID);
static const char positive_up[] = "up",
positive_down[] = "down";
static const struct attTxtTab tab[2] = {
{ positive_up, sizeof (positive_up) - 1 },
{ positive_down, sizeof (positive_down) - 1 },
};
if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
{
size_t select = positive == POSITIVE_DOWN;
cdf_put_att_text(fileID, ncvarid, "positive", tab[select].txtLen, tab[select].txt);
int positive = zaxisInqPositive(zaxisID);
static const char positive_up[] = "up",
positive_down[] = "down";
static const struct attTxtTab tab[2] = {
{ positive_up, sizeof (positive_up) - 1 },
{ positive_down, sizeof (positive_down) - 1 },
};
if ( positive == POSITIVE_UP || positive == POSITIVE_DOWN )
{
size_t select = positive == POSITIVE_DOWN;
cdf_put_att_text(fileID, ncvarid, "positive", tab[select].txtLen, tab[select].txt);
}
}
}
cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
cdf_put_att_text(fileID, ncvarid, "axis", 1, "Z");
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
size_t nvertex = 2;
if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
if ( nvdimID != UNDEFID )
{
size_t axisnameLen = strlen(axisname);
axisname[axisnameLen] = '_';
memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
dimIDs[0] = dimID;
dimIDs[ndims] = nvdimID;
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
}
}
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
size_t nvertex = 2;
if ( nc_inq_dimid(fileID, bndsName, &nvdimID) != NC_NOERR )
cdf_def_dim(fileID, bndsName, nvertex, &nvdimID);
if ( nvdimID != UNDEFID )
{
size_t axisnameLen = strlen(axisname);
axisname[axisnameLen] = '_';
memcpy(axisname + axisnameLen + 1, bndsName, sizeof (bndsName));
dimIDs[0] = dimID;
dimIDs[ndims] = nvdimID;
cdf_def_var(fileID, axisname, (nc_type) xtype, ndims+1, dimIDs, &ncbvarid);
cdf_put_att_text(fileID, ncvarid, "bounds", strlen(axisname), axisname);
}
}
}
cdf_enddef(fileID);
streamptr->ncmode = 2;
cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
if ( zaxisInqLevels(zaxisID, NULL) )
{
cdf_put_var_double(fileID, ncvarid, zaxisInqLevelsPtr(zaxisID));
if ( ncbvarid != UNDEFID )
{
double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
zaxisInqLbounds(zaxisID, lbounds);
zaxisInqUbounds(zaxisID, ubounds);
for ( size_t i = 0; i < dimlen; ++i )
{
zbounds[2*i ] = lbounds[i];
zbounds[2*i+1] = ubounds[i];
}
if ( ncbvarid != UNDEFID )
{
double lbounds[dimlen], ubounds[dimlen], zbounds[2*dimlen];
zaxisInqLbounds(zaxisID, lbounds);
zaxisInqUbounds(zaxisID, ubounds);
for ( size_t i = 0; i < dimlen; ++i )
{
zbounds[2*i ] = lbounds[i];
zbounds[2*i+1] = ubounds[i];
}
cdf_put_var_double(fileID, ncbvarid, zbounds);
}
cdf_put_var_double(fileID, ncbvarid, zbounds);
}
if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
}
if ( ndims == 0 ) streamptr->nczvarID[zaxisindex] = ncvarid;
{
int natts;
cdiInqNatts(zaxisID, CDI_GLOBAL, &natts);
{
int natts;
cdiInqNatts(zaxisID, CDI_GLOBAL, &natts);
if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
if ( natts > 0 && streamptr->ncmode == 2 ) cdf_redef(fileID);
cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
cdfDefineAttributes(zaxisID, CDI_GLOBAL, fileID, ncvarid);
if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
}
if ( natts > 0 && streamptr->ncmode == 2 ) cdf_enddef(fileID);
}
}
}
}
if ( dimID != UNDEFID )
......
......@@ -2304,24 +2304,6 @@ void grib2DefLevel(grib_handle *gh, int gcinit, long leveltype1, long leveltype2
}
}
/*
void grib_verfiy_zaxis(int zaxisID, double sf)
{
printf("grb_verfiy_vlist called\n");
int zaxisID = vlistZaxis(vlistID, index);
int nlevels = zaxisInqSize(zaxisID);
int zaxistype = zaxisInqType(zaxisID);
double *levels = (double *) Malloc(nlevels*sizeof(double));
int *ilevels = (int *) Malloc(nlevels*sizeof(int));
zaxisInqLevels(zaxisID, levels);
for ( int i = 0; i < nlevels; ++i )
printf("level %d %g\n", i+1, levels[i]);
Free(ilevels);
Free(levels);
}
*/
static
void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelID, int gcinit, int proddef_template_num)
{
......@@ -2332,7 +2314,7 @@ void gribapiDefLevel(int editionNumber, grib_handle *gh, int zaxisID, int levelI
int zaxistype = zaxisInqType(zaxisID);
long ltype = zaxisInqLtype(zaxisID);
long ltype2 = zaxisInqLtype2(zaxisID);
double level = zaxisInqLevel(zaxisID, levelID);
double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levelID) : levelID+1;
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
......
......@@ -580,33 +580,41 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
if ( nlevs != nlevs2 )
{
int nvct = 0;
double *levels = NULL;
double *lbounds = NULL, *ubounds = NULL;
const double *vct = NULL;
char ctemp[CDI_MAX_NAME];
if ( !vars1[varID].levinfo ) cdiVlistCreateVarLevInfo(vlistptr1, varID);
zaxisID = vars1[varID].zaxisID;
double *levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
if ( !vars1[varID].levinfo )
cdiVlistCreateVarLevInfo(vlistptr1, varID);
{
int levID2 = 0;
for ( int levID = 0; levID < nlevs; ++levID )
if ( vars1[varID].levinfo[levID].flag )
{
vars1[varID].levinfo[levID].flevelID = levID2;
vars1[varID].levinfo[levID].mlevelID = levID2;
levels[levID2++] = zaxisInqLevel(zaxisID, levID);
}
}
int zaxisType = zaxisInqType(zaxisID);
if ( zaxisType == ZAXIS_HYBRID )
{
nvct = zaxisInqVctSize(zaxisID);
vct = zaxisInqVctPtr(zaxisID);
}
int zaxisType = zaxisInqType(zaxisID);
int levID2 = 0;
for ( int levID = 0; levID < nlevs; ++levID )
if ( vars1[varID].levinfo[levID].flag )
{
vars1[varID].levinfo[levID].flevelID = levID2;
vars1[varID].levinfo[levID].mlevelID = levID2;
}
if ( zaxisInqLevels(zaxisID, NULL) )
{
levels = (double *) Malloc((size_t)nlevs2 * sizeof (double));
levID2 = 0;
for ( int levID = 0; levID < nlevs; ++levID )
if ( vars1[varID].levinfo[levID].flag )
{
levels[levID2++] = zaxisInqLevel(zaxisID, levID);
}
}
if ( zaxisType == ZAXIS_HYBRID )
{
nvct = zaxisInqVctSize(zaxisID);
vct = zaxisInqVctPtr(zaxisID);
}
if ( zaxisInqLbounds(zaxisID, NULL) && zaxisInqUbounds(zaxisID, NULL) )
{
......@@ -619,7 +627,7 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
zaxisInqLbounds(zaxisID, lbounds1);
zaxisInqUbounds(zaxisID, ubounds1);
int levID2 = 0;
levID2 = 0;
for ( int levID = 0; levID < nlevs; ++levID )
if ( vars1[varID].levinfo[levID].flag )
{
......@@ -632,8 +640,8 @@ void vlistCopyFlag(int vlistID2, int vlistID1)
}
int zaxisID2 = vlist_generate_zaxis(vlistID2, zaxisType, nlevs2, levels, lbounds, ubounds, nvct, vct);
Free(levels);
Free(lbounds);
if ( levels ) Free(levels);
if ( lbounds ) Free(lbounds);
zaxisInqName(zaxisID, ctemp);
zaxisDefName(zaxisID2, ctemp);
......@@ -836,19 +844,22 @@ void vlistMerge(int vlistID2, int vlistID1)
int zaxisID = zaxisDuplicate(zaxisID2);
zaxisResize(zaxisID, nlevs);
if ( zaxisInqLevels(zaxisID1, NULL) )
{
zaxisResize(zaxisID, nlevs);
double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
double *levels = (double *) Malloc((size_t)nlevs1 * sizeof(double));
zaxisInqLevels(zaxisID1, levels);
/*
for ( levID = 0; levID < nlevs1; levID++ )
fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
*/
for ( int levID = 0; levID < nlevs1; levID++ )
zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
zaxisInqLevels(zaxisID1, levels);
/*
for ( levID = 0; levID < nlevs1; levID++ )
fprintf(stderr, "%d %d %d %d %d %g\n", varID, levID, nlevs1, nlevs2, vars2[varID].nlevs, levels[levID]);
*/
for ( int levID = 0; levID < nlevs1; levID++ )
zaxisDefLevel(zaxisID, nlevs2+levID, levels[levID]);
Free(levels);
Free(levels);
}
for ( int index = 0; index < vlistptr2->nzaxis; index++ )
if ( vlistptr2->zaxisIDs[index] == zaxisID2 )
......@@ -1071,7 +1082,8 @@ void vlistPrintKernel(vlist_t *vlistptr, FILE *fp)
int mlevID = li.mlevelID;
int index = li.index;
int flag = li.flag;
double level = zaxisInqLevel(zaxisID, levID);
double level = zaxisInqLevels(zaxisID, NULL) ? zaxisInqLevel(zaxisID, levID) : levID+1;
fprintf(fp, "%6d %6d %6d %6d %6d %6d %6d %6d %5d %.9g\n",
varID, levID, fvarID, flevID, mvarID, mlevID, index,
......
......@@ -212,12 +212,6 @@ zaxisCreate_(int zaxistype, int size, int id)
zaxisptr->positive = ZaxistypeEntry[zaxistype].positive;
double *vals = zaxisptr->vals
= (double *) Malloc((size_t)size * sizeof(double));
for ( int ilev = 0; ilev < size; ilev++ )
vals[ilev] = 0.0;
return zaxisID;
}
......@@ -688,11 +682,14 @@ The function @func{zaxisDefLevels} defines the levels of a Z-axis.
void zaxisDefLevels(int zaxisID, const double *levels)
{
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
size_t size = (size_t)zaxisptr->size;
if ( zaxisptr->vals == NULL )
zaxisptr->vals = (double*) Malloc(size*sizeof(double));
int size = zaxisptr->size;
double *vals = zaxisptr->vals;
for ( int ilev = 0; ilev < size; ilev++ )
for ( size_t ilev = 0; ilev < size; ++ilev )
vals[ilev] = levels[ilev];
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
......@@ -716,8 +713,14 @@ The function @func{zaxisDefLevel} defines one level of a Z-axis.
void zaxisDefLevel(int zaxisID, int levelID, double level)
{
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
if ( levelID >= 0 && levelID < zaxisptr->size )
int size = zaxisptr->size;
if ( zaxisptr->vals == NULL )
zaxisptr->vals = (double*) Malloc((size_t)size*sizeof(double));
if ( levelID >= 0 && levelID < size )
zaxisptr->vals[levelID] = level;
reshSetStatus(zaxisID, &zaxisOps, RESH_DESYNC_IN_USE);
}
......@@ -845,7 +848,7 @@ The function @func{zaxisInqLevel} returns one level of a Z-axis.
*/
double zaxisInqLevel(int zaxisID, int levelID)
{
double level = levelID;
double level = 0;
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
if ( zaxisptr->vals && levelID >= 0 && levelID < zaxisptr->size )
......@@ -854,9 +857,10 @@ double zaxisInqLevel(int zaxisID, int levelID)
return level;
}
double zaxisInqLbound(int zaxisID, int levelID)
{
double level = levelID;
double level = 0;
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
if ( zaxisptr->lbounds && levelID >= 0 && levelID < zaxisptr->size )
......@@ -868,7 +872,7 @@ double zaxisInqLbound(int zaxisID, int levelID)
double zaxisInqUbound(int zaxisID, int levelID)
{
double level = levelID;
double level = 0;
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
if ( zaxisptr->ubounds && levelID >= 0 && levelID < zaxisptr->size )
......@@ -901,12 +905,21 @@ The function @func{zaxisInqLevels} returns all levels of a Z-axis.
@func{zaxisInqLevels} saves all levels to the parameter @func{levels}.
@EndFunction
*/
void zaxisInqLevels(int zaxisID, double *levels)
int zaxisInqLevels(int zaxisID, double *levels)
{
int size = 0;
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
int size = zaxisptr->size;
for ( int i = 0; i < size; i++ )
levels[i] = zaxisptr->vals[i];
if ( zaxisptr->vals )
{
size = zaxisptr->size;
if ( levels )
for ( int i = 0; i < size; i++ )
levels[i] = zaxisptr->vals[i];
}
return size;
}
......@@ -972,6 +985,7 @@ int zaxisInqLevelID(int zaxisID, double level)
if ( zaxisptr->vals )
{
int size = zaxisptr->size;
for ( int i = 0; i < size; i++ )
if ( fabs(level-zaxisptr->vals[i]) < DBL_EPSILON )
{
......@@ -1041,7 +1055,7 @@ void cdiCheckZaxis(int zaxisID)
{
zaxis_t *zaxisptr = zaxisID2Ptr(zaxisID);
if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC )
if ( zaxisInqType(zaxisID) == ZAXIS_GENERIC && zaxisptr->vals )
{
int size = zaxisptr->size;
if ( size > 1 )
......@@ -1179,7 +1193,7 @@ void zaxisResize(int zaxisID, int size)
zaxisptr->size = size;
if ( zaxisptr->vals )
zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size * sizeof(double));
zaxisptr->vals = (double *) Realloc(zaxisptr->vals, (size_t)size*sizeof(double));
}
......@@ -1203,7 +1217,6 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->vals )
{
size_t size = (size_t)zaxissize;
zaxisptrnew->vals = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->vals, zaxisptr->vals, size * sizeof (double));
}
......@@ -1211,7 +1224,6 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->lbounds )
{
size_t size = (size_t)zaxissize;
zaxisptrnew->lbounds = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->lbounds, zaxisptr->lbounds, size * sizeof(double));
}
......@@ -1219,7 +1231,6 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->ubounds )
{
size_t size = (size_t)zaxissize;
zaxisptrnew->ubounds = (double *) Malloc(size * sizeof (double));
memcpy(zaxisptrnew->ubounds, zaxisptr->ubounds, size * sizeof (double));
}
......@@ -1227,7 +1238,6 @@ int zaxisDuplicate(int zaxisID)
if ( zaxisptr->vct )
{
size_t size = (size_t)zaxisptr->vctsize;
if ( size )
{
zaxisptrnew->vctsize = (int)size;
......@@ -1255,6 +1265,7 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, int index, FILE *fp)
int dig = (prec == DATATYPE_FLT64) ? 15 : 7;
int nbyte;
int nbyte0 = 0;
fprintf(fp, "#\n");
fprintf(fp, "# zaxisID %d\n", index);
......@@ -1270,19 +1281,22 @@ void zaxisPrintKernel(zaxis_t *zaxisptr, int index, FILE *fp)
if ( zaxisptr->longname[0] ) fprintf(fp, "longname = %s\n", zaxisptr->longname);
if ( zaxisptr->units[0] ) fprintf(fp, "units = %s\n", zaxisptr->units);
nbyte0 = fprintf(fp, "levels = ");
int nbyte = nbyte0;
for ( int levelID = 0; levelID < nlevels; levelID++ )
if ( zaxisptr->vals )
{
if ( nbyte > 80 )
{
fprintf(fp, "\n");
fprintf(fp, "%*s", nbyte0, "");
nbyte = nbyte0;
}
nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
nbyte0 = fprintf(fp, "levels = ");
nbyte = nbyte0;
for ( int levelID = 0; levelID < nlevels; levelID++ )
{
if ( nbyte > 80 )
{
fprintf(fp, "\n");
fprintf(fp, "%*s", nbyte0, "");
nbyte = nbyte0;
}
nbyte += fprintf(fp, "%.*g ", dig, zaxisptr->vals[levelID]);
}
fprintf(fp, "\n");
}
fprintf(fp, "\n");
if ( zaxisptr->lbounds && zaxisptr->ubounds )
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment