Import Geant4 11.0.2 source tree
This commit is contained in:
@@ -16,6 +16,10 @@ commit in the repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
March 5 2022 M.Asai (geommng-V10-07-08)
|
||||
- G4SolidStore, G4LogicalVolumeStore, G4PhysicalVolumeStore:
|
||||
extend getter methods to optionally return the last-found object.
|
||||
|
||||
September 28, 2021 G.Cosmo (geommng-V10-07-07)
|
||||
- Use G4Allocator to dynamically allocate nodes and proxies for the
|
||||
voxels optimisation structure. Should help reducing memory fragmentation.
|
||||
|
||||
@@ -67,8 +67,9 @@ class G4LogicalVolumeStore : public std::vector<G4LogicalVolume*>
|
||||
static void Clean();
|
||||
// Delete all volumes from the store.
|
||||
|
||||
G4LogicalVolume* GetVolume(const G4String& name, G4bool verbose=true) const;
|
||||
// Return the pointer of the first volume in the collection having
|
||||
G4LogicalVolume* GetVolume(const G4String& name, G4bool verbose=true,
|
||||
G4bool reverseSearch=false) const;
|
||||
// Return the pointer of the first or last volume in the collection having
|
||||
// that name. Uses the internal map for fast search and warns if
|
||||
// a volume in the collection is not unique or not found.
|
||||
|
||||
|
||||
@@ -68,8 +68,9 @@ class G4PhysicalVolumeStore : public std::vector<G4VPhysicalVolume*>
|
||||
// are automatically notified and have their daughters de-registered.
|
||||
|
||||
G4VPhysicalVolume* GetVolume(const G4String& name,
|
||||
G4bool verbose = true) const;
|
||||
// Return the pointer of the first volume in the collection having
|
||||
G4bool verbose = true,
|
||||
G4bool reverseSearch = false) const;
|
||||
// Return the pointer of the first or last volume in the collection having
|
||||
// that name. Uses the internal map for fast search and warns if
|
||||
// a volume in the collection is not unique or not found.
|
||||
|
||||
|
||||
@@ -66,8 +66,9 @@ class G4SolidStore : public std::vector<G4VSolid*>
|
||||
static void Clean();
|
||||
// Delete all solids from the store.
|
||||
|
||||
G4VSolid* GetSolid(const G4String& name, G4bool verbose = true) const;
|
||||
// Return the pointer of the first solid in the collection having
|
||||
G4VSolid* GetSolid(const G4String& name, G4bool verbose = true,
|
||||
G4bool reverseSearch = false) const;
|
||||
// Return the pointer of the first or last solid in the collection having
|
||||
// that name. Uses the internal map for fast search and warns if
|
||||
// a solid in the collection is not unique or not found.
|
||||
|
||||
|
||||
@@ -216,11 +216,12 @@ void G4LogicalVolumeStore::DeRegister(G4LogicalVolume* pVolume)
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Retrieve the first volume pointer in the container having that name
|
||||
// Retrieve the first or last volume pointer in the container having that name
|
||||
// ***************************************************************************
|
||||
//
|
||||
G4LogicalVolume*
|
||||
G4LogicalVolumeStore::GetVolume(const G4String& name, G4bool verbose) const
|
||||
G4LogicalVolumeStore::GetVolume(const G4String& name, G4bool verbose,
|
||||
G4bool reverseSearch) const
|
||||
{
|
||||
G4LogicalVolumeStore* store = GetInstance();
|
||||
if (!store->mvalid) { store->UpdateMap(); }
|
||||
@@ -236,7 +237,14 @@ G4LogicalVolumeStore::GetVolume(const G4String& name, G4bool verbose) const
|
||||
G4Exception("G4LogicalVolumeStore::GetVolume()",
|
||||
"GeomMgt1001", JustWarning, message);
|
||||
}
|
||||
return pos->second[0];
|
||||
if(reverseSearch)
|
||||
{
|
||||
return pos->second[pos->second.size()-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return pos->second[0];
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
{
|
||||
|
||||
@@ -220,11 +220,12 @@ void G4PhysicalVolumeStore::DeRegister(G4VPhysicalVolume* pVolume)
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Retrieve the first volume pointer in the container having that name
|
||||
// Retrieve the first or last volume pointer in the container having that name
|
||||
// ***************************************************************************
|
||||
//
|
||||
G4VPhysicalVolume*
|
||||
G4PhysicalVolumeStore::GetVolume(const G4String& name, G4bool verbose) const
|
||||
G4PhysicalVolumeStore::GetVolume(const G4String& name, G4bool verbose,
|
||||
G4bool reverseSearch) const
|
||||
{
|
||||
G4PhysicalVolumeStore* store = GetInstance();
|
||||
if (!store->mvalid) { store->UpdateMap(); }
|
||||
@@ -240,7 +241,14 @@ G4PhysicalVolumeStore::GetVolume(const G4String& name, G4bool verbose) const
|
||||
G4Exception("G4PhysicalVolumeStore::GetVolume()",
|
||||
"GeomMgt1001", JustWarning, message);
|
||||
}
|
||||
return pos->second[0];
|
||||
if(reverseSearch)
|
||||
{
|
||||
return pos->second[pos->second.size()-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return pos->second[0];
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
{
|
||||
|
||||
@@ -215,10 +215,11 @@ void G4SolidStore::DeRegister(G4VSolid* pSolid)
|
||||
}
|
||||
|
||||
// ***************************************************************************
|
||||
// Retrieve the first solid pointer in the container having that name
|
||||
// Retrieve the first or last solid pointer in the container having that name
|
||||
// ***************************************************************************
|
||||
//
|
||||
G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose) const
|
||||
G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose,
|
||||
G4bool reverseSearch) const
|
||||
{
|
||||
G4SolidStore* store = GetInstance();
|
||||
if (!store->mvalid) { store->UpdateMap(); }
|
||||
@@ -234,7 +235,14 @@ G4VSolid* G4SolidStore::GetSolid(const G4String& name, G4bool verbose) const
|
||||
G4Exception("G4SolidStore::GetSolid()",
|
||||
"GeomMgt1001", JustWarning, message);
|
||||
}
|
||||
return pos->second[0];
|
||||
if(reverseSearch)
|
||||
{
|
||||
return pos->second[pos->second.size()-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
return pos->second[0];
|
||||
}
|
||||
}
|
||||
if (verbose)
|
||||
{
|
||||
|
||||
@@ -16,6 +16,17 @@ committal in the CVS repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
March 3, 2022 - P.Arce (geomnav-V10-07-06)
|
||||
-------------
|
||||
- G4RegularNavigation: reset the zero step counter when a non-zero step was
|
||||
performed, to avoid aborted events. Correct tabulation.
|
||||
Fixes as proposed in [GitHub PR #38](https://github.com/Geant4/geant4/pull/38)
|
||||
|
||||
January 1, 2022 - G.Cosmo
|
||||
-------------------------
|
||||
- G4VIntersectionLocator: fixed compilation warning on Intel-icx compiler
|
||||
for unused data.
|
||||
|
||||
September 25, 2021 - P.Arce (geomnav-V10-07-05)
|
||||
----------------------------
|
||||
- Reduce warning messages in GetReplicaNo: only when difference is > kCarTolerance
|
||||
|
||||
@@ -205,16 +205,16 @@ G4double G4RegularNavigation::ComputeStepSkippingEqualMaterials(
|
||||
.InverseTransformPoint(localPoint);
|
||||
std::ostringstream message;
|
||||
message << "G4RegularNavigation::ComputeStepSkippingEqualMaterials()"
|
||||
<< "Stuck Track: potential geometry or navigation problem."
|
||||
<< G4endl
|
||||
<< " Track stuck, moving for more than "
|
||||
<< ii << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint << G4endl
|
||||
<< " local direction: " << localDirection << G4endl;
|
||||
<< "Stuck Track: potential geometry or navigation problem."
|
||||
<< G4endl
|
||||
<< " Track stuck, moving for more than "
|
||||
<< ii << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint << G4endl
|
||||
<< " local direction: " << localDirection << G4endl;
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1001",
|
||||
EventMustBeAborted,
|
||||
message);
|
||||
"GeomRegNav1001",
|
||||
EventMustBeAborted,
|
||||
message);
|
||||
}
|
||||
newStep = voxelBox->DistanceToOut( localPoint, localDirection );
|
||||
fLastStepWasZero = (newStep<fMinStep);
|
||||
@@ -226,63 +226,67 @@ G4double G4RegularNavigation::ComputeStepSkippingEqualMaterials(
|
||||
{
|
||||
G4ThreeVector pGlobalpoint = history.GetTransform(ide)
|
||||
.InverseTransformPoint(localPoint);
|
||||
std::ostringstream message;
|
||||
message.precision(16);
|
||||
message << "G4RegularNavigation::ComputeStepSkippingEqualMaterials(): another 'zero' step, # "
|
||||
<< fNumberZeroSteps
|
||||
<< ", at " << pGlobalpoint
|
||||
<< ", nav-comp-step calls # " << ii
|
||||
<< ", Step= " << newStep;
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1002", JustWarning, message,
|
||||
"Potential overlap in geometry!");
|
||||
std::ostringstream message;
|
||||
message.precision(16);
|
||||
message << "G4RegularNavigation::ComputeStepSkippingEqualMaterials(): another 'zero' step, # "
|
||||
<< fNumberZeroSteps
|
||||
<< ", at " << pGlobalpoint
|
||||
<< ", nav-comp-step calls # " << ii
|
||||
<< ", Step= " << newStep;
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1002", JustWarning, message,
|
||||
"Potential overlap in geometry!");
|
||||
}
|
||||
#endif
|
||||
if( fNumberZeroSteps > fActionThreshold_NoZeroSteps-1 )
|
||||
{
|
||||
// Act to recover this stuck track. Pushing it along direction
|
||||
//
|
||||
newStep = std::min(101*kCarTolerance*std::pow(10,fNumberZeroSteps-2),0.1);
|
||||
// Act to recover this stuck track. Pushing it along direction
|
||||
//
|
||||
newStep = std::min(101*kCarTolerance*std::pow(10,fNumberZeroSteps-2),0.1);
|
||||
#ifdef G4DEBUG_NAVIGATION
|
||||
G4ThreeVector pGlobalpoint = history.GetTransform(ide)
|
||||
.InverseTransformPoint(localPoint);
|
||||
std::ostringstream message;
|
||||
message.precision(16);
|
||||
message << "Track stuck or not moving." << G4endl
|
||||
<< " Track stuck, not moving for "
|
||||
<< fNumberZeroSteps << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint
|
||||
<< " (local point " << localPoint << ")" << G4endl
|
||||
<< " local direction: " << localDirection
|
||||
<< " Potential geometry or navigation problem !"
|
||||
<< G4endl
|
||||
<< " Trying pushing it of " << newStep << " mm ...";
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1003", JustWarning, message,
|
||||
"Potential overlap in geometry!");
|
||||
std::ostringstream message;
|
||||
message.precision(16);
|
||||
message << "Track stuck or not moving." << G4endl
|
||||
<< " Track stuck, not moving for "
|
||||
<< fNumberZeroSteps << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint
|
||||
<< " (local point " << localPoint << ")" << G4endl
|
||||
<< " local direction: " << localDirection
|
||||
<< " Potential geometry or navigation problem !"
|
||||
<< G4endl
|
||||
<< " Trying pushing it of " << newStep << " mm ...";
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1003", JustWarning, message,
|
||||
"Potential overlap in geometry!");
|
||||
#endif
|
||||
}
|
||||
if( fNumberZeroSteps > fAbandonThreshold_NoZeroSteps-1 )
|
||||
{
|
||||
// Must kill this stuck track
|
||||
//
|
||||
G4ThreeVector pGlobalpoint = history.GetTransform(ide)
|
||||
.InverseTransformPoint(localPoint);
|
||||
std::ostringstream message;
|
||||
message << "G4RegularNavigation::ComputeStepSkippingEqualMaterials()"
|
||||
<< "Stuck Track: potential geometry or navigation problem."
|
||||
<< G4endl
|
||||
<< " Track stuck, not moving for "
|
||||
<< fNumberZeroSteps << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint << G4endl
|
||||
<< " local direction: " << localDirection << G4endl;
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1004",
|
||||
EventMustBeAborted,
|
||||
message);
|
||||
// Must kill this stuck track
|
||||
//
|
||||
G4ThreeVector pGlobalpoint = history.GetTransform(ide)
|
||||
.InverseTransformPoint(localPoint);
|
||||
std::ostringstream message;
|
||||
message << "G4RegularNavigation::ComputeStepSkippingEqualMaterials()"
|
||||
<< "Stuck Track: potential geometry or navigation problem."
|
||||
<< G4endl
|
||||
<< " Track stuck, not moving for "
|
||||
<< fNumberZeroSteps << " steps" << G4endl
|
||||
<< "- at point " << pGlobalpoint << G4endl
|
||||
<< " local direction: " << localDirection << G4endl;
|
||||
G4Exception("G4RegularNavigation::ComputeStepSkippingEqualMaterials()",
|
||||
"GeomRegNav1004",
|
||||
EventMustBeAborted,
|
||||
message);
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// reset the zero step counter when a non-zero step was performed
|
||||
fNumberZeroSteps = 0;
|
||||
}
|
||||
if( (bFirstStep) && (newStep < currentProposedStepLength) )
|
||||
{
|
||||
exiting = true;
|
||||
|
||||
@@ -296,17 +296,19 @@ ReEstimateEndpoint( const G4FieldTrack& CurrentStateA,
|
||||
G4Exception("G4VIntersectionLocator::ReEstimateEndpoint()",
|
||||
"GeomNav1002", JustWarning, message);
|
||||
}
|
||||
/*
|
||||
#else
|
||||
// Statistics on the RMS value of the corrections
|
||||
|
||||
static G4ThreadLocal G4int noCorrections = 0;
|
||||
static G4ThreadLocal G4double sumCorrectionsSq = 0;
|
||||
static G4ThreadLocal G4int noCorrections = 0;
|
||||
++noCorrections;
|
||||
if( goodAdvance )
|
||||
{
|
||||
static G4ThreadLocal G4double sumCorrectionsSq;
|
||||
sumCorrectionsSq += (EstimatedEndStateB.GetPosition() -
|
||||
newEndPoint.GetPosition()).mag2();
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
return retEndPoint;
|
||||
|
||||
@@ -19,6 +19,16 @@ committal in the CVS repository !
|
||||
* Reverse chronological order (last date on top), please *
|
||||
----------------------------------------------------------
|
||||
|
||||
May 4, 2022, G.Cosmo (geom-bool-V10-07-05)
|
||||
- Minor cleanup in G4UnionSolid constructors.
|
||||
|
||||
April 29, 2022, G.Cosmo
|
||||
- G4UnionSolid: added missing data initialisation in copy-ctr and operator=().
|
||||
|
||||
April 5, 2022, G.Cosmo
|
||||
- G4UnionSolid: add surface tolerance in Inside(p) for check on Z.
|
||||
Minor optimisation in caching half-tolerance.
|
||||
|
||||
January 10, 2022, G.Cosmo geom-bool-V10-07-04
|
||||
- Added alternative signature for AddNode() taking a pointer to solid.
|
||||
Added 'const' qualification to transformation passed as argument.
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
class G4UnionSolid : public G4BooleanSolid
|
||||
{
|
||||
public: // with description
|
||||
public:
|
||||
|
||||
G4UnionSolid( const G4String& pName,
|
||||
G4VSolid* pSolidA ,
|
||||
@@ -67,8 +67,6 @@ class G4UnionSolid : public G4BooleanSolid
|
||||
|
||||
G4VSolid* Clone() const;
|
||||
|
||||
public: // without description
|
||||
|
||||
G4UnionSolid(__void__&);
|
||||
// Fake default constructor for usage restricted to direct object
|
||||
// persistency for clients requiring preallocation of memory for
|
||||
@@ -114,7 +112,10 @@ class G4UnionSolid : public G4BooleanSolid
|
||||
|
||||
private:
|
||||
|
||||
void Init();
|
||||
|
||||
G4ThreeVector fPMin, fPMax; // bounding box extended by half-tolerance
|
||||
G4double halfCarTolerance;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -55,11 +55,7 @@ G4UnionSolid:: G4UnionSolid( const G4String& pName,
|
||||
G4VSolid* pSolidB )
|
||||
: G4BooleanSolid(pName,pSolidA,pSolidB)
|
||||
{
|
||||
G4ThreeVector pdelta(0.5*kCarTolerance,0.5*kCarTolerance,0.5*kCarTolerance);
|
||||
G4ThreeVector pmin, pmax;
|
||||
BoundingLimits(pmin, pmax);
|
||||
fPMin = pmin - pdelta;
|
||||
fPMax = pmax + pdelta;
|
||||
Init();
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
@@ -74,11 +70,7 @@ G4UnionSolid::G4UnionSolid( const G4String& pName,
|
||||
: G4BooleanSolid(pName,pSolidA,pSolidB,rotMatrix,transVector)
|
||||
|
||||
{
|
||||
G4ThreeVector pdelta(0.5*kCarTolerance,0.5*kCarTolerance,0.5*kCarTolerance);
|
||||
G4ThreeVector pmin, pmax;
|
||||
BoundingLimits(pmin, pmax);
|
||||
fPMin = pmin - pdelta;
|
||||
fPMax = pmax + pdelta;
|
||||
Init();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
@@ -91,11 +83,7 @@ G4UnionSolid::G4UnionSolid( const G4String& pName,
|
||||
const G4Transform3D& transform )
|
||||
: G4BooleanSolid(pName,pSolidA,pSolidB,transform)
|
||||
{
|
||||
G4ThreeVector pdelta(0.5*kCarTolerance,0.5*kCarTolerance,0.5*kCarTolerance);
|
||||
G4ThreeVector pmin, pmax;
|
||||
BoundingLimits(pmin, pmax);
|
||||
fPMin = pmin - pdelta;
|
||||
fPMax = pmax + pdelta;
|
||||
Init();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
@@ -125,6 +113,7 @@ G4UnionSolid::G4UnionSolid(const G4UnionSolid& rhs)
|
||||
{
|
||||
fPMin = rhs.fPMin;
|
||||
fPMax = rhs.fPMax;
|
||||
halfCarTolerance=0.5*kCarTolerance;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
@@ -143,9 +132,25 @@ G4UnionSolid& G4UnionSolid::operator = (const G4UnionSolid& rhs)
|
||||
|
||||
fPMin = rhs.fPMin;
|
||||
fPMax = rhs.fPMax;
|
||||
halfCarTolerance = rhs.halfCarTolerance;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Initialisation
|
||||
|
||||
void G4UnionSolid::Init()
|
||||
{
|
||||
G4ThreeVector pdelta(kCarTolerance,kCarTolerance,kCarTolerance);
|
||||
G4ThreeVector pmin, pmax;
|
||||
BoundingLimits(pmin, pmax);
|
||||
fPMin = pmin - pdelta;
|
||||
fPMax = pmax + pdelta;
|
||||
halfCarTolerance=0.5*kCarTolerance;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Get bounding box
|
||||
@@ -221,7 +226,7 @@ G4UnionSolid::CalculateExtent( const EAxis pAxis,
|
||||
|
||||
EInside G4UnionSolid::Inside( const G4ThreeVector& p ) const
|
||||
{
|
||||
if (std::max(p.z()-fPMax.z(),fPMin.z()-p.z()) > 0) return kOutside;
|
||||
if (std::max(p.z()-fPMax.z(), fPMin.z()-p.z()) > 0) { return kOutside; }
|
||||
|
||||
EInside positionA = fPtrSolidA->Inside(p);
|
||||
if (positionA == kInside) { return positionA; } // inside A
|
||||
@@ -286,7 +291,7 @@ G4UnionSolid::SurfaceNormal( const G4ThreeVector& p ) const
|
||||
|
||||
G4double
|
||||
G4UnionSolid::DistanceToIn( const G4ThreeVector& p,
|
||||
const G4ThreeVector& v ) const
|
||||
const G4ThreeVector& v ) const
|
||||
{
|
||||
#ifdef G4BOOLDEBUG
|
||||
if( Inside(p) == kInside )
|
||||
@@ -305,7 +310,7 @@ G4UnionSolid::DistanceToIn( const G4ThreeVector& p,
|
||||
#endif
|
||||
|
||||
return std::min(fPtrSolidA->DistanceToIn(p,v),
|
||||
fPtrSolidB->DistanceToIn(p,v) ) ;
|
||||
fPtrSolidB->DistanceToIn(p,v) ) ;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
@@ -394,7 +399,7 @@ G4UnionSolid::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
while( (fPtrSolidA->Inside(p+dist*v) != kOutside)
|
||||
&& (disTmp > 0.5*kCarTolerance) );
|
||||
&& (disTmp > halfCarTolerance) );
|
||||
}
|
||||
else // if( positionB != kOutside )
|
||||
{
|
||||
@@ -412,7 +417,7 @@ G4UnionSolid::DistanceToOut( const G4ThreeVector& p,
|
||||
}
|
||||
}
|
||||
while( (fPtrSolidB->Inside(p+dist*v) != kOutside)
|
||||
&& (disTmp > 0.5*kCarTolerance) );
|
||||
&& (disTmp > halfCarTolerance) );
|
||||
}
|
||||
}
|
||||
if( calcNorm )
|
||||
@@ -457,7 +462,7 @@ G4UnionSolid::DistanceToOut( const G4ThreeVector& p ) const
|
||||
(positionA == kSurface && positionB == kInside ) )
|
||||
{
|
||||
distout= std::max(fPtrSolidA->DistanceToOut(p),
|
||||
fPtrSolidB->DistanceToOut(p) ) ;
|
||||
fPtrSolidB->DistanceToOut(p) ) ;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user