Any
MoveToDecade
This commit is contained in:
@ -1,10 +1,11 @@
|
||||
---
|
||||
created: "2023-07-21T18:26:38.899Z"
|
||||
updated: "2023-07-21T18:26:38.900Z"
|
||||
created: 2023-07-21T18:26:38.899Z
|
||||
updated: 2023-07-21T18:26:38.900Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
type: "kanbn"
|
||||
completed: "2023-07-21T04:34:47.650Z"
|
||||
type: kanbn
|
||||
completed: 2023-07-21T04:34:47.650Z
|
||||
column: Done
|
||||
---
|
||||
|
||||
# Family Tree as Markdown Files
|
15
Shared/.kanbn/archive/run-scan-originals.md
Normal file
15
Shared/.kanbn/archive/run-scan-originals.md
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
created: 2023-07-21T18:26:38.916Z
|
||||
updated: 2023-07-21T18:26:38.917Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
status: 4-Done
|
||||
type: kanbn
|
||||
column: Done
|
||||
---
|
||||
|
||||
# Run Scan Originals
|
||||
|
||||
## Sub-tasks
|
||||
|
||||
- [x] run-scan-originals
|
@ -32,20 +32,21 @@ taskTemplate: '^+^_${overdue ? ''^R'' : ''''}${name}^: ${relations ? (''\n^-^/^g
|
||||
- [nef-support](tasks/nef-support.md)
|
||||
- [set-date-taken-when-missing](tasks/set-date-taken-when-missing.md)
|
||||
- [set-focus-person-based-on-number-of-matched](tasks/set-focus-person-based-on-number-of-matched.md)
|
||||
- [move-images-in-distance-directories-to-decade-match-minimum-decade-match-maximum-decade-match-none](tasks/move-images-in-distance-directories-to-decade-match-minimum-decade-match-maximum-decade-match-none.md)
|
||||
|
||||
## In Progress
|
||||
|
||||
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
||||
- [look-for-family-from-jlink-in-x-mapped](tasks/look-for-family-from-jlink-in-x-mapped.md)
|
||||
- [review-what-system-does-when-duplicate-matched-with-x-and-non-x](tasks/review-what-system-does-when-duplicate-matched-with-x-and-non-x.md)
|
||||
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
|
||||
|
||||
## Done
|
||||
|
||||
- [eof-error](tasks/eof-error.md)
|
||||
- [run-scan-originals](tasks/run-scan-originals.md)
|
||||
- [shrink-percent](tasks/shrink-percent.md)
|
||||
- [merge-kristy-files](tasks/merge-kristy-files.md)
|
||||
- [family-tree-as-markdown-files](tasks/family-tree-as-markdown-files.md)
|
||||
- [move-over-2023-california-pictures](tasks/move-over-2023-california-pictures.md)
|
||||
- [verify-person-key-collection-fixed-x-issue](tasks/verify-person-key-collection-fixed-x-issue.md)
|
||||
- [genealogical-data-communication-as-golden](tasks/genealogical-data-communication-as-golden.md)
|
||||
- [review-what-system-does-when-duplicate-matched-with-x-and-non-x](tasks/review-what-system-does-when-duplicate-matched-with-x-and-non-x.md)
|
||||
- [add-facebook-and-linked-in-txt-to-ged](tasks/add-facebook-and-linked-in-txt-to-ged.md)
|
||||
- [setup-photo-prism-again-in-wsl-docker](tasks/setup-photo-prism-again-in-wsl-docker.md)
|
||||
- [rename-files-to-padded-number-string](tasks/rename-files-to-padded-number-string.md)
|
||||
|
11
Shared/.kanbn/tasks/add-facebook-and-linked-in-txt-to-ged.md
Normal file
11
Shared/.kanbn/tasks/add-facebook-and-linked-in-txt-to-ged.md
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
created: 2023-08-05T17:50:34.233Z
|
||||
updated: 2023-08-05T23:12:26.511Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
started: 2023-08-05T17:50:34.233Z
|
||||
completed: 2023-08-05T23:12:26.511Z
|
||||
---
|
||||
|
||||
# Add Facebook and LinkedIn *.txt to *.ged
|
@ -1,6 +1,6 @@
|
||||
---
|
||||
created: 2023-07-31T19:08:57.684Z
|
||||
updated: 2023-08-01T06:13:54.468Z
|
||||
updated: 2023-08-06T03:40:58.576Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
|
@ -1,12 +1,11 @@
|
||||
---
|
||||
created: 2023-07-21T18:26:38.910Z
|
||||
updated: 2023-08-05T08:33:35.448Z
|
||||
updated: 2023-08-05T17:43:51.430Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
status: 2-Todo
|
||||
type: kanbn
|
||||
started: 2023-07-08T21:44:14.665Z
|
||||
completed: 2023-08-05T08:33:35.448Z
|
||||
progress: 0.5
|
||||
tags: []
|
||||
started: 2023-07-06T00:00:00.000Z
|
||||
completed: 2023-08-03T00:00:00.000Z
|
||||
---
|
||||
|
||||
# Merge Kristy Files
|
||||
@ -26,3 +25,4 @@ return new(result, (from l in results orderby l.FileHolder.DirectoryName?.EndsWi
|
||||
- [x] Set created date
|
||||
- [x] Verify
|
||||
- [x] Move to production ...
|
||||
- [ ] Cleanup D:/7-Question/- Scans.*
|
||||
|
@ -0,0 +1,9 @@
|
||||
---
|
||||
created: 2023-08-06T00:25:42.224Z
|
||||
updated: 2023-08-06T00:25:42.220Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
---
|
||||
|
||||
# Move images in Distance directories to {Decade}MatchMinimum {Decade}MatchMaximum {Decade}MatchNone
|
@ -1,10 +1,11 @@
|
||||
---
|
||||
created: 2023-08-05T08:33:59.693Z
|
||||
updated: 2023-08-05T08:33:59.689Z
|
||||
updated: 2023-08-05T17:38:11.824Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
started: 2023-08-05T08:33:59.693Z
|
||||
completed: 2023-08-05T17:38:11.824Z
|
||||
---
|
||||
|
||||
# Move over 2023 California Pictures
|
||||
|
@ -9,13 +9,14 @@ type: "kanbn"
|
||||
|
||||
# Rename Files to Padded Number String
|
||||
|
||||
- [?] ~~Go Back to Index for Sort~~
|
||||
- [?] ~~New file for index to to id~~
|
||||
- [?] ~~Count backwards~~
|
||||
- [?] ~~Maybe skip some for scan images~~
|
||||
- [?] [Set Date Taken When Missing](set-date-taken-when-missing.md)
|
||||
|
||||
## Sub-tasks
|
||||
|
||||
- [ ] ~~Go Back to Index for Sort~~
|
||||
- [ ] ~~New file for index to to id~~
|
||||
- [ ] ~~Count backwards~~
|
||||
- [ ] ~~Maybe skip some for scan images~~
|
||||
- [Set Date Taken When Missing](set-date-taken-when-missing.md)
|
||||
- [x] Rename production with padding names starting with one directory
|
||||
- [x] Need equivalent to NameWithoutExtensionIsIdFormat method
|
||||
- [x] Verify nothing broke (run from resize original now ... ?)
|
||||
|
@ -1,10 +1,13 @@
|
||||
---
|
||||
created: 2023-08-05T08:33:05.117Z
|
||||
updated: 2023-08-05T08:33:22.874Z
|
||||
updated: 2023-08-06T05:44:59.047Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
started: 2023-08-05T00:00:00.000Z
|
||||
started: 2023-08-04T00:00:00.000Z
|
||||
completed: 2023-08-06T05:44:59.047Z
|
||||
---
|
||||
|
||||
# Review what system does when duplicate matched with X] and non X]
|
||||
|
||||
AlternateDirectoryDateTime helps but not full proof
|
||||
|
@ -1,14 +0,0 @@
|
||||
---
|
||||
created: "2023-07-21T18:26:38.916Z"
|
||||
updated: "2023-07-21T18:26:38.917Z"
|
||||
assigned: ""
|
||||
progress: 0
|
||||
status: "4-Done"
|
||||
type: "kanbn"
|
||||
---
|
||||
|
||||
# Run Scan Originals
|
||||
|
||||
## Sub-tasks
|
||||
|
||||
- [x] run-scan-originals
|
@ -0,0 +1,11 @@
|
||||
---
|
||||
created: 2023-08-06T01:04:57.884Z
|
||||
updated: 2023-08-06T06:55:09.617Z
|
||||
assigned: ""
|
||||
progress: 0
|
||||
tags: []
|
||||
started: 2023-08-06T01:04:57.884Z
|
||||
completed: 2023-08-06T06:55:09.617Z
|
||||
---
|
||||
|
||||
# Verify personKeyCollection fixed X] issue
|
@ -1,3 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@ -49,11 +50,11 @@ public class Mapping : Properties.IMapping
|
||||
_SegmentC = !saveIndividually ? null : sortingContainer.Sorting.DistancePermyriad.ToString();
|
||||
}
|
||||
|
||||
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
|
||||
public void UpdateMappingFromPerson(ReadOnlyCollection<string> locationContainersFiles, int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
|
||||
{
|
||||
_SortingContainer = null;
|
||||
_By = Stateless.IMapLogic.Mapping;
|
||||
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
|
||||
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
|
||||
}
|
||||
|
||||
public void UpdateMappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB, string segmentC, SortingContainer sortingContainer)
|
||||
@ -61,7 +62,8 @@ public class Mapping : Properties.IMapping
|
||||
_SegmentC = segmentC;
|
||||
_By = Stateless.IMapLogic.Sorting;
|
||||
_SortingContainer = sortingContainer;
|
||||
_MappingFromPerson = new(approximateYears, displayDirectoryName, personBirthday, segmentB);
|
||||
ReadOnlyCollection<string> locationContainersFiles = new(Array.Empty<string>());
|
||||
_MappingFromPerson = new(approximateYears, displayDirectoryName, locationContainersFiles, personBirthday, segmentB);
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
@ -8,14 +9,16 @@ public class MappingFromPerson : Properties.IMappingFromPerson
|
||||
|
||||
public int? ApproximateYears { init; get; }
|
||||
public string DisplayDirectoryName { init; get; }
|
||||
public ReadOnlyCollection<string> LocationContainersFiles { init; get; }
|
||||
public PersonBirthday PersonBirthday { init; get; }
|
||||
public string SegmentB { init; get; }
|
||||
|
||||
[JsonConstructor]
|
||||
public MappingFromPerson(int? approximateYears, string displayDirectoryName, PersonBirthday personBirthday, string segmentB)
|
||||
public MappingFromPerson(int? approximateYears, string displayDirectoryName, ReadOnlyCollection<string> locationContainersFiles, PersonBirthday personBirthday, string segmentB)
|
||||
{
|
||||
ApproximateYears = approximateYears;
|
||||
DisplayDirectoryName = displayDirectoryName;
|
||||
LocationContainersFiles = locationContainersFiles;
|
||||
PersonBirthday = personBirthday;
|
||||
SegmentB = segmentB;
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Methods;
|
||||
|
||||
public interface IMapLogic
|
||||
{
|
||||
|
||||
(bool, Dictionary<int, PersonContainer[]>?) GetWholePercentagesToPersonContainers(int id);
|
||||
(bool, ReadOnlyDictionary<int, ReadOnlyCollection<PersonContainer>>?) GetWholePercentagesToPersonContainers(int id);
|
||||
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
public interface IMapping
|
||||
|
@ -1,3 +1,5 @@
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace View_by_Distance.Shared.Models.Properties;
|
||||
|
||||
public interface IMappingFromPerson
|
||||
@ -5,6 +7,7 @@ public interface IMappingFromPerson
|
||||
|
||||
public int? ApproximateYears { init; get; }
|
||||
public string DisplayDirectoryName { init; get; }
|
||||
public ReadOnlyCollection<string> LocationContainersFiles { init; get; }
|
||||
public PersonBirthday PersonBirthday { init; get; }
|
||||
public string SegmentB { init; get; }
|
||||
|
||||
|
@ -63,7 +63,7 @@ internal abstract class Container
|
||||
{
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
if (!argZeroIsConfigurationRootDirectory && !container.SourceDirectory.StartsWith(argZero))
|
||||
continue;
|
||||
@ -169,7 +169,7 @@ internal abstract class Container
|
||||
Dictionary<string, List<Models.Item>> directoryToItems = new();
|
||||
foreach (string[] files in filesCollection)
|
||||
{
|
||||
if (!files.Any())
|
||||
if (files.Length == 0)
|
||||
continue;
|
||||
directory = Path.GetDirectoryName(files.First());
|
||||
if (directory is null)
|
||||
@ -199,7 +199,7 @@ internal abstract class Container
|
||||
}
|
||||
foreach (KeyValuePair<string, List<Models.Item>> keyValuePair in directoryToItems)
|
||||
{
|
||||
if (!keyValuePair.Value.Any())
|
||||
if (keyValuePair.Value.Count == 0)
|
||||
continue;
|
||||
container = new(keyValuePair.Key, keyValuePair.Value);
|
||||
results.Add(container);
|
||||
@ -233,10 +233,10 @@ internal abstract class Container
|
||||
Models.Item[] filteredItems;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
filteredItems = GetFilterItems(propertyConfiguration, container);
|
||||
if (!filteredItems.Any())
|
||||
if (filteredItems.Length == 0)
|
||||
continue;
|
||||
foreach (Models.Item item in filteredItems)
|
||||
{
|
||||
@ -257,7 +257,7 @@ internal abstract class Container
|
||||
IEnumerable<Models.Item> filteredItems;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
if (!filterItems)
|
||||
filteredItems = container.Items;
|
||||
|
@ -56,7 +56,7 @@ internal abstract class Face
|
||||
{
|
||||
Models.Face? result;
|
||||
List<Models.Face> results = GetFaces(jsonFileFullName, maximum: 1);
|
||||
if (!results.Any())
|
||||
if (results.Count == 0)
|
||||
throw new Exception();
|
||||
result = results[0];
|
||||
return result;
|
||||
|
@ -17,7 +17,7 @@ internal abstract class FaceFileSystem
|
||||
else
|
||||
{
|
||||
string[] files = Directory.GetFiles(parentDirectoryName, Path.GetFileName(fullFileName), SearchOption.AllDirectories);
|
||||
if (!files.Any())
|
||||
if (files.Length == 0)
|
||||
throw new Exception($"File [{fileInfo.Name}] <{fullFileName}> doesn't exist (deep search)!");
|
||||
else
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ internal abstract class FileHolder
|
||||
next = Directory.GetFiles(path, searchPattern);
|
||||
}
|
||||
catch { }
|
||||
if (next is not null && next.Any())
|
||||
if (next is not null && next.Length > 0)
|
||||
yield return new(path, next);
|
||||
try
|
||||
{
|
||||
|
@ -37,9 +37,9 @@ public interface IPerson
|
||||
hour == 17 ? "Dead-Male-No" :
|
||||
throw new NotImplementedException(personDisplayDirectoryName);
|
||||
|
||||
bool TestStatic_IsDefaultName(string mappingDefaultName, string value) =>
|
||||
IsDefaultName(mappingDefaultName, value);
|
||||
static bool IsDefaultName(string mappingDefaultName, string value) =>
|
||||
value == mappingDefaultName || (value.Length > 1 && value[0] == 'X' && value[1] == ']');
|
||||
bool TestStatic_IsDefaultName(string mappingDefaultName, string personDisplayDirectoryName) =>
|
||||
IsDefaultName(mappingDefaultName, personDisplayDirectoryName);
|
||||
static bool IsDefaultName(string mappingDefaultName, string personDisplayDirectoryName) =>
|
||||
personDisplayDirectoryName == mappingDefaultName || (personDisplayDirectoryName.Length > 1 && personDisplayDirectoryName[0] == 'X' && personDisplayDirectoryName[1] == ']');
|
||||
|
||||
}
|
@ -103,7 +103,7 @@ internal abstract class PersonContainer
|
||||
foreach ((string personKeyFormatted, Models.PersonBirthday personBirthday) in collection)
|
||||
{
|
||||
orderedPersonBirthdays = (from l in collection where !l.PersonKeyFormatted.Contains(numberSign) orderby l.PersonBirthday.Value.Ticks descending select l.PersonBirthday).ToArray();
|
||||
if (!orderedPersonBirthdays.Any())
|
||||
if (orderedPersonBirthdays.Length == 0)
|
||||
personKey = collection[zero].PersonBirthday.Value.Ticks;
|
||||
else
|
||||
{
|
||||
@ -113,7 +113,7 @@ internal abstract class PersonContainer
|
||||
}
|
||||
personKeyDirectory = Path.Combine(personDisplayDirectory, personKeyFormatted);
|
||||
files = Directory.GetFiles(personKeyDirectory, "*", SearchOption.AllDirectories);
|
||||
if (!files.Any())
|
||||
if (files.Length == 0)
|
||||
continue;
|
||||
personDisplayDirectoryAllFiles.AddRange(files.Where(l => l.EndsWith(".rel")));
|
||||
personContainer = new(approximateYears, orderedPersonBirthdays, personDisplayDirectoryAllFiles.ToArray(), personDisplayDirectoryName, personKey, personDirectory);
|
||||
@ -127,7 +127,7 @@ internal abstract class PersonContainer
|
||||
string? result;
|
||||
if (approximateYears is null)
|
||||
throw new NotSupportedException();
|
||||
if (!collection.Any())
|
||||
if (collection.Count == 0)
|
||||
throw new NotSupportedException();
|
||||
const int zero = 0;
|
||||
int? updateApproximateYears;
|
||||
@ -225,7 +225,7 @@ internal abstract class PersonContainer
|
||||
{
|
||||
innerGroupDirectoryName = Path.GetFileName(innerGroupDirectory);
|
||||
segments = innerGroupDirectoryName.Split('-');
|
||||
if (!segments.Any())
|
||||
if (segments.Length == 0)
|
||||
throw new NotSupportedException("Misplaced directory!");
|
||||
if (segments.Length != 3)
|
||||
continue;
|
||||
@ -285,7 +285,7 @@ internal abstract class PersonContainer
|
||||
_ = Directory.CreateDirectory(a2PeopleSingletonDirectoryChar);
|
||||
}
|
||||
string[] groupDirectories = Directory.GetDirectories(a2PeopleSingletonDirectory, "*", SearchOption.TopDirectoryOnly);
|
||||
if (!groupDirectories.Any())
|
||||
if (groupDirectories.Length == 0)
|
||||
results = new();
|
||||
else
|
||||
results = GetPersonContainersGroups(personBirthdayFormat, facesFileNameExtension, personCharacters, groupDirectories);
|
||||
|
@ -40,10 +40,10 @@ internal abstract class Property
|
||||
|| (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.')
|
||||
select l
|
||||
).ToArray();
|
||||
if (!results.Any())
|
||||
if (results.Length == 0)
|
||||
result = null;
|
||||
else
|
||||
result = !matches.Any();
|
||||
result = matches.Length == 0;
|
||||
return new(result, results);
|
||||
}
|
||||
|
||||
@ -203,7 +203,7 @@ internal abstract class Property
|
||||
}
|
||||
long threeStandardDeviationHigh;
|
||||
long min;
|
||||
if (!ticksCollection.Any())
|
||||
if (ticksCollection.Count == 0)
|
||||
min = 0;
|
||||
else
|
||||
min = ticksCollection.Min();
|
||||
@ -263,7 +263,7 @@ internal abstract class Property
|
||||
bool result = false;
|
||||
foreach (Models.Container container in containers)
|
||||
{
|
||||
if (!container.Items.Any())
|
||||
if (container.Items.Count == 0)
|
||||
continue;
|
||||
if ((from l in container.Items where l.Any() select true).Any())
|
||||
{
|
||||
|
@ -97,7 +97,7 @@ internal abstract partial class XDirectory
|
||||
}
|
||||
}
|
||||
}
|
||||
if (renameCollection.Any())
|
||||
if (renameCollection.Count > 0)
|
||||
IDirectory.MoveFiles(renameCollection, "{}", "{abd}");
|
||||
return renameCollection.Count;
|
||||
}
|
||||
@ -139,7 +139,7 @@ internal abstract partial class XDirectory
|
||||
continue;
|
||||
matches.Add(possible);
|
||||
}
|
||||
if (matches.Count == 1 || (matches.Any() && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
|
||||
if (matches.Count == 1 || (matches.Count > 0 && lengths.Distinct().Count() == 1 && creationTimes.Distinct().Count() == 1))
|
||||
result = matches.First();
|
||||
return result;
|
||||
}
|
||||
@ -167,7 +167,7 @@ internal abstract partial class XDirectory
|
||||
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, new(), null));
|
||||
else
|
||||
{
|
||||
if (!collection.Any())
|
||||
if (collection.Count == 0)
|
||||
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, null));
|
||||
else if (uniqueFileName && collection.Count == 1)
|
||||
results.Add(new(file, uniqueFileName, isNotUniqueAndNeedsReview, collection, collection.First()));
|
||||
|
@ -32,7 +32,7 @@ internal abstract class XPath
|
||||
bool result;
|
||||
List<string> results = new();
|
||||
DeleteEmptyDirectories(rootDirectory, results);
|
||||
result = results.Any();
|
||||
result = results.Count > 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ internal abstract class XPath
|
||||
{
|
||||
DeleteEmptyDirectories(directory, check);
|
||||
deletedDirectories.AddRange(check);
|
||||
if (check.Any())
|
||||
if (check.Count > 0)
|
||||
DeleteEmptyDirectories(directory, deletedDirectories);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user