Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
C
core
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
LibreOffice
core
Commits
c0f48981
Kaydet (Commit)
c0f48981
authored
Kas 13, 2015
tarafından
Michael Stahl
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
sc: replace boost::ptr_vector with std::vector<std::unique_ptr>
Change-Id: I59831588fb7bc7e907fbffb24ddfe068552b6492
üst
6f6056d9
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
64 additions
and
52 deletions
+64
-52
precompiled_sc.hxx
sc/inc/pch/precompiled_sc.hxx
+0
-1
precompiled_scfilt.hxx
sc/inc/pch/precompiled_scfilt.hxx
+0
-1
queryparam.hxx
sc/inc/queryparam.hxx
+4
-3
dpsave.cxx
sc/source/core/data/dpsave.cxx
+3
-3
sortparam.cxx
sc/source/core/data/sortparam.cxx
+2
-0
table3.cxx
sc/source/core/data/table3.cxx
+2
-2
queryparam.cxx
sc/source/core/tool/queryparam.cxx
+53
-42
No files found.
sc/inc/pch/precompiled_sc.hxx
Dosyayı görüntüle @
c0f48981
...
@@ -40,7 +40,6 @@
...
@@ -40,7 +40,6 @@
#include <boost/math/special_functions/log1p.hpp>
#include <boost/math/special_functions/log1p.hpp>
#include <boost/noncopyable.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/ptr_container/ptr_map.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <memory>
#include <memory>
#include <cassert>
#include <cassert>
#include <climits>
#include <climits>
...
...
sc/inc/pch/precompiled_scfilt.hxx
Dosyayı görüntüle @
c0f48981
...
@@ -21,7 +21,6 @@
...
@@ -21,7 +21,6 @@
#include <boost/bind.hpp>
#include <boost/bind.hpp>
#include <boost/checked_delete.hpp>
#include <boost/checked_delete.hpp>
#include <boost/noncopyable.hpp>
#include <boost/noncopyable.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <memory>
#include <memory>
#include <cassert>
#include <cassert>
#include <com/sun/star/awt/DeviceInfo.hpp>
#include <com/sun/star/awt/DeviceInfo.hpp>
...
...
sc/inc/queryparam.hxx
Dosyayı görüntüle @
c0f48981
...
@@ -23,7 +23,8 @@
...
@@ -23,7 +23,8 @@
#include "global.hxx"
#include "global.hxx"
#include "types.hxx"
#include "types.hxx"
#include <boost/ptr_container/ptr_vector.hpp>
#include <memory>
#include <vector>
class
SvNumberFormatter
;
class
SvNumberFormatter
;
...
@@ -61,7 +62,7 @@ struct ScQueryParamBase
...
@@ -61,7 +62,7 @@ struct ScQueryParamBase
SvNumberFormatter
*
pFormatter
);
SvNumberFormatter
*
pFormatter
);
protected
:
protected
:
typedef
boost
::
ptr_vector
<
ScQueryEntry
>
EntriesType
;
typedef
std
::
vector
<
std
::
unique_ptr
<
ScQueryEntry
>
>
EntriesType
;
public
:
public
:
typedef
EntriesType
::
const_iterator
const_iterator
;
typedef
EntriesType
::
const_iterator
const_iterator
;
...
@@ -73,7 +74,7 @@ protected:
...
@@ -73,7 +74,7 @@ protected:
ScQueryParamBase
();
ScQueryParamBase
();
ScQueryParamBase
(
const
ScQueryParamBase
&
r
);
ScQueryParamBase
(
const
ScQueryParamBase
&
r
);
EntriesType
m
a
Entries
;
EntriesType
m
_
Entries
;
};
};
struct
ScQueryParamTable
struct
ScQueryParamTable
...
...
sc/source/core/data/dpsave.cxx
Dosyayı görüntüle @
c0f48981
...
@@ -1085,9 +1085,9 @@ void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
...
@@ -1085,9 +1085,9 @@ void ScDPSaveData::SetPosition( ScDPSaveDimension* pDim, long nNew )
{
{
if
(
pDim
==
it
->
get
())
if
(
pDim
==
it
->
get
())
{
{
// Tell
ptr_vector to give up ownership of this element. Don't
// Tell
vector<unique_ptr> to give up ownership of this element.
//
delete this instance as it is re-inserted into the container
//
Don't delete this instance as it is re-inserted into the
// later.
//
container
later.
it
->
release
();
it
->
release
();
m_DimList
.
erase
(
it
);
m_DimList
.
erase
(
it
);
break
;
break
;
...
...
sc/source/core/data/sortparam.cxx
Dosyayı görüntüle @
c0f48981
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
#include <osl/diagnose.h>
#include <osl/diagnose.h>
#include <algorithm>
ScSortParam
::
ScSortParam
()
ScSortParam
::
ScSortParam
()
{
{
Clear
();
Clear
();
...
...
sc/source/core/data/table3.cxx
Dosyayı görüntüle @
c0f48981
...
@@ -2620,9 +2620,9 @@ bool ScTable::ValidQuery(
...
@@ -2620,9 +2620,9 @@ bool ScTable::ValidQuery(
long
nPos
=
-
1
;
long
nPos
=
-
1
;
QueryEvaluator
aEval
(
*
pDocument
,
*
this
,
rParam
,
pbTestEqualCondition
);
QueryEvaluator
aEval
(
*
pDocument
,
*
this
,
rParam
,
pbTestEqualCondition
);
ScQueryParam
::
const_iterator
it
,
itBeg
=
rParam
.
begin
(),
itEnd
=
rParam
.
end
();
ScQueryParam
::
const_iterator
it
,
itBeg
=
rParam
.
begin
(),
itEnd
=
rParam
.
end
();
for
(
it
=
itBeg
;
it
!=
itEnd
&&
it
->
bDoQuery
;
++
it
)
for
(
it
=
itBeg
;
it
!=
itEnd
&&
(
*
it
)
->
bDoQuery
;
++
it
)
{
{
const
ScQueryEntry
&
rEntry
=
*
it
;
const
ScQueryEntry
&
rEntry
=
*
*
it
;
SCCOL
nCol
=
static_cast
<
SCCOL
>
(
rEntry
.
nField
);
SCCOL
nCol
=
static_cast
<
SCCOL
>
(
rEntry
.
nField
);
// We can only handle one single direct query passed as a known pCell,
// We can only handle one single direct query passed as a known pCell,
...
...
sc/source/core/tool/queryparam.cxx
Dosyayı görüntüle @
c0f48981
...
@@ -23,8 +23,11 @@
...
@@ -23,8 +23,11 @@
#include <svl/sharedstringpool.hxx>
#include <svl/sharedstringpool.hxx>
#include <svl/zforlist.hxx>
#include <svl/zforlist.hxx>
#include <o3tl/make_unique.hxx>
#include <osl/diagnose.h>
#include <osl/diagnose.h>
#include <algorithm>
namespace
{
namespace
{
const
size_t
MAXQUERY
=
8
;
const
size_t
MAXQUERY
=
8
;
...
@@ -34,17 +37,17 @@ class FindByField : public std::unary_function<ScQueryEntry, bool>
...
@@ -34,17 +37,17 @@ class FindByField : public std::unary_function<ScQueryEntry, bool>
SCCOLROW
mnField
;
SCCOLROW
mnField
;
public
:
public
:
explicit
FindByField
(
SCCOLROW
nField
)
:
mnField
(
nField
)
{}
explicit
FindByField
(
SCCOLROW
nField
)
:
mnField
(
nField
)
{}
bool
operator
()
(
const
ScQueryEntry
&
r
Entry
)
const
bool
operator
()
(
const
std
::
unique_ptr
<
ScQueryEntry
>&
rp
Entry
)
const
{
{
return
r
Entry
.
bDoQuery
&&
rEntry
.
nField
==
mnField
;
return
r
pEntry
->
bDoQuery
&&
rpEntry
->
nField
==
mnField
;
}
}
};
};
struct
FindUnused
:
public
std
::
unary_function
<
ScQueryEntry
,
bool
>
struct
FindUnused
:
public
std
::
unary_function
<
ScQueryEntry
,
bool
>
{
{
bool
operator
()
(
const
ScQueryEntry
&
r
Entry
)
const
bool
operator
()
(
const
std
::
unique_ptr
<
ScQueryEntry
>&
rp
Entry
)
const
{
{
return
!
r
Entry
.
bDoQuery
;
return
!
r
pEntry
->
bDoQuery
;
}
}
};
};
...
@@ -52,12 +55,12 @@ struct FindUnused : public std::unary_function<ScQueryEntry, bool>
...
@@ -52,12 +55,12 @@ struct FindUnused : public std::unary_function<ScQueryEntry, bool>
ScQueryParamBase
::
const_iterator
ScQueryParamBase
::
begin
()
const
ScQueryParamBase
::
const_iterator
ScQueryParamBase
::
begin
()
const
{
{
return
m
a
Entries
.
begin
();
return
m
_
Entries
.
begin
();
}
}
ScQueryParamBase
::
const_iterator
ScQueryParamBase
::
end
()
const
ScQueryParamBase
::
const_iterator
ScQueryParamBase
::
end
()
const
{
{
return
m
a
Entries
.
end
();
return
m
_
Entries
.
end
();
}
}
ScQueryParamBase
::
ScQueryParamBase
()
:
ScQueryParamBase
::
ScQueryParamBase
()
:
...
@@ -70,14 +73,17 @@ ScQueryParamBase::ScQueryParamBase() :
...
@@ -70,14 +73,17 @@ ScQueryParamBase::ScQueryParamBase() :
mbRangeLookup
(
false
)
mbRangeLookup
(
false
)
{
{
for
(
size_t
i
=
0
;
i
<
MAXQUERY
;
++
i
)
for
(
size_t
i
=
0
;
i
<
MAXQUERY
;
++
i
)
m
aEntries
.
push_back
(
new
ScQueryEntry
);
m
_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
()
);
}
}
ScQueryParamBase
::
ScQueryParamBase
(
const
ScQueryParamBase
&
r
)
:
ScQueryParamBase
::
ScQueryParamBase
(
const
ScQueryParamBase
&
r
)
bHasHeader
(
r
.
bHasHeader
),
bByRow
(
r
.
bByRow
),
bInplace
(
r
.
bInplace
),
bCaseSens
(
r
.
bCaseSens
),
:
bHasHeader
(
r
.
bHasHeader
),
bByRow
(
r
.
bByRow
),
bInplace
(
r
.
bInplace
),
bCaseSens
(
r
.
bCaseSens
)
bRegExp
(
r
.
bRegExp
),
bDuplicate
(
r
.
bDuplicate
),
mbRangeLookup
(
r
.
mbRangeLookup
),
,
bRegExp
(
r
.
bRegExp
),
bDuplicate
(
r
.
bDuplicate
),
mbRangeLookup
(
r
.
mbRangeLookup
)
maEntries
(
r
.
maEntries
)
{
{
for
(
auto
const
&
it
:
r
.
m_Entries
)
{
m_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
(
*
it
));
}
}
}
ScQueryParamBase
::~
ScQueryParamBase
()
ScQueryParamBase
::~
ScQueryParamBase
()
...
@@ -91,43 +97,43 @@ bool ScQueryParamBase::IsValidFieldIndex() const
...
@@ -91,43 +97,43 @@ bool ScQueryParamBase::IsValidFieldIndex() const
SCSIZE
ScQueryParamBase
::
GetEntryCount
()
const
SCSIZE
ScQueryParamBase
::
GetEntryCount
()
const
{
{
return
m
a
Entries
.
size
();
return
m
_
Entries
.
size
();
}
}
const
ScQueryEntry
&
ScQueryParamBase
::
GetEntry
(
SCSIZE
n
)
const
const
ScQueryEntry
&
ScQueryParamBase
::
GetEntry
(
SCSIZE
n
)
const
{
{
return
ma
Entries
[
n
];
return
*
m_
Entries
[
n
];
}
}
ScQueryEntry
&
ScQueryParamBase
::
GetEntry
(
SCSIZE
n
)
ScQueryEntry
&
ScQueryParamBase
::
GetEntry
(
SCSIZE
n
)
{
{
return
ma
Entries
[
n
];
return
*
m_
Entries
[
n
];
}
}
ScQueryEntry
&
ScQueryParamBase
::
AppendEntry
()
ScQueryEntry
&
ScQueryParamBase
::
AppendEntry
()
{
{
// Find the first unused entry.
// Find the first unused entry.
EntriesType
::
iterator
itr
=
std
::
find_if
(
EntriesType
::
iterator
itr
=
std
::
find_if
(
m
aEntries
.
begin
(),
ma
Entries
.
end
(),
FindUnused
());
m
_Entries
.
begin
(),
m_
Entries
.
end
(),
FindUnused
());
if
(
itr
!=
m
a
Entries
.
end
())
if
(
itr
!=
m
_
Entries
.
end
())
// Found!
// Found!
return
*
itr
;
return
*
*
itr
;
// Add a new entry to the end.
// Add a new entry to the end.
m
aEntries
.
push_back
(
new
ScQueryEntry
);
m
_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
()
);
return
ma
Entries
.
back
();
return
*
m_
Entries
.
back
();
}
}
ScQueryEntry
*
ScQueryParamBase
::
FindEntryByField
(
SCCOLROW
nField
,
bool
bNew
)
ScQueryEntry
*
ScQueryParamBase
::
FindEntryByField
(
SCCOLROW
nField
,
bool
bNew
)
{
{
EntriesType
::
iterator
itr
=
std
::
find_if
(
EntriesType
::
iterator
itr
=
std
::
find_if
(
m
aEntries
.
begin
(),
ma
Entries
.
end
(),
FindByField
(
nField
));
m
_Entries
.
begin
(),
m_
Entries
.
end
(),
FindByField
(
nField
));
if
(
itr
!=
m
a
Entries
.
end
())
if
(
itr
!=
m
_
Entries
.
end
())
{
{
// existing entry found!
// existing entry found!
return
&
(
*
itr
);
return
(
*
itr
).
get
(
);
}
}
if
(
!
bNew
)
if
(
!
bNew
)
...
@@ -140,15 +146,15 @@ ScQueryEntry* ScQueryParamBase::FindEntryByField(SCCOLROW nField, bool bNew)
...
@@ -140,15 +146,15 @@ ScQueryEntry* ScQueryParamBase::FindEntryByField(SCCOLROW nField, bool bNew)
void
ScQueryParamBase
::
RemoveEntryByField
(
SCCOLROW
nField
)
void
ScQueryParamBase
::
RemoveEntryByField
(
SCCOLROW
nField
)
{
{
EntriesType
::
iterator
itr
=
std
::
find_if
(
EntriesType
::
iterator
itr
=
std
::
find_if
(
m
aEntries
.
begin
(),
ma
Entries
.
end
(),
FindByField
(
nField
));
m
_Entries
.
begin
(),
m_
Entries
.
end
(),
FindByField
(
nField
));
if
(
itr
!=
m
a
Entries
.
end
())
if
(
itr
!=
m
_
Entries
.
end
())
{
{
m
a
Entries
.
erase
(
itr
);
m
_
Entries
.
erase
(
itr
);
if
(
m
a
Entries
.
size
()
<
MAXQUERY
)
if
(
m
_
Entries
.
size
()
<
MAXQUERY
)
// Make sure that we have at least MAXQUERY number of entries at
// Make sure that we have at least MAXQUERY number of entries at
// all times.
// all times.
m
aEntries
.
push_back
(
new
ScQueryEntry
);
m
_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
()
);
}
}
}
}
...
@@ -157,17 +163,17 @@ void ScQueryParamBase::Resize(size_t nNew)
...
@@ -157,17 +163,17 @@ void ScQueryParamBase::Resize(size_t nNew)
if
(
nNew
<
MAXQUERY
)
if
(
nNew
<
MAXQUERY
)
nNew
=
MAXQUERY
;
// never less than MAXQUERY
nNew
=
MAXQUERY
;
// never less than MAXQUERY
if
(
nNew
<
m
a
Entries
.
size
())
if
(
nNew
<
m
_
Entries
.
size
())
{
{
size_t
n
=
m
a
Entries
.
size
()
-
nNew
;
size_t
n
=
m
_
Entries
.
size
()
-
nNew
;
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
m
a
Entries
.
pop_back
();
m
_
Entries
.
pop_back
();
}
}
else
if
(
nNew
>
m
a
Entries
.
size
())
else
if
(
nNew
>
m
_
Entries
.
size
())
{
{
size_t
n
=
nNew
-
m
a
Entries
.
size
();
size_t
n
=
nNew
-
m
_
Entries
.
size
();
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
for
(
size_t
i
=
0
;
i
<
n
;
++
i
)
m
aEntries
.
push_back
(
new
ScQueryEntry
);
m
_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
()
);
}
}
}
}
...
@@ -175,7 +181,7 @@ void ScQueryParamBase::FillInExcelSyntax(
...
@@ -175,7 +181,7 @@ void ScQueryParamBase::FillInExcelSyntax(
svl
::
SharedStringPool
&
rPool
,
const
OUString
&
rStr
,
SCSIZE
nIndex
,
SvNumberFormatter
*
pFormatter
)
svl
::
SharedStringPool
&
rPool
,
const
OUString
&
rStr
,
SCSIZE
nIndex
,
SvNumberFormatter
*
pFormatter
)
{
{
const
OUString
aCellStr
=
rStr
;
const
OUString
aCellStr
=
rStr
;
if
(
nIndex
>=
m
a
Entries
.
size
())
if
(
nIndex
>=
m
_
Entries
.
size
())
Resize
(
nIndex
+
1
);
Resize
(
nIndex
+
1
);
ScQueryEntry
&
rEntry
=
GetEntry
(
nIndex
);
ScQueryEntry
&
rEntry
=
GetEntry
(
nIndex
);
...
@@ -297,9 +303,10 @@ void ScQueryParam::Clear()
...
@@ -297,9 +303,10 @@ void ScQueryParam::Clear()
bHasHeader
=
bCaseSens
=
bRegExp
=
false
;
bHasHeader
=
bCaseSens
=
bRegExp
=
false
;
bInplace
=
bByRow
=
bDuplicate
=
true
;
bInplace
=
bByRow
=
bDuplicate
=
true
;
boost
::
ptr_vector
<
ScQueryEntry
>::
iterator
itr
=
maEntries
.
begin
(),
itrEnd
=
maEntries
.
end
();
for
(
auto
&
itr
:
m_Entries
)
for
(;
itr
!=
itrEnd
;
++
itr
)
{
itr
->
Clear
();
itr
->
Clear
();
}
ClearDestParams
();
ClearDestParams
();
}
}
...
@@ -330,7 +337,11 @@ ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r )
...
@@ -330,7 +337,11 @@ ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r )
bByRow
=
r
.
bByRow
;
bByRow
=
r
.
bByRow
;
bDestPers
=
r
.
bDestPers
;
bDestPers
=
r
.
bDestPers
;
maEntries
=
r
.
maEntries
.
clone
();
m_Entries
.
clear
();
for
(
auto
const
&
it
:
r
.
m_Entries
)
{
m_Entries
.
push_back
(
o3tl
::
make_unique
<
ScQueryEntry
>
(
*
it
));
}
return
*
this
;
return
*
this
;
}
}
...
@@ -345,8 +356,8 @@ bool ScQueryParam::operator==( const ScQueryParam& rOther ) const
...
@@ -345,8 +356,8 @@ bool ScQueryParam::operator==( const ScQueryParam& rOther ) const
SCSIZE
nEntryCount
=
GetEntryCount
();
SCSIZE
nEntryCount
=
GetEntryCount
();
SCSIZE
nOtherEntryCount
=
rOther
.
GetEntryCount
();
SCSIZE
nOtherEntryCount
=
rOther
.
GetEntryCount
();
while
(
nUsed
<
nEntryCount
&&
maEntries
[
nUsed
].
bDoQuery
)
++
nUsed
;
while
(
nUsed
<
nEntryCount
&&
m_Entries
[
nUsed
]
->
bDoQuery
)
++
nUsed
;
while
(
nOtherUsed
<
nOtherEntryCount
&&
rOther
.
maEntries
[
nOtherUsed
].
bDoQuery
)
while
(
nOtherUsed
<
nOtherEntryCount
&&
rOther
.
m_Entries
[
nOtherUsed
]
->
bDoQuery
)
++
nOtherUsed
;
++
nOtherUsed
;
if
(
(
nUsed
==
nOtherUsed
)
if
(
(
nUsed
==
nOtherUsed
)
...
@@ -368,7 +379,7 @@ bool ScQueryParam::operator==( const ScQueryParam& rOther ) const
...
@@ -368,7 +379,7 @@ bool ScQueryParam::operator==( const ScQueryParam& rOther ) const
{
{
bEqual
=
true
;
bEqual
=
true
;
for
(
SCSIZE
i
=
0
;
i
<
nUsed
&&
bEqual
;
i
++
)
for
(
SCSIZE
i
=
0
;
i
<
nUsed
&&
bEqual
;
i
++
)
bEqual
=
maEntries
[
i
]
==
rOther
.
ma
Entries
[
i
];
bEqual
=
*
m_Entries
[
i
]
==
*
rOther
.
m_
Entries
[
i
];
}
}
return
bEqual
;
return
bEqual
;
}
}
...
@@ -386,9 +397,9 @@ void ScQueryParam::MoveToDest()
...
@@ -386,9 +397,9 @@ void ScQueryParam::MoveToDest()
nCol2
=
sal
::
static_int_cast
<
SCCOL
>
(
nCol2
+
nDifX
);
nCol2
=
sal
::
static_int_cast
<
SCCOL
>
(
nCol2
+
nDifX
);
nRow2
=
sal
::
static_int_cast
<
SCROW
>
(
nRow2
+
nDifY
);
nRow2
=
sal
::
static_int_cast
<
SCROW
>
(
nRow2
+
nDifY
);
nTab
=
sal
::
static_int_cast
<
SCTAB
>
(
nTab
+
nDifZ
);
nTab
=
sal
::
static_int_cast
<
SCTAB
>
(
nTab
+
nDifZ
);
size_t
n
=
m
a
Entries
.
size
();
size_t
n
=
m
_
Entries
.
size
();
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
for
(
size_t
i
=
0
;
i
<
n
;
i
++
)
m
aEntries
[
i
].
nField
+=
nDifX
;
m
_Entries
[
i
]
->
nField
+=
nDifX
;
bInplace
=
true
;
bInplace
=
true
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a 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