diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 0000000..2547dca
--- /dev/null
+++ b/.editorconfig
@@ -0,0 +1,4 @@
+[*.cs]
+
+# CA1822: Member als statisch markieren
+dotnet_diagnostic.CA1822.severity = none
diff --git a/ExeToBat.sln b/ExeToBat.sln
index 24ea6f9..34cdaa3 100644
--- a/ExeToBat.sln
+++ b/ExeToBat.sln
@@ -1,9 +1,14 @@
Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 15
-VisualStudioVersion = 15.0.28010.2036
+# Visual Studio Version 17
+VisualStudioVersion = 17.3.32929.385
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExeToBat", "ExeToBat\ExeToBat.csproj", "{04F45237-23C8-4EE6-B61C-6C47B9979A4B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExeToBat", "ExeToBat\ExeToBat.csproj", "{97ED5369-CCC1-4EAD-B316-97FB983E0A62}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1E4294A3-12F4-4F45-93B3-05D31958042B}"
+ ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
+ EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -11,15 +16,15 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {04F45237-23C8-4EE6-B61C-6C47B9979A4B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {97ED5369-CCC1-4EAD-B316-97FB983E0A62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
- SolutionGuid = {4AA99DAC-6B37-42AF-8FB7-8394329BD79A}
+ SolutionGuid = {9F9811F2-7CC0-4D74-8D4A-51D126D13ECD}
EndGlobalSection
EndGlobal
diff --git a/ExeToBat/App.config b/ExeToBat/App.config
deleted file mode 100644
index bcb2ae2..0000000
--- a/ExeToBat/App.config
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/ExeToBat/Console.cs b/ExeToBat/Console.cs
index 159c47a..7556912 100644
--- a/ExeToBat/Console.cs
+++ b/ExeToBat/Console.cs
@@ -1,8 +1,4 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Linq;
-using static ExeToBat.Generator;
+using static ExeToBat.Generator;
using static System.ConsoleUtils;
using Mono.Options;
using System.Text.Json;
@@ -11,22 +7,27 @@ namespace ExeToBat
{
class Console
{
- static void Main(string[] args) => new Console().Show(args);
+ public static void Main(string[] args) => new Console().Show(args);
public Console() { }
- private readonly Generator generator = new Generator();
+ private readonly Generator generator = new();
public void Show(string[] args)
{
- string config = null;
+ string? config = null;
bool help = false;
- OptionSet options = new OptionSet()
- {
- { "c|config=", "the config file used for automatic generation", v => config = v },
- { "h|help", "show this message and exit", v => help = v != null },
- };
+ OptionSet options =
+ new()
+ {
+ {
+ "c|config=",
+ "the config file used for automatic generation",
+ v => config = v
+ },
+ { "h|help", "show this message and exit", v => help = v != null },
+ };
try
{
@@ -63,13 +64,14 @@ namespace ExeToBat
private void MainMenu()
{
- Dictionary options = new Dictionary
- {
- { "Files", ChooseSource },
- { "Save config", SaveConfig },
- { "Load config", LoadConfig },
- { "Generate", Generate },
- };
+ Dictionary options =
+ new()
+ {
+ { "Files", ChooseSource },
+ { "Save config", SaveConfig },
+ { "Load config", LoadConfig },
+ { "Generate", Generate },
+ };
new ListMenu(options.Keys.ToList())
{
@@ -96,10 +98,9 @@ namespace ExeToBat
System.Console.WriteLine("ExeToBat > Config > Save");
System.Console.WriteLine();
System.Console.Write("{0}> ", "Output File");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
- input.Trim();
- input = input.Replace("\"", "");
+ input = input?.Trim()?.Replace("\"", "");
if (!string.IsNullOrEmpty(input))
{
try
@@ -125,10 +126,9 @@ namespace ExeToBat
System.Console.WriteLine("ExeToBat > Config > Load");
System.Console.WriteLine();
System.Console.Write("{0}> ", "Config File");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
- input.Trim();
- input = input.Replace("\"", "");
+ input = input?.Trim()?.Replace("\"", "");
if (!string.IsNullOrEmpty(input))
{
try
@@ -187,10 +187,9 @@ namespace ExeToBat
System.Console.WriteLine("ExeToBat > Files > Add");
System.Console.WriteLine();
System.Console.Write("{0}> ", "File/Folder");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
- input.Trim();
- input = input.Replace("\"", "");
+ input = input?.Trim()?.Replace("\"", "");
switch (input)
{
case var i when string.IsNullOrEmpty(i):
@@ -198,14 +197,14 @@ namespace ExeToBat
break;
case var i when Directory.Exists(i):
IsInputValid = true;
- foreach (string file in Directory.GetFiles(input))
+ foreach (string file in Directory.GetFiles(i))
{
generator.Sources.Add(new SourceFile(file));
}
break;
case var i when File.Exists(i):
IsInputValid = true;
- generator.Sources.Add(new SourceFile(input));
+ generator.Sources.Add(new SourceFile(i));
break;
default:
@@ -217,33 +216,34 @@ namespace ExeToBat
private void ManageSource(SourceFile source)
{
- Dictionary> options = new Dictionary>
- {
+ Dictionary> options =
+ new()
{
- "Edit",
- () =>
{
- ModifySource(source);
- return false;
- }
- },
- {
- "Position",
- () =>
+ "Edit",
+ () =>
+ {
+ ModifySource(source);
+ return false;
+ }
+ },
{
- EditPosition(source);
- return false;
- }
- },
- {
- "Delete",
- () =>
+ "Position",
+ () =>
+ {
+ EditPosition(source);
+ return false;
+ }
+ },
{
- generator.Sources.Remove(source);
- return true;
- }
- },
- };
+ "Delete",
+ () =>
+ {
+ generator.Sources.Remove(source);
+ return true;
+ }
+ },
+ };
new ListMenu(options.Keys.ToList())
{
@@ -262,16 +262,17 @@ namespace ExeToBat
{
List<(string, string, Action)> options()
{
- List<(string, string, Action)> result = new List<(string, string, Action)>()
- {
- ("File", source.Path, () => { }),
- ("Extraction directory", source.Directory, () => EditExtraction(source)),
- (
- "Execute after extraction",
- source.Execute.ToString(),
- () => source.Execute = !source.Execute
- ),
- };
+ List<(string, string, Action)> result =
+ new()
+ {
+ ("File", source.Path, () => { }),
+ ("Extraction directory", source.Directory, () => EditExtraction(source)),
+ (
+ "Execute after extraction",
+ source.Execute.ToString(),
+ () => source.Execute = !source.Execute
+ ),
+ };
if (source.Execute)
{
result.Add(("Parameters", source.Parameters, () => EditParameters(source)));
@@ -331,7 +332,7 @@ namespace ExeToBat
System.Console.WriteLine("https://ss64.com/nt/syntax-args.html");
System.Console.WriteLine();
System.Console.Write("{0}> ", "Directory");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
if (!string.IsNullOrEmpty(input))
{
@@ -348,9 +349,9 @@ namespace ExeToBat
);
System.Console.WriteLine();
System.Console.Write("{0}> ", "Parameters");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
- input.Trim();
+ input = input?.Trim();
if (!string.IsNullOrEmpty(input))
{
source.Parameters = input;
@@ -371,7 +372,7 @@ namespace ExeToBat
System.Console.WriteLine();
System.Console.Write("{0}> ", "New index");
- string input = System.Console.ReadLine();
+ string? input = System.Console.ReadLine();
if (int.TryParse(input, out int index))
{
@@ -420,13 +421,12 @@ namespace ExeToBat
}
}
- private void OnGenerate(object sender, GeneratorEvent e)
+ private void OnGenerate(object? sender, GeneratorEvent e)
{
switch (e)
{
case GenerationStartEvent s:
System.Console.WriteLine("Starting generation...");
- System.Console.WriteLine("Config file: {0}", "no config file");
System.Console.WriteLine("{0} files scheduled", s.Files.Count);
break;
case ReadingFileEvent s:
diff --git a/ExeToBat/ConsoleUtils.cs b/ExeToBat/ConsoleUtils.cs
index 745fb30..77c0d20 100644
--- a/ExeToBat/ConsoleUtils.cs
+++ b/ExeToBat/ConsoleUtils.cs
@@ -1,7 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
-
-namespace System
+namespace System
{
public static class ConsoleUtils
{
diff --git a/ExeToBat/ExeToBat.csproj b/ExeToBat/ExeToBat.csproj
index 983ab3c..4366e04 100644
--- a/ExeToBat/ExeToBat.csproj
+++ b/ExeToBat/ExeToBat.csproj
@@ -1,97 +1,26 @@
-
-
-
+
+
- Debug
- AnyCPU
- {04F45237-23C8-4EE6-B61C-6C47B9979A4B}
Exe
- ExeToBat
- ExeToBat
- v4.8
- 512
- true
- true
-
-
-
+ net6.0
+ enable
+ enable
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
+
+
+ $(WarningsAsErrors);NU1605;CS8600;CS8601;CS8602;CS8603;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633;CS8767;
-
- AnyCPU
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
+
+
+ $(WarningsAsErrors);NU1605;CS8600;CS8601;CS8602;CS8603;CS8604;CS8613;CS8614;CS8619;CS8620;CS8622;CS8625;CS8629;CS8633;CS8767;
+
-
- ..\packages\Microsoft.Bcl.AsyncInterfaces.6.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
-
-
- ..\packages\Mono.Options.6.12.0.148\lib\net40\Mono.Options.dll
-
-
-
- ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
-
-
-
- ..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
-
-
-
- ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
-
-
- ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
-
-
- ..\packages\System.Text.Encodings.Web.6.0.0\lib\net461\System.Text.Encodings.Web.dll
-
-
- ..\packages\System.Text.Json.6.0.6\lib\net461\System.Text.Json.dll
-
-
- ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
-
-
- ..\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll
-
-
-
-
-
-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
-
-
- Dieses Projekt verweist auf mindestens ein NuGet-Paket, das auf diesem Computer fehlt. Verwenden Sie die Wiederherstellung von NuGet-Paketen, um die fehlenden Dateien herunterzuladen. Weitere Informationen finden Sie unter "http://go.microsoft.com/fwlink/?LinkID=322105". Die fehlende Datei ist "{0}".
-
-
-
-
\ No newline at end of file
+
+
diff --git a/ExeToBat/Generator.cs b/ExeToBat/Generator.cs
index 01b8740..ee361f4 100644
--- a/ExeToBat/Generator.cs
+++ b/ExeToBat/Generator.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.Json;
+using System.Text.Json;
namespace ExeToBat
{
@@ -17,7 +13,7 @@ namespace ExeToBat
public const int ChunkSize = 8000;
- public List Sources = new List();
+ public List Sources = new();
public class SourceFile
{
@@ -64,7 +60,8 @@ namespace ExeToBat
public static GeneratorConfig FromJson(string raw)
{
- return JsonSerializer.Deserialize(raw);
+ return JsonSerializer.Deserialize(raw)
+ ?? new GeneratorConfig(new());
}
}
@@ -89,11 +86,11 @@ namespace ExeToBat
///
/// Sends progress updates about ongoing generation task.
///
- public event EventHandler Generation;
+ public event EventHandler? Generation;
protected virtual void OnGeneration(GeneratorEvent e)
{
- EventHandler handler = Generation;
+ EventHandler? handler = Generation;
handler?.Invoke(this, e);
}
@@ -105,94 +102,92 @@ namespace ExeToBat
{
if (Sources.Any())
{
- using (StreamWriter writer = new StreamWriter(outputFile))
+ using StreamWriter writer = new(outputFile);
+ OnGeneration(new GenerationStartEvent(Sources));
+ writer.WriteLine("@echo off");
+ writer.WriteLine(":: Auto-generated batch file by ExeToBat ::");
+ writer.WriteLine("");
+
+ foreach (SourceFile source in Sources)
{
- OnGeneration(new GenerationStartEvent(Sources));
- writer.WriteLine("@echo off");
- writer.WriteLine(":: Auto-generated batch file by ExeToBat ::");
- writer.WriteLine("");
+ OnGeneration(new ReadingFileEvent(source));
+ List fileChunks = Convert
+ .ToBase64String(File.ReadAllBytes(source.Path))
+ .Chunks(ChunkSize)
+ .ToList();
+ string tempFile = Path.Combine("%temp%", source.Resource);
+ writer.WriteLine("(");
- foreach (SourceFile source in Sources)
+ int pos = 0;
+ foreach (string part in fileChunks)
{
- OnGeneration(new ReadingFileEvent(source));
- List fileChunks = Convert
- .ToBase64String(File.ReadAllBytes(source.Path))
- .Chunks(ChunkSize)
- .ToList();
- string tempFile = Path.Combine("%temp%", source.Resource);
- writer.WriteLine("(");
-
- int pos = 0;
- foreach (string part in fileChunks)
- {
- pos++;
- OnGeneration(new WritingFilePartEvent(source, pos, fileChunks.Count));
- writer.WriteLine(string.Format("echo {0}", part));
- }
-
- writer.WriteLine(string.Format(") >> \"{0}\"", tempFile));
- writer.WriteLine("");
-
- OnGeneration(new WritingFileDecoderEvent(source));
- writer.WriteLine(
- string.Format(
- "certutil -decode \"{0}\" \"{1}\" >nul 2>&1",
- tempFile,
- Path.Combine(source.Directory, Path.GetFileName(source.Path))
- )
- );
- writer.WriteLine(string.Format("del /f /q \"{0}\" >nul 2>&1", tempFile));
- writer.WriteLine("");
-
- if (source.Execute)
- {
- string wait;
- if (source.Wait)
- {
- wait = " /wait";
- }
- else
- {
- wait = " ";
- }
-
- OnGeneration(new WritingFileExecuteEvent(source));
- writer.WriteLine(
- string.Format(
- "start{0} \"\" \"cmd /c {1}\" {2}",
- wait,
- Path.Combine(source.Directory, Path.GetFileName(source.Path)),
- source.Parameters
- )
- );
- if (source.Wait)
- {
- OnGeneration(new WritingFileWaitEvent(source));
- if (source.Delete)
- {
- OnGeneration(new WritingFileDeleteEvent(source));
- writer.WriteLine(
- string.Format(
- "del /f /q \"{0}\" >nul 2>&1",
- Path.Combine(
- source.Directory,
- Path.GetFileName(source.Path)
- )
- )
- );
- writer.WriteLine("");
- }
- }
-
- writer.WriteLine("");
- }
-
- writer.Flush();
- OnGeneration(new WritingFileCompleteEvent(source));
+ pos++;
+ OnGeneration(new WritingFilePartEvent(source, pos, fileChunks.Count));
+ writer.WriteLine(string.Format("echo {0}", part));
}
- OnGeneration(new GenerationCompleteEvent(outputFile));
+ writer.WriteLine(string.Format(") >> \"{0}\"", tempFile));
+ writer.WriteLine("");
+
+ OnGeneration(new WritingFileDecoderEvent(source));
+ writer.WriteLine(
+ string.Format(
+ "certutil -decode \"{0}\" \"{1}\" >nul 2>&1",
+ tempFile,
+ Path.Combine(source.Directory, Path.GetFileName(source.Path))
+ )
+ );
+ writer.WriteLine(string.Format("del /f /q \"{0}\" >nul 2>&1", tempFile));
+ writer.WriteLine("");
+
+ if (source.Execute)
+ {
+ string wait;
+ if (source.Wait)
+ {
+ wait = " /wait";
+ }
+ else
+ {
+ wait = " ";
+ }
+
+ OnGeneration(new WritingFileExecuteEvent(source));
+ writer.WriteLine(
+ string.Format(
+ "start{0} \"\" \"cmd /c {1}\" {2}",
+ wait,
+ Path.Combine(source.Directory, Path.GetFileName(source.Path)),
+ source.Parameters
+ )
+ );
+ if (source.Wait)
+ {
+ OnGeneration(new WritingFileWaitEvent(source));
+ if (source.Delete)
+ {
+ OnGeneration(new WritingFileDeleteEvent(source));
+ writer.WriteLine(
+ string.Format(
+ "del /f /q \"{0}\" >nul 2>&1",
+ Path.Combine(
+ source.Directory,
+ Path.GetFileName(source.Path)
+ )
+ )
+ );
+ writer.WriteLine("");
+ }
+ }
+
+ writer.WriteLine("");
+ }
+
+ writer.Flush();
+ OnGeneration(new WritingFileCompleteEvent(source));
}
+
+ OnGeneration(new GenerationCompleteEvent(outputFile));
}
else
{
@@ -204,7 +199,12 @@ namespace ExeToBat
public abstract class GeneratorFileEvent : GeneratorEvent
{
- public SourceFile File { get; protected set; }
+ public GeneratorFileEvent(SourceFile file)
+ {
+ File = file;
+ }
+
+ public SourceFile File { get; private set; }
}
public class GenerationStartEvent : GeneratorEvent
@@ -219,17 +219,13 @@ namespace ExeToBat
public class ReadingFileEvent : GeneratorFileEvent
{
- public ReadingFileEvent(SourceFile file)
- {
- File = file;
- }
+ public ReadingFileEvent(SourceFile file) : base(file) { }
}
public class WritingFilePartEvent : GeneratorFileEvent
{
- public WritingFilePartEvent(SourceFile file, int part, int max)
+ public WritingFilePartEvent(SourceFile file, int part, int max) : base(file)
{
- File = file;
Part = part;
Max = max;
}
@@ -240,42 +236,27 @@ namespace ExeToBat
public class WritingFileDecoderEvent : GeneratorFileEvent
{
- public WritingFileDecoderEvent(SourceFile file)
- {
- File = file;
- }
+ public WritingFileDecoderEvent(SourceFile file) : base(file) { }
}
public class WritingFileExecuteEvent : GeneratorFileEvent
{
- public WritingFileExecuteEvent(SourceFile file)
- {
- File = file;
- }
+ public WritingFileExecuteEvent(SourceFile file) : base(file) { }
}
public class WritingFileWaitEvent : GeneratorFileEvent
{
- public WritingFileWaitEvent(SourceFile file)
- {
- File = file;
- }
+ public WritingFileWaitEvent(SourceFile file) : base(file) { }
}
public class WritingFileDeleteEvent : GeneratorFileEvent
{
- public WritingFileDeleteEvent(SourceFile file)
- {
- File = file;
- }
+ public WritingFileDeleteEvent(SourceFile file) : base(file) { }
}
public class WritingFileCompleteEvent : GeneratorFileEvent
{
- public WritingFileCompleteEvent(SourceFile file)
- {
- File = file;
- }
+ public WritingFileCompleteEvent(SourceFile file) : base(file) { }
}
public class GenerationCompleteEvent : GeneratorEvent
diff --git a/ExeToBat/Properties/AssemblyInfo.cs b/ExeToBat/Properties/AssemblyInfo.cs
deleted file mode 100644
index 6af03c8..0000000
--- a/ExeToBat/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// Allgemeine Informationen über eine Assembly werden über die folgenden
-// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
-// die einer Assembly zugeordnet sind.
-[assembly: AssemblyTitle("ExeToBat")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ExeToBat")]
-[assembly: AssemblyCopyright("Copyright © 2018")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
-// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
-// COM aus zugreifen müssen, sollten Sie das ComVisible-Attribut für diesen Typ auf "True" festlegen.
-[assembly: ComVisible(false)]
-
-// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
-[assembly: Guid("04f45237-23c8-4ee6-b61c-6c47b9979a4b")]
-
-// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
-//
-// Hauptversion
-// Nebenversion
-// Buildnummer
-// Revision
-//
-// Sie können alle Werte angeben oder Standardwerte für die Build- und Revisionsnummern verwenden,
-// übernehmen, indem Sie "*" eingeben:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/ExeToBat/packages.config b/ExeToBat/packages.config
deleted file mode 100644
index eae92fd..0000000
--- a/ExeToBat/packages.config
+++ /dev/null
@@ -1,13 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file