mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-07-01 02:41:48 +00:00
[upstream_utils] Recopy Eigen source (#8251)
Upstream slid the tag (again). Change to the SHA commit ID until things stabilize.
This commit is contained in:
@@ -235,8 +235,7 @@ DenseBase<Derived>::Constant(const Scalar& value) {
|
||||
* \sa LinSpaced(Index,const Scalar&, const Scalar&), setLinSpaced(Index,const Scalar&,const Scalar&)
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<
|
||||
Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const Scalar& high) {
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
return DenseBase<Derived>::NullaryExpr(size, internal::linspaced_op<Scalar>(low, high, size));
|
||||
@@ -247,8 +246,7 @@ DenseBase<Derived>::LinSpaced(Sequential_t, Index size, const Scalar& low, const
|
||||
* \sa LinSpaced(const Scalar&, const Scalar&)
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<
|
||||
Derived>::RandomAccessLinSpacedReturnType
|
||||
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const typename DenseBase<Derived>::RandomAccessLinSpacedReturnType
|
||||
DenseBase<Derived>::LinSpaced(Sequential_t, const Scalar& low, const Scalar& high) {
|
||||
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
|
||||
EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived)
|
||||
|
||||
@@ -306,12 +306,12 @@ class DenseBase
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Constant(Index size, const Scalar& value);
|
||||
EIGEN_DEVICE_FUNC static const ConstantReturnType Constant(const Scalar& value);
|
||||
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t, Index size,
|
||||
const Scalar& low,
|
||||
const Scalar& high);
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t,
|
||||
const Scalar& low,
|
||||
const Scalar& high);
|
||||
EIGEN_DEPRECATED_WITH_REASON("The method may result in accuracy loss. Use .EqualSpaced() instead.")
|
||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t, Index size, const Scalar& low,
|
||||
const Scalar& high);
|
||||
EIGEN_DEPRECATED_WITH_REASON("The method may result in accuracy loss. Use .EqualSpaced() instead.")
|
||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Sequential_t, const Scalar& low,
|
||||
const Scalar& high);
|
||||
|
||||
EIGEN_DEVICE_FUNC static const RandomAccessLinSpacedReturnType LinSpaced(Index size, const Scalar& low,
|
||||
const Scalar& high);
|
||||
|
||||
@@ -65,7 +65,7 @@ struct default_packet_traits {
|
||||
HasAbsDiff = 0,
|
||||
HasBlend = 0,
|
||||
// This flag is used to indicate whether packet comparison is supported.
|
||||
// pcmp_eq, pcmp_lt and pcmp_le should be defined for it to be true.
|
||||
// pcmp_eq and pcmp_lt should be defined for it to be true.
|
||||
HasCmp = 0,
|
||||
|
||||
HasDiv = 0,
|
||||
@@ -432,30 +432,6 @@ EIGEN_DEVICE_FUNC inline Packet pzero(const Packet& a) {
|
||||
return pzero_impl<Packet>::run(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a <= b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_le(const Packet& a, const Packet& b) {
|
||||
return a <= b ? ptrue(a) : pzero(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a < b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_lt(const Packet& a, const Packet& b) {
|
||||
return a < b ? ptrue(a) : pzero(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a == b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_eq(const Packet& a, const Packet& b) {
|
||||
return a == b ? ptrue(a) : pzero(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_lt_or_nan(const Packet& a, const Packet& b) {
|
||||
return a >= b ? pzero(a) : ptrue(a);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
struct bit_and {
|
||||
EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE T operator()(const T& a, const T& b) const { return a & b; }
|
||||
@@ -582,6 +558,30 @@ EIGEN_DEVICE_FUNC inline Packet pandnot(const Packet& a, const Packet& b) {
|
||||
return pand(a, pnot(b));
|
||||
}
|
||||
|
||||
/** \internal \returns a < b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_lt(const Packet& a, const Packet& b) {
|
||||
return a < b ? ptrue(a) : pzero(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a == b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_eq(const Packet& a, const Packet& b) {
|
||||
return a == b ? ptrue(a) : pzero(a);
|
||||
}
|
||||
|
||||
/** \internal \returns a <= b as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_le(const Packet& a, const Packet& b) {
|
||||
return por(pcmp_eq(a, b), pcmp_lt(a, b));
|
||||
}
|
||||
|
||||
/** \internal \returns a < b or a==NaN or b==NaN as a bit mask */
|
||||
template <typename Packet>
|
||||
EIGEN_DEVICE_FUNC inline Packet pcmp_lt_or_nan(const Packet& a, const Packet& b) {
|
||||
return a >= b ? pzero(a) : ptrue(a);
|
||||
}
|
||||
|
||||
// In the general case, use bitwise select.
|
||||
template <typename Packet, bool is_scalar = is_scalar<Packet>::value>
|
||||
struct pselect_impl {
|
||||
|
||||
@@ -373,12 +373,14 @@ class MatrixBase : public DenseBase<Derived> {
|
||||
template <int Options = 0>
|
||||
inline JacobiSVD<PlainObject, Options> jacobiSvd() const;
|
||||
template <int Options = 0>
|
||||
EIGEN_DEPRECATED inline JacobiSVD<PlainObject, Options> jacobiSvd(unsigned int computationOptions) const;
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using method's template parameter.")
|
||||
inline JacobiSVD<PlainObject, Options> jacobiSvd(unsigned int computationOptions) const;
|
||||
|
||||
template <int Options = 0>
|
||||
inline BDCSVD<PlainObject, Options> bdcSvd() const;
|
||||
template <int Options = 0>
|
||||
EIGEN_DEPRECATED inline BDCSVD<PlainObject, Options> bdcSvd(unsigned int computationOptions) const;
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using method's template parameter.")
|
||||
inline BDCSVD<PlainObject, Options> bdcSvd(unsigned int computationOptions) const;
|
||||
|
||||
/////////// Geometry module ///////////
|
||||
|
||||
@@ -391,7 +393,8 @@ class MatrixBase : public DenseBase<Derived> {
|
||||
|
||||
EIGEN_DEVICE_FUNC inline PlainObject unitOrthogonal(void) const;
|
||||
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline Matrix<Scalar, 3, 1> eulerAngles(Index a0, Index a1, Index a2) const;
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .canonicalEulerAngles() instead.")
|
||||
EIGEN_DEVICE_FUNC inline Matrix<Scalar, 3, 1> eulerAngles(Index a0, Index a1, Index a2) const;
|
||||
|
||||
EIGEN_DEVICE_FUNC inline Matrix<Scalar, 3, 1> canonicalEulerAngles(Index a0, Index a1, Index a2) const;
|
||||
|
||||
|
||||
@@ -1264,6 +1264,14 @@ struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, SkewSymmetricShape, Pr
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||
struct generic_product_impl<Lhs, Rhs, MatrixShape, HomogeneousShape, ProductTag>
|
||||
: generic_product_impl<Lhs, typename Rhs::PlainObject, MatrixShape, DenseShape, ProductTag> {};
|
||||
|
||||
template <typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
|
||||
struct generic_product_impl<Lhs, Rhs, HomogeneousShape, MatrixShape, ProductTag>
|
||||
: generic_product_impl<typename Lhs::PlainObject, Rhs, DenseShape, MatrixShape, ProductTag> {};
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
@@ -287,7 +287,7 @@ struct packet_traits<bool> : default_packet_traits {
|
||||
AlignedOnScalar = 1,
|
||||
size = 16,
|
||||
|
||||
HasCmp = 1, // note -- only pcmp_eq is defined
|
||||
HasCmp = 1,
|
||||
HasShift = 0,
|
||||
HasAbs = 0,
|
||||
HasAbs2 = 0,
|
||||
@@ -883,7 +883,14 @@ template <>
|
||||
EIGEN_STRONG_INLINE Packet4ui pandnot<Packet4ui>(const Packet4ui& a, const Packet4ui& b) {
|
||||
return _mm_andnot_si128(b, a);
|
||||
}
|
||||
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet16b pandnot<Packet16b>(const Packet16b& a, const Packet16b& b) {
|
||||
return _mm_andnot_si128(b, a);
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet16b pcmp_lt(const Packet16b& a, const Packet16b& b) {
|
||||
return _mm_andnot_si128(a, b);
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4f pcmp_le(const Packet4f& a, const Packet4f& b) {
|
||||
return _mm_cmple_ps(a, b);
|
||||
@@ -927,7 +934,11 @@ EIGEN_STRONG_INLINE Packet4i pcmp_eq(const Packet4i& a, const Packet4i& b) {
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet4i pcmp_le(const Packet4i& a, const Packet4i& b) {
|
||||
#ifdef EIGEN_VECTORIZE_SSE4_1
|
||||
return _mm_cmpeq_epi32(a, _mm_min_epi32(a, b));
|
||||
#else
|
||||
return por(pcmp_lt(a, b), pcmp_eq(a, b));
|
||||
#endif
|
||||
}
|
||||
template <>
|
||||
EIGEN_STRONG_INLINE Packet2l pcmp_lt(const Packet2l& a, const Packet2l& b) {
|
||||
|
||||
@@ -47,7 +47,7 @@ inline void manage_multi_threading(Action action, int* v);
|
||||
// Public APIs.
|
||||
|
||||
/** Must be call first when calling Eigen from multiple threads */
|
||||
EIGEN_DEPRECATED inline void initParallel() {}
|
||||
EIGEN_DEPRECATED_WITH_REASON("Initialization is no longer needed.") inline void initParallel() {}
|
||||
|
||||
/** \returns the max number of threads reserved for Eigen
|
||||
* \sa setNbThreads */
|
||||
|
||||
@@ -940,6 +940,18 @@
|
||||
#define EIGEN_DEPRECATED
|
||||
#endif
|
||||
|
||||
#ifndef EIGEN_NO_DEPRECATED_WARNING
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_DEPRECATED_WITH_REASON(message) __attribute__((deprecated(message)))
|
||||
#elif EIGEN_COMP_MSVC
|
||||
#define EIGEN_DEPRECATED_WITH_REASON(message) __declspec(deprecated(message))
|
||||
#else
|
||||
#define EIGEN_DEPRECATED_WITH_REASON(message)
|
||||
#endif
|
||||
#else
|
||||
#define EIGEN_DEPRECATED_WITH_REASON(message)
|
||||
#endif
|
||||
|
||||
#if EIGEN_COMP_GNUC
|
||||
#define EIGEN_UNUSED __attribute__((unused))
|
||||
#else
|
||||
|
||||
@@ -28,7 +28,8 @@ class Serializer;
|
||||
|
||||
// Specialization for POD types.
|
||||
template <typename T>
|
||||
class Serializer<T, typename std::enable_if_t<std::is_trivial<T>::value && std::is_standard_layout<T>::value>> {
|
||||
class Serializer<T,
|
||||
typename std::enable_if_t<std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value>> {
|
||||
public:
|
||||
/**
|
||||
* Determines the required size of the serialization buffer for a value.
|
||||
|
||||
@@ -409,7 +409,7 @@ inline void RealSchur<MatrixType>::computeShift(Index iu, Index iter, Scalar& ex
|
||||
shiftInfo.coeffRef(2) = m_matT.coeff(iu, iu - 1) * m_matT.coeff(iu - 1, iu);
|
||||
|
||||
// Alternate exceptional shifting strategy every 16 iterations.
|
||||
if (iter % 16 == 0) {
|
||||
if (iter > 0 && iter % 16 == 0) {
|
||||
// Wilkinson's original ad hoc shift
|
||||
if (iter % 32 != 0) {
|
||||
exshift += shiftInfo.coeff(0);
|
||||
|
||||
@@ -133,8 +133,8 @@ EIGEN_DEVICE_FUNC inline Matrix<typename MatrixBase<Derived>::Scalar, 3, 1> Matr
|
||||
* \sa class AngleAxis
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline Matrix<typename MatrixBase<Derived>::Scalar, 3, 1>
|
||||
MatrixBase<Derived>::eulerAngles(Index a0, Index a1, Index a2) const {
|
||||
EIGEN_DEVICE_FUNC inline Matrix<typename MatrixBase<Derived>::Scalar, 3, 1> MatrixBase<Derived>::eulerAngles(
|
||||
Index a0, Index a1, Index a2) const {
|
||||
/* Implemented from Graphics Gems IV */
|
||||
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(Derived, 3, 3)
|
||||
|
||||
|
||||
@@ -80,14 +80,12 @@ class Homogeneous : public MatrixBase<Homogeneous<MatrixType, Direction_> >, int
|
||||
|
||||
template <typename Rhs>
|
||||
EIGEN_DEVICE_FUNC inline const Product<Homogeneous, Rhs> operator*(const MatrixBase<Rhs>& rhs) const {
|
||||
eigen_assert(int(Direction) == Horizontal);
|
||||
return Product<Homogeneous, Rhs>(*this, rhs.derived());
|
||||
}
|
||||
|
||||
template <typename Lhs>
|
||||
friend EIGEN_DEVICE_FUNC inline const Product<Lhs, Homogeneous> operator*(const MatrixBase<Lhs>& lhs,
|
||||
const Homogeneous& rhs) {
|
||||
eigen_assert(int(Direction) == Vertical);
|
||||
return Product<Lhs, Homogeneous>(lhs.derived(), rhs);
|
||||
}
|
||||
|
||||
|
||||
@@ -155,7 +155,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
|
||||
* \deprecated Will be removed in the next major Eigen version. Options should
|
||||
* be specified in the \a Options template parameter.
|
||||
*/
|
||||
EIGEN_DEPRECATED BDCSVD(Index rows, Index cols, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
|
||||
BDCSVD(Index rows, Index cols, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) {
|
||||
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
|
||||
allocate(rows, cols, computationOptions);
|
||||
}
|
||||
@@ -183,8 +184,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
|
||||
* be specified in the \a Options template parameter.
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED BDCSVD(const MatrixBase<Derived>& matrix, unsigned int computationOptions)
|
||||
: m_algoswap(16), m_numIters(0) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
|
||||
BDCSVD(const MatrixBase<Derived>& matrix, unsigned int computationOptions) : m_algoswap(16), m_numIters(0) {
|
||||
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
|
||||
compute_impl(matrix, computationOptions);
|
||||
}
|
||||
@@ -211,7 +212,8 @@ class BDCSVD : public SVDBase<BDCSVD<MatrixType_, Options_> > {
|
||||
* be specified in the \a Options template parameter.
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED BDCSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
|
||||
BDCSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
|
||||
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, matrix.rows(), matrix.cols());
|
||||
return compute_impl(matrix, computationOptions);
|
||||
}
|
||||
|
||||
@@ -555,7 +555,8 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
|
||||
* \deprecated Will be removed in the next major Eigen version. Options should
|
||||
* be specified in the \a Options template parameter.
|
||||
*/
|
||||
EIGEN_DEPRECATED JacobiSVD(Index rows, Index cols, unsigned int computationOptions) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
|
||||
JacobiSVD(Index rows, Index cols, unsigned int computationOptions) {
|
||||
internal::check_svd_options_assertions<MatrixType, Options>(computationOptions, rows, cols);
|
||||
allocate(rows, cols, computationOptions);
|
||||
}
|
||||
@@ -610,7 +611,8 @@ class JacobiSVD : public SVDBase<JacobiSVD<MatrixType_, Options_> > {
|
||||
* be specified in the \a Options template parameter.
|
||||
*/
|
||||
template <typename Derived>
|
||||
EIGEN_DEPRECATED JacobiSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Options should be specified using the class template parameter.")
|
||||
JacobiSVD& compute(const MatrixBase<Derived>& matrix, unsigned int computationOptions) {
|
||||
internal::check_svd_options_assertions<MatrixBase<Derived>, Options>(m_computationOptions, matrix.rows(),
|
||||
matrix.cols());
|
||||
return compute_impl(matrix, computationOptions);
|
||||
|
||||
@@ -354,40 +354,40 @@ class SparseVector : public SparseCompressedBase<SparseVector<Scalar_, Options_,
|
||||
|
||||
public:
|
||||
/** \internal \deprecated use setZero() and reserve() */
|
||||
EIGEN_DEPRECATED void startFill(Index reserve) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .setZero() and .reserve() instead.") void startFill(Index reserve) {
|
||||
setZero();
|
||||
m_data.reserve(reserve);
|
||||
}
|
||||
|
||||
/** \internal \deprecated use insertBack(Index,Index) */
|
||||
EIGEN_DEPRECATED Scalar& fill(Index r, Index c) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .insertBack() instead.") Scalar& fill(Index r, Index c) {
|
||||
eigen_assert(r == 0 || c == 0);
|
||||
return fill(IsColVector ? r : c);
|
||||
}
|
||||
|
||||
/** \internal \deprecated use insertBack(Index) */
|
||||
EIGEN_DEPRECATED Scalar& fill(Index i) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .insertBack() instead.") Scalar& fill(Index i) {
|
||||
m_data.append(0, i);
|
||||
return m_data.value(m_data.size() - 1);
|
||||
}
|
||||
|
||||
/** \internal \deprecated use insert(Index,Index) */
|
||||
EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c) {
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .insert() instead.") Scalar& fillrand(Index r, Index c) {
|
||||
eigen_assert(r == 0 || c == 0);
|
||||
return fillrand(IsColVector ? r : c);
|
||||
}
|
||||
|
||||
/** \internal \deprecated use insert(Index) */
|
||||
EIGEN_DEPRECATED Scalar& fillrand(Index i) { return insert(i); }
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .insert() instead.") Scalar& fillrand(Index i) { return insert(i); }
|
||||
|
||||
/** \internal \deprecated use finalize() */
|
||||
EIGEN_DEPRECATED void endFill() {}
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .finalize() instead.") void endFill() {}
|
||||
|
||||
// These two functions were here in the 3.1 release, so let's keep them in case some code rely on them.
|
||||
/** \internal \deprecated use data() */
|
||||
EIGEN_DEPRECATED Storage& _data() { return m_data; }
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .data() instead.") Storage& _data() { return m_data; }
|
||||
/** \internal \deprecated use data() */
|
||||
EIGEN_DEPRECATED const Storage& _data() const { return m_data; }
|
||||
EIGEN_DEPRECATED_WITH_REASON("Use .data() instead.") const Storage& _data() const { return m_data; }
|
||||
|
||||
#ifdef EIGEN_SPARSEVECTOR_PLUGIN
|
||||
#include EIGEN_SPARSEVECTOR_PLUGIN
|
||||
|
||||
Reference in New Issue
Block a user