AOT Builds

This commit is contained in:
2023-10-22 11:25:08 -07:00
commit f7573e95e4
56 changed files with 4270 additions and 0 deletions

15
Shared/.vscode/mklink.md vendored Normal file
View File

@ -0,0 +1,15 @@
---
type: "note"
created: "2023-10-20T03:58:11.564Z"
updated: "2023-10-20T03:59:01.765Z"
---
# mklink
```bash
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
```
```bash
mklink /J "L:\Git\AA\Shared\.kanbn" "D:\5-Other-Small\Kanban\View-by-Distance"
```

61
Shared/.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,61 @@
{
"cSpell.words": [
"appsettings",
"Argb",
"ASPNETCORE",
"Barrick",
"bcdfghjklmnpqrstvwxyz",
"Bday",
"Beichler",
"Bohdi",
"Cobertura",
"cref",
"CUDA",
"Dlib",
"DSCN",
"Exif",
"eyeα",
"Getα",
"Greyscale",
"Hasher",
"Hmmss",
"Hmmssfff",
"jfif",
"JOSN",
"mmod",
"Nicéphore",
"Niépce",
"nosj",
"paramref",
"permille",
"permyriad",
"Phares",
"Phgtv",
"Photoshop",
"RDHC",
"recognise",
"Rects",
"resnet",
"Serilog",
"Subfile",
"Subfiles",
"Syncthing",
"Unmanaged",
"unrecognised",
"Upsample",
"Vericruz"
],
"files.watcherExclude": {
"**/node_modules": true
},
"cSpell.enabled": true,
"files.exclude": {
"**/.git": false,
"**/node_modules": true
},
"coverage-gutters.coverageBaseDir": "./.vscode/ReportGenerator/Cobertura/*",
"extensions.ignoreRecommendations": true,
"[markdown]": {
"editor.wordWrap": "off"
}
}

38
Shared/AA.Shared.csproj Normal file
View File

@ -0,0 +1,38 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RuntimeIdentifiers>win-x64;linux-x64</RuntimeIdentifiers>
<TargetFramework>net8.0</TargetFramework>
</PropertyGroup>
<PropertyGroup>
<PackageId>Phares.AA.Shared</PackageId>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<Version>8.0.101.1</Version>
<Authors>Mike Phares</Authors>
<Company>Phares</Company>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
</PropertyGroup>
<PropertyGroup>
<IsWindows Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Windows)))' == 'true'">true</IsWindows>
<IsOSX Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::OSX)))' == 'true'">true</IsOSX>
<IsLinux Condition="'$([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform($([System.Runtime.InteropServices.OSPlatform]::Linux)))' == 'true'">true</IsLinux>
</PropertyGroup>
<PropertyGroup Condition="'$(IsWindows)'=='true'">
<DefineConstants>Windows</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsOSX)'=='true'">
<DefineConstants>OSX</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(IsLinux)'=='true'">
<DefineConstants>Linux</DefineConstants>
</PropertyGroup>
<ItemGroup Condition="'$(RuntimeIdentifier)' == 'browser-wasm'">
<SupportedPlatform Include="browser" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="7.0.0" />
<PackageReference Include="System.Text.Json" Version="7.0.3" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,24 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record AviDirectory(DateTime? DateTimeOriginal,
string? Duration,
string? Height,
string? Width)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, AviDirectorySourceGenerationContext.Default.AviDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(AviDirectory))]
public partial class AviDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,35 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record ExifDirectory(AviDirectory AviDirectory,
ExifDirectoryBase ExifDirectoryBase,
string File,
FileMetadataDirectory FileMetadataDirectory,
GifHeaderDirectory GifHeaderDirectory,
GpsDirectory GpsDirectory,
int? Height,
string JsonFile,
JpegDirectory JpegDirectory,
PhotoshopDirectory PhotoshopDirectory,
PngDirectory PngDirectory,
QuickTimeMovieHeaderDirectory QuickTimeMovieHeaderDirectory,
QuickTimeTrackHeaderDirectory QuickTimeTrackHeaderDirectory,
WebPDirectory WebPDirectory,
int? Width)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, ExifDirectorySourceGenerationContext.Default.ExifDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ExifDirectory))]
public partial class ExifDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,66 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record ExifDirectoryBase(string? Aperture,
string? ApplicationNotes,
string? Artist,
string? BitsPerSample,
string? BodySerialNumber,
string? CameraOwnerName,
string? CompressedAverageBitsPerPixel,
string? Compression,
string? Copyright,
DateTime? DateTime,
DateTime? DateTimeDigitized,
DateTime? DateTimeOriginal,
string? DocumentName,
string? ExifVersion,
string? ExposureTime,
string? FileSource,
string? ImageDescription,
string? ImageHeight,
string? ImageNumber,
string? ImageUniqueId,
string? ImageWidth,
string? IsoSpeed,
string? LensMake,
string? LensModel,
string? LensSerialNumber,
string? Make,
string? MakerNote,
string? Model,
string? Orientation,
int? OrientationValue,
string? Rating,
string? RatingPercent,
string? SecurityClassification,
string? ShutterSpeed,
string? Software,
string? TimeZone,
string? TimeZoneDigitized,
string? TimeZoneOriginal,
string? UserComment,
string? WinAuthor,
string? WinComment,
string? WinKeywords,
string? WinSubject,
string? WinTitle,
string? XResolution,
string? YResolution)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, ExifDirectoryBaseSourceGenerationContext.Default.ExifDirectoryBase);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(ExifDirectoryBase))]
public partial class ExifDirectoryBaseSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,82 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public class FileHolder
{
protected readonly DateTime? _CreationTime;
protected readonly string? _DirectoryName;
protected readonly bool _Exists;
protected readonly string _ExtensionLowered;
protected readonly string _FullName;
protected readonly int? _Id;
protected readonly DateTime? _LastWriteTime;
protected readonly long? _Length;
protected readonly string _Name;
protected readonly string _NameWithoutExtension;
public DateTime? CreationTime => _CreationTime;
public string? DirectoryName => _DirectoryName;
public bool Exists => _Exists;
public string ExtensionLowered => _ExtensionLowered;
public string FullName => _FullName;
public int? Id => _Id;
public DateTime? LastWriteTime => _LastWriteTime;
public long? Length => _Length;
public string Name => _Name;
public string NameWithoutExtension => _NameWithoutExtension;
public FileHolder(DateTime? creationTime, string? directoryName, bool exists, string extensionLowered, string fullName, int? id, DateTime? lastWriteTime, long? length, string name, string nameWithoutExtension)
{
_CreationTime = creationTime;
_DirectoryName = directoryName;
_Exists = exists;
_ExtensionLowered = extensionLowered;
_FullName = fullName;
_Id = id;
_LastWriteTime = lastWriteTime;
_Length = length;
_Name = name;
_NameWithoutExtension = nameWithoutExtension;
}
public FileHolder(FileInfo fileInfo, int? id)
{
if (fileInfo.Exists)
{
_CreationTime = fileInfo.CreationTime;
_CreationTime = fileInfo.CreationTime;
_LastWriteTime = fileInfo.LastWriteTime;
_Length = fileInfo.Length;
}
_DirectoryName = fileInfo.DirectoryName;
_Exists = fileInfo.Exists;
_ExtensionLowered = fileInfo.Extension.ToLower();
_Id = id;
_FullName = fileInfo.FullName;
_Name = fileInfo.Name;
_NameWithoutExtension = Path.GetFileNameWithoutExtension(fileInfo.FullName);
}
public FileHolder(string fileName) :
this(new FileInfo(fileName), null)
{ }
public FileHolder(string fileName, int? id) :
this(new FileInfo(fileName), id)
{ }
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FileHolderSourceGenerationContext.Default.FileHolder);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FileHolder))]
internal partial class FileHolderSourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,23 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record FileMetadataDirectory(DateTime? FileModifiedDate,
string? FileName,
string? FileSize)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, FileMetadataDirectorySourceGenerationContext.Default.FileMetadataDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(FileMetadataDirectory))]
public partial class FileMetadataDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record GifHeaderDirectory(string? ImageHeight,
string? ImageWidth)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, GifHeaderDirectorySourceGenerationContext.Default.GifHeaderDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(GifHeaderDirectory))]
public partial class GifHeaderDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,26 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record GpsDirectory(string? Altitude,
string? Latitude,
string? LatitudeRef,
string? Longitude,
string? LongitudeRef,
DateTime? TimeStamp)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, GpsDirectorySourceGenerationContext.Default.GpsDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(GpsDirectory))]
public partial class GpsDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record JpegDirectory(string? ImageHeight,
string? ImageWidth)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, JpegDirectorySourceGenerationContext.Default.JpegDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(JpegDirectory))]
public partial class JpegDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record PhotoshopDirectory(string? JpegQuality,
string? Url)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, PhotoshopDirectorySourceGenerationContext.Default.PhotoshopDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(PhotoshopDirectory))]
public partial class PhotoshopDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record PngDirectory(string? ImageHeight,
string? ImageWidth)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, PngDirectorySourceGenerationContext.Default.PngDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(PngDirectory))]
public partial class PngDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,25 @@
namespace View_by_Distance.Shared.Models.Properties;
public interface IAAConfiguration
{
public string DateGroup { init; get; }
public string[] IgnoreExtensions { init; get; }
public string[] IgnoreRulesKeyWords { init; get; }
public string PersonBirthdayFormat { init; get; }
public bool PropertiesChangedForProperty { init; get; }
public string[] PropertyContentCollectionFiles { init; get; }
public string ResultAllInOne { init; get; }
public int ResultAllInOneSubdirectoryLength { init; get; }
public string ResultCollection { init; get; }
public string ResultContent { init; get; }
public string ResultSingleton { init; get; }
public string[] ValidImageFormatExtensions { init; get; }
public string? ModelName { get; }
public int? NumberOfJitters { get; }
public int? NumberOfTimesToUpsample { get; }
public int Offset { init; get; }
public string? PredictorModelName { get; }
public string RootDirectory { get; }
}

View File

@ -0,0 +1,21 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record QuickTimeMovieHeaderDirectory(DateTime? Created)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, QuickTimeMovieHeaderDirectorySourceGenerationContext.Default.QuickTimeMovieHeaderDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(QuickTimeMovieHeaderDirectory))]
public partial class QuickTimeMovieHeaderDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,21 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record QuickTimeTrackHeaderDirectory(DateTime? Created)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, QuickTimeTrackHeaderDirectorySourceGenerationContext.Default.QuickTimeTrackHeaderDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(QuickTimeTrackHeaderDirectory))]
public partial class QuickTimeTrackHeaderDirectorySourceGenerationContext : JsonSerializerContext
{
}

View File

@ -0,0 +1,20 @@
using View_by_Distance.Shared.Models.Stateless.Methods;
namespace View_by_Distance.Shared.Models;
public class Console : IConsole
{
ConsoleKey IConsole.ReadKey()
{
ConsoleKey result = System.Console.ReadKey().Key;
return result;
}
string? IConsole.ReadLine()
{
string? result = System.Console.ReadLine();
return result;
}
}

View File

@ -0,0 +1,20 @@
namespace View_by_Distance.Shared.Models.Stateless;
internal abstract class Id
{
internal static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension)
{
bool result;
int intMinValueLength = int.MinValue.ToString().Length;
if (fileNameWithoutExtension.Length < 5 || fileNameWithoutExtension.Length > intMinValueLength)
result = false;
else
{
bool skipOneAllAreNumbers = fileNameWithoutExtension[1..].All(l => char.IsNumber(l));
result = (skipOneAllAreNumbers && fileNameWithoutExtension[0] == '-') || (skipOneAllAreNumbers && char.IsNumber(fileNameWithoutExtension[0]));
}
return result;
}
}

View File

@ -0,0 +1,9 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IConsole
{
string? ReadLine();
ConsoleKey ReadKey();
}

View File

@ -0,0 +1,16 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IDate
{
(bool?, string[]) TestStatic_IsWrongYear(string[] segments, string year) =>
IsWrongYear(segments, year);
static (bool?, string[]) IsWrongYear(string[] segments, string year) =>
XDate.IsWrongYear(segments, year);
(int Season, string seasonName) TestStatic_GetSeason(int dayOfYear) =>
GetSeason(dayOfYear);
static (int Season, string seasonName) GetSeason(int dayOfYear) =>
XDate.GetSeason(dayOfYear);
}

View File

@ -0,0 +1,39 @@
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IId
{
bool TestStatic_NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
static bool NameWithoutExtensionIsIdFormat(string fileNameWithoutExtension) =>
Id.NameWithoutExtensionIsIdFormat(fileNameWithoutExtension);
bool TestStatic_NameWithoutExtensionIsIdFormat(FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(fileHolder);
static bool NameWithoutExtensionIsIdFormat(FileHolder fileHolder) =>
NameWithoutExtensionIsIdFormat(fileHolder.NameWithoutExtension);
string TestStatic_GetPaddedId(int intMinValueLength, int index, int id) =>
GetPaddedId(intMinValueLength, index, id);
static string GetPaddedId(int intMinValueLength, int index, int id) =>
id > -1 ? $"{index}070{id.ToString().PadLeft(intMinValueLength, '0')}" : $"{index}030{id.ToString()[1..].PadLeft(intMinValueLength, '0')}";
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileNameWithoutExtension, sortOrderOnlyLengthIndex);
static bool NameWithoutExtensionIsPaddedIdFormat(string fileNameWithoutExtension, int sortOrderOnlyLengthIndex) =>
fileNameWithoutExtension.Length > sortOrderOnlyLengthIndex
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex] == '0'
&& fileNameWithoutExtension[sortOrderOnlyLengthIndex - 3] == '0'
&& fileNameWithoutExtension.All(l => char.IsNumber(l));
short TestStatic_GetSortOrderOnlyLengthIndex(int offset) =>
GetSortOrderOnlyLengthIndex(offset);
static short GetSortOrderOnlyLengthIndex(int offset) =>
(short)(offset.ToString().Length + 3);
bool TestStatic_NameWithoutExtensionIsPaddedIdFormat(FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileHolder, sortOrderOnlyLengthIndex);
static bool NameWithoutExtensionIsPaddedIdFormat(FileHolder fileHolder, int sortOrderOnlyLengthIndex) =>
NameWithoutExtensionIsPaddedIdFormat(fileHolder.NameWithoutExtension, sortOrderOnlyLengthIndex);
}

View File

@ -0,0 +1,74 @@
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IPath
{ // ...
string TestStatic_GetRelativePath(string path, int length) =>
GetRelativePath(path, length);
static string GetRelativePath(string path, int length) =>
XPath.GetRelativePath(path, length, forceExtensionToLower: false);
bool TestStatic_DeleteEmptyDirectories(string rootDirectory) =>
DeleteEmptyDirectories(rootDirectory);
static bool DeleteEmptyDirectories(string rootDirectory) =>
XPath.DeleteEmptyDirectories(rootDirectory);
void TestStatic_ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
ChangeDateForEmptyDirectories(rootDirectory, ticks);
static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks) =>
XPath.ChangeDateForEmptyDirectories(rootDirectory, ticks);
void TestStatic_MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
MakeHiddenIfAllItemsAreHidden(rootDirectory);
static void MakeHiddenIfAllItemsAreHidden(string rootDirectory) =>
XPath.MakeHiddenIfAllItemsAreHidden(rootDirectory);
void TestStatic_DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
DeleteEmptyDirectories(rootDirectory, deletedDirectories);
static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories) =>
XPath.DeleteEmptyDirectories(rootDirectory, deletedDirectories);
// $dirs = gci "" -directory -recurse | Where { (gci $_.fullName).count -eq 0 } | select -expandproperty FullName $dirs | Foreach-Object { Remove-Item $_ }
string[] TestStatic_GetDirectoryNames(string directory) =>
GetDirectoryNames(directory);
static string[] GetDirectoryNames(string directory) =>
XPath.GetDirectoryNames(directory).ToArray();
string[] TestStatic_GetDirectories(string directory) =>
GetDirectories(directory);
static string[] GetDirectories(string directory) =>
XPath.GetDirectories(directory).ToArray();
string TestStatic_GetRelativePath(string path, int length, bool forceExtensionToLower) =>
GetRelativePath(path, length, forceExtensionToLower);
static string GetRelativePath(string path, int length, bool forceExtensionToLower) =>
XPath.GetRelativePath(path, length, forceExtensionToLower);
bool TestStatic_WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches = null) =>
XPath.WriteAllText(path, contents, updateDateWhenMatches, compareBeforeWrite, updateToWhenMatches);
(int level, List<string> directories) TestStatic_Get(string rootDirectory, string sourceDirectory) =>
Get(rootDirectory, sourceDirectory);
static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory) =>
XPath.Get(rootDirectory, sourceDirectory);
string TestStatic_GetDirectory(string sourceDirectory, int level, string directoryName) =>
GetDirectory(sourceDirectory, level, directoryName);
static string GetDirectory(string sourceDirectory, int level, string directoryName) =>
XPath.GetDirectory(sourceDirectory, level, directoryName);
(string, int) TestStatic_GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName) =>
XPath.GetDirectoryNameAndIndex(resultAllInOneSubdirectoryLength, fileName);
Dictionary<string, string[]> TestStatic_GetKeyValuePairs(IAAConfiguration aAConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
GetKeyValuePairs(aAConfiguration, resultsFullGroupDirectory, directories);
static Dictionary<string, string[]> GetKeyValuePairs(IAAConfiguration propertyConfiguration, string? resultsFullGroupDirectory, string[]? directories) =>
XPath.GetKeyValuePairs(propertyConfiguration, resultsFullGroupDirectory, directories);
}

View File

@ -0,0 +1,48 @@
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless.Methods;
public interface IResult
{
string TestStatic_GetRelativePath(IAAConfiguration aAConfiguration, string path) =>
GetRelativePath(aAConfiguration, path);
static string GetRelativePath(IAAConfiguration aAConfiguration, string path) =>
XResult.GetRelativePath(aAConfiguration, path);
string TestStatic_GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create) =>
GetResultsGroupDirectory(aAConfiguration, description, create);
static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create) =>
XResult.GetResultsGroupDirectory(aAConfiguration, description, create);
string TestStatic_GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
GetResultsGroupDirectory(aAConfiguration, description);
static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
XResult.GetResultsGroupDirectory(aAConfiguration, description, create: true);
string TestStatic_GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
GetResultsDateGroupDirectory(aAConfiguration, description);
static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description) =>
XResult.GetResultsDateGroupDirectory(aAConfiguration, description);
string TestStatic_GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup) =>
GetResultsDateGroupDirectory(aAConfiguration, description, jsonGroup);
static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup) =>
XResult.GetResultsDateGroupDirectory(aAConfiguration, description, jsonGroup);
List<string> TestStatic_GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) =>
GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted) =>
XResult.GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
string TestStatic_GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) =>
GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
static string GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel) =>
XResult.GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
List<string> TestStatic_GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) =>
GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription) =>
XResult.GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel, contentDescription, singletonDescription, collectionDescription);
}

View File

@ -0,0 +1,24 @@
namespace View_by_Distance.Shared.Models.Stateless;
/// <summary>
/// Specifies the model of face detector.
/// </summary>
public enum Model
{
/// <summary>
/// Specifies that the model is HOG (Histograms of Oriented Gradients) based face detector.
/// </summary>
Hog,
/// <summary>
/// Specifies that the model is CNN (Convolutional Neural Network) based face detector.
/// </summary>
Cnn,
/// <summary>
/// Specifies that the custom face detector.
/// </summary>
Custom
}

View File

@ -0,0 +1,24 @@
namespace View_by_Distance.Shared.Models.Stateless;
/// <summary>
/// Specifies the dimension of vector which be returned from detector.
/// </summary>
public enum PredictorModel
{
/// <summary>
/// Specifies that the large scale detector. The detector returns 68 points for represent face.
/// </summary>
Large,
/// <summary>
/// Specifies that the small scale detector. The detector returns 5 points for represent face.
/// </summary>
Small,
/// <summary>
/// Specifies that the custom detector.
/// </summary>
Custom
}

View File

@ -0,0 +1,50 @@
namespace View_by_Distance.Shared.Models.Stateless;
internal abstract class XDate
{
internal static (int Season, string seasonName) GetSeason(int dayOfYear)
{
(int Season, string seasonName) result = dayOfYear switch
{
< 78 => new(0, "Winter"),
< 171 => new(1, "Spring"),
< 264 => new(2, "Summer"),
< 354 => new(3, "Fall"),
_ => new(4, "Winter")
};
return result;
}
internal static (bool?, string[]) IsWrongYear(string[] segments, string year)
{
bool? result;
string[] results = (
from l
in segments
where l?.Length > 2
&& (
l[..2] is "18" or "19" or "20"
|| (l.Length == 5 && l.Substring(1, 2) is "18" or "19" or "20" && (l[0] is '~' or '=' or '-' or '^' or '#'))
|| (l.Length == 6 && l[..2] is "18" or "19" or "20" && l[4] == '.')
|| (l.Length == 7 && l.Substring(1, 2) is "18" or "19" or "20" && l[5] == '.')
)
select l
).ToArray();
string[] matches = (
from l
in results
where l == year
|| (l.Length == 5 && l.Substring(1, 4) == year && (l[0] is '~' or '=' or '-' or '^' or '#'))
|| (l.Length == 6 && l[..4] == year && l[4] == '.')
|| (l.Length == 7 && l.Substring(1, 4) == year && l[5] == '.')
select l
).ToArray();
if (results.Length == 0)
result = null;
else
result = matches.Length == 0;
return new(result, results);
}
}

View File

@ -0,0 +1,331 @@
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless;
internal abstract class XPath
{
internal static string GetRelativePath(string path, int length, bool forceExtensionToLower)
{
string result;
if (forceExtensionToLower)
{
string extension = Path.GetExtension(path);
string extensionLowered = Path.GetExtension(path).ToLower();
if (extension != extensionLowered)
{
string? directoryName = Path.GetDirectoryName(path);
if (string.IsNullOrEmpty(directoryName))
throw new NullReferenceException(directoryName);
string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
if (string.IsNullOrEmpty(fileNameWithoutExtension))
throw new NullReferenceException(fileNameWithoutExtension);
path = Path.Combine(directoryName, $"{fileNameWithoutExtension}{extensionLowered}");
}
}
result = path[length..].Replace(@"\", "/");
return result;
}
internal static bool DeleteEmptyDirectories(string rootDirectory)
{
bool result;
List<string> results = [];
DeleteEmptyDirectories(rootDirectory, results);
result = results.Count > 0;
return result;
}
internal static void DeleteEmptyDirectories(string rootDirectory, List<string> deletedDirectories)
{
if (Directory.Exists(rootDirectory))
{
string[] files;
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.TopDirectoryOnly);
if (directories.Length > 0)
files = [];
else
files = Directory.GetFiles(rootDirectory, "*", SearchOption.AllDirectories);
if (directories.Length == 0 && files.Length == 0)
{
deletedDirectories.Add(rootDirectory);
try
{ Directory.Delete(rootDirectory); }
catch (UnauthorizedAccessException)
{
new DirectoryInfo(rootDirectory).Attributes = FileAttributes.Normal;
Directory.Delete(rootDirectory);
}
}
else
{
List<string> check = [];
foreach (string directory in directories)
{
DeleteEmptyDirectories(directory, check);
deletedDirectories.AddRange(check);
if (check.Count > 0)
DeleteEmptyDirectories(directory, deletedDirectories);
}
}
}
}
internal static bool WriteAllText(string path, string contents, bool updateDateWhenMatches, bool compareBeforeWrite, DateTime? updateToWhenMatches)
{
bool result;
string text;
if (!compareBeforeWrite)
result = true;
else
{
if (!File.Exists(path))
text = string.Empty;
else
text = File.ReadAllText(path);
result = text != contents;
if (!result && updateDateWhenMatches)
{
if (updateToWhenMatches is null)
File.SetLastWriteTime(path, DateTime.Now);
else
File.SetLastWriteTime(path, updateToWhenMatches.Value);
}
}
if (result)
{
if (path.Contains("()"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("[]") && !path.EndsWith(".json"))
File.WriteAllText(path, contents);
else if (path.Contains("{}") && path.EndsWith(".json") && contents[0] == '{')
File.WriteAllText(path, contents);
else if (path.Contains("[]") && path.EndsWith(".json") && contents[0] == '[')
File.WriteAllText(path, contents);
else
File.WriteAllText(path, contents);
}
return result;
}
internal static List<string> GetDirectoryNames(string directory)
{
List<string> results = [];
string? fileName;
string? checkDirectory = directory;
string? pathRoot = Path.GetPathRoot(directory);
string extension = Path.GetExtension(directory);
if (string.IsNullOrEmpty(pathRoot))
throw new NullReferenceException(nameof(pathRoot));
if (Directory.Exists(directory))
{
fileName = Path.GetFileName(directory);
if (!string.IsNullOrEmpty(fileName))
results.Add(fileName);
}
else if ((string.IsNullOrEmpty(extension) || extension.Length > 3) && !File.Exists(directory))
{
fileName = Path.GetFileName(directory);
if (!string.IsNullOrEmpty(fileName))
results.Add(fileName);
}
for (int i = 0; i < int.MaxValue; i++)
{
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
break;
fileName = Path.GetFileName(checkDirectory);
if (string.IsNullOrEmpty(fileName))
continue;
results.Add(fileName);
}
results.Add(pathRoot);
results.Reverse();
return results;
}
internal static List<string> GetDirectories(string directory)
{
List<string> results = [];
string? checkDirectory = directory;
string? pathRoot = Path.GetPathRoot(directory);
if (string.IsNullOrEmpty(pathRoot))
throw new NullReferenceException(nameof(pathRoot));
if (Directory.Exists(directory))
results.Add(directory);
for (int i = 0; i < int.MaxValue; i++)
{
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory) || checkDirectory == pathRoot)
break;
results.Add(checkDirectory);
}
results.Add(pathRoot);
results.Reverse();
return results;
}
internal static (int level, List<string> directories) Get(string rootDirectory, string sourceDirectory)
{
int result = 0;
string? directory;
string? checkDirectory;
List<string> results = [];
checkDirectory = sourceDirectory;
for (int i = 0; i < int.MaxValue; i++)
{
result += 1;
directory = Path.GetFileName(checkDirectory);
if (string.IsNullOrEmpty(directory))
break;
results.Add(directory);
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (checkDirectory == rootDirectory)
break;
}
results.Reverse();
return new(result, results);
}
internal static string GetDirectory(string sourceDirectory, int level, string directoryName)
{
string result;
string? checkDirectory;
checkDirectory = Path.GetDirectoryName(sourceDirectory);
for (int i = 0; i < level; i++)
checkDirectory = Path.GetDirectoryName(checkDirectory);
if (string.IsNullOrEmpty(checkDirectory))
throw new Exception();
checkDirectory = Path.Combine(checkDirectory, directoryName);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
result = checkDirectory;
return result;
}
internal static void ChangeDateForEmptyDirectories(string rootDirectory, long ticks)
{
DateTime dateTime = new(ticks);
IEnumerable<string> fileSystemEntries;
string[] directories;
if (!Directory.Exists(rootDirectory))
directories = [];
else
directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
fileSystemEntries = Directory.EnumerateFileSystemEntries(directory, "*", SearchOption.TopDirectoryOnly);
if (fileSystemEntries.Any())
continue;
Directory.SetLastWriteTime(directory, dateTime);
}
}
internal static void MakeHiddenIfAllItemsAreHidden(string rootDirectory)
{
bool check;
FileInfo fileInfo;
IEnumerable<string> files;
DirectoryInfo directoryInfo;
IEnumerable<string> subDirectories;
string[] directories = Directory.GetDirectories(rootDirectory, "*", SearchOption.AllDirectories);
foreach (string directory in directories)
{
directoryInfo = new(directory);
if (directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
continue;
check = true;
subDirectories = Directory.EnumerateDirectories(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string subDirectory in subDirectories)
{
directoryInfo = new(subDirectory);
if (!directoryInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
check = false;
break;
}
}
if (!check)
continue;
files = Directory.EnumerateFiles(directory, "*", SearchOption.TopDirectoryOnly);
foreach (string file in files)
{
fileInfo = new(file);
if (!fileInfo.Attributes.HasFlag(FileAttributes.Hidden))
{
check = false;
break;
}
}
if (!check)
continue;
directoryInfo.Attributes |= FileAttributes.Hidden;
}
}
internal static (string, int) GetDirectoryNameAndIndex(int resultAllInOneSubdirectoryLength, string fileName)
{
int converted;
string result;
string check = fileName.Length < resultAllInOneSubdirectoryLength ? new('-', resultAllInOneSubdirectoryLength) : fileName.Split('.')[0][^resultAllInOneSubdirectoryLength..];
if (check.Any(l => !char.IsNumber(l)))
{
result = new('-', resultAllInOneSubdirectoryLength);
converted = int.Parse($"1{new string('0', resultAllInOneSubdirectoryLength)}");
}
else
{
result = check;
converted = int.Parse(check);
}
return (result, converted);
}
internal static Dictionary<string, string[]> GetKeyValuePairs(IAAConfiguration aAConfiguration, string? resultsFullGroupDirectory, string[]? directories)
{
Dictionary<string, string[]> results = [];
string directory;
string checkDirectory;
int converted = int.Parse($"1{new string('0', aAConfiguration.ResultAllInOneSubdirectoryLength)}");
int plusOne = converted + 1;
List<string> collection = [];
if (directories is not null)
{
foreach (string key in directories)
{
if (resultsFullGroupDirectory is null)
continue;
collection.Clear();
for (int i = 0; i < plusOne; i++)
{
if (string.IsNullOrEmpty(key))
{
if (i == converted)
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, new('-', aAConfiguration.ResultAllInOneSubdirectoryLength)));
else
checkDirectory = Path.GetFullPath(Path.Combine(resultsFullGroupDirectory, i.ToString().PadLeft(aAConfiguration.ResultAllInOneSubdirectoryLength, '0')));
}
else
{
directory = Path.Combine(resultsFullGroupDirectory, key, aAConfiguration.ResultAllInOne);
if (i == converted)
checkDirectory = Path.GetFullPath(Path.Combine(directory, new('-', aAConfiguration.ResultAllInOneSubdirectoryLength)));
else
checkDirectory = Path.GetFullPath(Path.Combine(directory, i.ToString().PadLeft(aAConfiguration.ResultAllInOneSubdirectoryLength, '0')));
}
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
collection.Add(checkDirectory);
}
if (!string.IsNullOrEmpty(key))
results.Add(key, collection.ToArray());
else
results.Add(aAConfiguration.ResultAllInOne, collection.ToArray());
}
}
return results;
}
}

View File

@ -0,0 +1,138 @@
using View_by_Distance.Shared.Models.Properties;
namespace View_by_Distance.Shared.Models.Stateless;
internal abstract class XResult
{
internal static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description, string jsonGroup)
{
string result = Path.Combine(GetResultsDateGroupDirectory(aAConfiguration, description), jsonGroup);
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
internal static string GetResultsDateGroupDirectory(IAAConfiguration aAConfiguration, string description)
{
string result = Path.Combine(GetResultsGroupDirectory(aAConfiguration, description, create: true), aAConfiguration.DateGroup);
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
internal static string GetRelativePath(IAAConfiguration aAConfiguration, string path)
{
string result = Methods.IPath.GetRelativePath(path, aAConfiguration.RootDirectory.Length);
return result;
}
private static void CheckContent(IAAConfiguration aAConfiguration, string dateGroupDirectory, string contentDescription, string result)
{
string checkDirectory;
checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultContent, aAConfiguration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
string contentDirectory = new(result.Replace("<>", aAConfiguration.ResultContent));
if (!Directory.Exists(contentDirectory))
_ = Directory.CreateDirectory(contentDirectory);
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("() - ", contentDescription));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
private static void CheckSingleton(IAAConfiguration aAConfiguration, string dateGroupDirectory, string singletonDescription, bool converted, string result)
{
string checkDirectory;
checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultSingleton, aAConfiguration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (!converted)
{
string singletonDirectory = new(result.Replace("<>", aAConfiguration.ResultSingleton));
if (!Directory.Exists(singletonDirectory))
_ = Directory.CreateDirectory(singletonDirectory);
}
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("{} - ", singletonDescription));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
private static void CheckCollection(IAAConfiguration aAConfiguration, string dateGroupDirectory, string collectionDescription, bool converted, string result)
{
string checkDirectory = Path.Combine(dateGroupDirectory, aAConfiguration.ResultCollection, aAConfiguration.ResultAllInOne);
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
if (!converted)
{
string collectionDirectory = new(result.Replace("<>", aAConfiguration.ResultCollection));
if (!Directory.Exists(collectionDirectory))
_ = Directory.CreateDirectory(collectionDirectory);
}
checkDirectory = Path.Combine(dateGroupDirectory, string.Concat("[] - ", collectionDescription));
if (!Directory.Exists(checkDirectory))
_ = Directory.CreateDirectory(checkDirectory);
}
internal static string GetResultsFullGroupDirectory(IAAConfiguration aAConfiguration, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel)
{
string result = GetResultsDateGroupDirectory(aAConfiguration, description);
if (includeResizeGroup)
result = Path.Combine(result, outputResolution);
if (includeModel && includePredictorModel)
{
string modelName;
string predictorModelName;
if (aAConfiguration.ModelName is null)
modelName = Model.Hog.ToString();
else
modelName = aAConfiguration.ModelName;
if (aAConfiguration.PredictorModelName is null)
predictorModelName = PredictorModel.Large.ToString();
else
predictorModelName = aAConfiguration.PredictorModelName;
string dateGroupDirectory = string.Concat(outputResolution.Replace(" ", string.Empty), "-", modelName, "-", predictorModelName, "-", aAConfiguration.NumberOfJitters, "-", aAConfiguration.NumberOfTimesToUpsample);
result = Path.Combine(result, dateGroupDirectory);
}
else if (includeModel)
throw new Exception();
else if (includePredictorModel)
throw new Exception();
if (!Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
internal static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string dateGroupDirectory, string contentDescription, string singletonDescription, string collectionDescription, bool converted)
{
List<string> results = [];
string sourceDirectorySegment = GetRelativePath(aAConfiguration, sourceDirectory);
string result = string.Concat(Path.Combine(dateGroupDirectory, "<>"), sourceDirectorySegment);
if (!string.IsNullOrEmpty(contentDescription))
CheckContent(aAConfiguration, dateGroupDirectory, contentDescription, result);
if (!string.IsNullOrEmpty(singletonDescription))
CheckSingleton(aAConfiguration, dateGroupDirectory, singletonDescription, converted, result);
if (!string.IsNullOrEmpty(collectionDescription))
CheckCollection(aAConfiguration, dateGroupDirectory, collectionDescription, converted, result);
results.Add(result);
return results;
}
internal static string GetResultsGroupDirectory(IAAConfiguration aAConfiguration, string description, bool create)
{
string result = Path.Combine($"{aAConfiguration.RootDirectory}-Results", description.Replace('_', ')'));
if (create && !Directory.Exists(result))
_ = Directory.CreateDirectory(result);
return result;
}
internal static List<string> GetDirectoryInfoCollection(IAAConfiguration aAConfiguration, string sourceDirectory, string description, string outputResolution, bool includeResizeGroup, bool includeModel, bool includePredictorModel, string contentDescription, string singletonDescription, string collectionDescription)
{
List<string> results;
bool converted = false;
string dateGroupDirectory = GetResultsFullGroupDirectory(aAConfiguration, description, outputResolution, includeResizeGroup, includeModel, includePredictorModel);
results = GetDirectoryInfoCollection(aAConfiguration, sourceDirectory, dateGroupDirectory, contentDescription, singletonDescription, collectionDescription, converted);
return results;
}
}

View File

@ -0,0 +1,22 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace View_by_Distance.Shared.Models;
public record WebPDirectory(string? ImageHeight,
string? ImageWidth)
{
public override string ToString()
{
string result = JsonSerializer.Serialize(this, WebPDirectorySourceGenerationContext.Default.WebPDirectory);
return result;
}
}
[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WebPDirectory))]
public partial class WebPDirectorySourceGenerationContext : JsonSerializerContext
{
}