From c318a92c20ec5fa5b44d1f1a6837108b8cca3c9f Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Fri, 1 Apr 2022 20:52:04 +0200
Subject: [PATCH 01/67] re #9437 initial lauterbach debugger client structure
 setup

---
 ld_client/LDClient/LDClient.csproj           | 20 +++++++++++++
 ld_client/LDClient/Program.cs                | 11 +++++++
 ld_client/LDClientTests/LDClientTests.csproj | 17 +++++++++++
 ld_client/LDClientTests/UnitTest1.cs         | 15 ++++++++++
 ld_client/LauterbachDebuggerClient.sln       | 31 ++++++++++++++++++++
 5 files changed, 94 insertions(+)
 create mode 100644 ld_client/LDClient/LDClient.csproj
 create mode 100644 ld_client/LDClient/Program.cs
 create mode 100644 ld_client/LDClientTests/LDClientTests.csproj
 create mode 100644 ld_client/LDClientTests/UnitTest1.cs
 create mode 100644 ld_client/LauterbachDebuggerClient.sln

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
new file mode 100644
index 0000000..9b3c77f
--- /dev/null
+++ b/ld_client/LDClient/LDClient.csproj
@@ -0,0 +1,20 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>net6.0</TargetFramework>
+    <ImplicitUsings>enable</ImplicitUsings>
+    <Nullable>enable</Nullable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <Reference Include="t32apinet">
+      <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath>
+    </Reference>
+  </ItemGroup>
+
+  <ItemGroup>
+    <Folder Include="NewFolder\" />
+  </ItemGroup>
+
+</Project>
diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
new file mode 100644
index 0000000..22069e5
--- /dev/null
+++ b/ld_client/LDClient/Program.cs
@@ -0,0 +1,11 @@
+using System;
+
+
+class Program {
+
+    // Main Method
+    static public void Main() {
+
+        Console.WriteLine("Main Method");
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj
new file mode 100644
index 0000000..5085235
--- /dev/null
+++ b/ld_client/LDClientTests/LDClientTests.csproj
@@ -0,0 +1,17 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <TargetFramework>net6.0</TargetFramework>
+    <Nullable>enable</Nullable>
+
+    <IsPackable>false</IsPackable>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
+    <PackageReference Include="NUnit" Version="3.13.2" />
+    <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
+    <PackageReference Include="coverlet.collector" Version="3.1.0" />
+  </ItemGroup>
+
+</Project>
diff --git a/ld_client/LDClientTests/UnitTest1.cs b/ld_client/LDClientTests/UnitTest1.cs
new file mode 100644
index 0000000..03cf433
--- /dev/null
+++ b/ld_client/LDClientTests/UnitTest1.cs
@@ -0,0 +1,15 @@
+using NUnit.Framework;
+
+namespace LDClientTests {
+    public class Tests {
+        [SetUp]
+        public void Setup() {
+
+        }
+
+        [Test]
+        public void Test1() {
+            Assert.Pass();
+        }
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln
new file mode 100644
index 0000000..d62277c
--- /dev/null
+++ b/ld_client/LauterbachDebuggerClient.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.1.32210.238
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{26616C14-A61B-4611-8CD0-D29837FA34E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{26616C14-A61B-4611-8CD0-D29837FA34E7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{26616C14-A61B-4611-8CD0-D29837FA34E7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{26616C14-A61B-4611-8CD0-D29837FA34E7}.Release|Any CPU.Build.0 = Release|Any CPU
+		{5A1DB888-70E5-41E8-A900-FC22B51727F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{5A1DB888-70E5-41E8-A900-FC22B51727F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{5A1DB888-70E5-41E8-A900-FC22B51727F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{5A1DB888-70E5-41E8-A900-FC22B51727F8}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {189367A8-6FB6-4C6C-85EF-FEA949122C26}
+	EndGlobalSection
+EndGlobal
-- 
GitLab


From db562f60458ab53733eb190e590dec2f1c7065a8 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 2 Apr 2022 01:27:27 +0200
Subject: [PATCH 02/67] re #9440 initial config manager definition

---
 ld_client/LDClient/LDClient.csproj       | 13 ++++-
 ld_client/LDClient/appsettings.json      | 17 ++++++
 ld_client/LDClient/utils/ConfigLoader.cs | 72 ++++++++++++++++++++++++
 ld_client/LauterbachDebuggerClient.sln   |  2 +-
 4 files changed, 102 insertions(+), 2 deletions(-)
 create mode 100644 ld_client/LDClient/appsettings.json
 create mode 100644 ld_client/LDClient/utils/ConfigLoader.cs

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
index 9b3c77f..3db4860 100644
--- a/ld_client/LDClient/LDClient.csproj
+++ b/ld_client/LDClient/LDClient.csproj
@@ -7,6 +7,16 @@
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
+  <ItemGroup>
+    <None Remove="appsettings.json" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="appsettings.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </EmbeddedResource>
+  </ItemGroup>
+
   <ItemGroup>
     <Reference Include="t32apinet">
       <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath>
@@ -14,7 +24,8 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Folder Include="NewFolder\" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
+    <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
   </ItemGroup>
 
 </Project>
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
new file mode 100644
index 0000000..505db61
--- /dev/null
+++ b/ld_client/LDClient/appsettings.json
@@ -0,0 +1,17 @@
+{
+  "Logging": {
+    "ColorConsole": {
+      "LogLevels": {
+        "Information": "DarkGreen",
+        "Warning": "Cyan",
+        "Error": "Red"
+      }
+    },
+    "LogChunkSize": 1000,
+    "LogChunkMaxCount": 1,
+    "LogArchiveMaxCount": 1,
+    "LogCleanupPeriod": 1000,
+    "LogVerbosityType": 2,
+    "LogFlowType": 1
+  }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
new file mode 100644
index 0000000..d6502ac
--- /dev/null
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Json;
+
+namespace LDClient {
+    internal class ConfigurationLoader {
+
+        private readonly string LOGGING_SECTION = "Logging";
+
+
+        public int LogChunkSize { get; set; }
+        public int LogChunkMaxCount { get; set; }
+        public int LogArchiveMaxCount { get; set; }
+
+        public int LogCleanupPeriod { get; set; }
+
+        private LogVerbosity _logVerbosity = LogVerbosity.Full;
+        public LogVerbosity LogVerbosityType {
+            get {
+                return _logVerbosity;
+            } 
+            set 
+                { _logVerbosity = value; 
+            } 
+        }
+
+        private LogFlow _logFlowType = LogFlow.Console;
+        public LogFlow LogFlowType { 
+            get {
+                return _logFlowType;
+            } 
+            set {
+                _logFlowType = value;
+            } 
+        }
+
+        public ConfigurationLoader() {
+            var configuration = new ConfigurationBuilder()
+                .AddJsonFile("appsettings.json")
+                .Build();
+            ReadAllSettings(configuration);
+        }
+
+        void ReadAllSettings(IConfigurationRoot configuration) {
+
+            try {
+                var logging = configuration.GetSection(LOGGING_SECTION);
+                //TODO: Exception handling
+                LogChunkSize = Int32.Parse(logging["LogChunkSize"]);
+                LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]);
+                LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]);
+                LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]);
+                LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]);
+                LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]);
+
+
+                Console.WriteLine("Configuration successfully loaded!");
+            } catch (FormatException e) {
+                //Console.WriteLine("Error reading app settings");
+                //TODO: remove stacktrace print in production
+                Console.WriteLine("Error during reading of configuration occured!" + e);
+                throw new IOException("Reading of configuration file failed! " + e);
+            }
+        }
+
+    }
+}
diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln
index d62277c..6e2f143 100644
--- a/ld_client/LauterbachDebuggerClient.sln
+++ b/ld_client/LauterbachDebuggerClient.sln
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.1.32210.238
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-- 
GitLab


From 715205760dd3f78b9f7056f92f1d102cc6f736c6 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 2 Apr 2022 15:07:38 +0200
Subject: [PATCH 03/67] re #9439 Implementation of console and rotating file
 logger

---
 ld_client/LDClient/Program.cs      |  12 +-
 ld_client/LDClient/utils/Logger.cs | 225 +++++++++++++++++++++++++++++
 2 files changed, 235 insertions(+), 2 deletions(-)
 create mode 100644 ld_client/LDClient/utils/Logger.cs

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 22069e5..2d372d9 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,11 +1,19 @@
-using System;
+using LDClient;
+using System;
 
 
 class Program {
 
+    public static LDClient.ConfigLoader Config { get; set; }
+
     // Main Method
     static public void Main() {
+        Config = new LDClient.ConfigLoader();
 
-        Console.WriteLine("Main Method");
+        while (true) {
+            Logger.Current.Info("Ok");
+            Logger.Current.Debug("Debug");
+            Logger.Current.Error("Error");
+        }
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/Logger.cs b/ld_client/LDClient/utils/Logger.cs
new file mode 100644
index 0000000..aaf0ea1
--- /dev/null
+++ b/ld_client/LDClient/utils/Logger.cs
@@ -0,0 +1,225 @@
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO.Compression;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient {
+    enum LogVerbosity {
+        None = 0,
+        Exceptions,
+        Full
+    }
+
+    public enum LogType {
+        Info = 0,
+        Debug,
+        Error
+    }
+
+    enum LogFlow {
+        Console = 0,
+        File
+    }
+
+
+    public abstract class Logger : IDisposable {
+
+        private LogVerbosity _verbosity;
+        private LogFlow _logFlow;
+
+        private Queue<Action> _queue = new Queue<Action>();
+        private ManualResetEvent _hasNewItems = new ManualResetEvent(false);
+        private ManualResetEvent _terminate = new ManualResetEvent(false);
+        private ManualResetEvent _waiting = new ManualResetEvent(false);
+        private Thread _loggingThread;
+
+        private static readonly Lazy<Logger> _lazyLog = new Lazy<Logger>(()
+            => {
+                switch (Program.Config.LogFlowType) {
+                    case LogFlow.File:
+                        return new FileLogger();
+                    case LogFlow.Console:
+                    default:
+                        return new ConsoleLogger();
+
+                }
+            }
+        );
+
+        public static Logger Current => _lazyLog.Value;
+
+        protected Logger() {
+            _verbosity = (LogVerbosity)Program.Config.LogVerbosityType;
+            _logFlow = (LogFlow)Program.Config.LogFlowType;
+            _loggingThread = new Thread(new ThreadStart(ProcessQueue)) { IsBackground = true };
+            _loggingThread.Start();
+        }
+
+        public void Info(string message) {
+            Log(message, LogType.Info);
+        }
+
+        public void Debug(string message) {
+            Log(message, LogType.Debug);
+        }
+
+        public void Error(string message) {
+            Log(message, LogType.Error);
+        }
+
+        public void Error(Exception e) {
+            if (_verbosity != LogVerbosity.None) {
+                Log(UnwrapExceptionMessages(e), LogType.Error);
+            }
+        }
+
+        public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, ";
+
+        protected abstract void CreateLog(string message);
+
+        public void Flush() => _waiting.WaitOne();
+
+        public void Dispose() {
+            _terminate.Set();
+            _loggingThread.Join();
+        }
+
+        protected virtual string ComposeLogRow(string message, LogType logType) =>
+            $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}";
+
+        protected virtual string UnwrapExceptionMessages(Exception ex) {
+            if (ex == null)
+                return string.Empty;
+
+            return $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";
+        }
+
+        private void ProcessQueue() {
+            while (true) {
+                _waiting.Set();
+                int i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });
+                if (i == 1) return;
+                _hasNewItems.Reset();
+                _waiting.Reset();
+
+                Queue<Action> queueCopy;
+                lock (_queue) {
+                    queueCopy = new Queue<Action>(_queue);
+                    _queue.Clear();
+                }
+
+                foreach (var log in queueCopy) {
+                    log();
+                }
+            }
+        }
+
+        private void Log(string message, LogType logType) {
+            if (string.IsNullOrEmpty(message))
+                return;
+
+            var logRow = ComposeLogRow(message, logType);
+            System.Diagnostics.Debug.WriteLine(logRow);
+
+            if (_verbosity == LogVerbosity.Full) {
+                lock (_queue)
+                    _queue.Enqueue(() => CreateLog(logRow));
+
+                _hasNewItems.Set();
+            }
+        }
+    }
+
+    class ConsoleLogger : Logger {
+        protected override void CreateLog(string message) {
+            Console.WriteLine(message);
+        }
+    }
+
+
+    class FileLogger : Logger {
+
+        private const string LogFolderName = "logs";
+        private const string LogFileName = "app_info.log";
+        private readonly int _logChunkSize = Program.Config.LogChunkSize;
+        private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount;
+        private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount;
+        private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod;
+
+        private readonly string logFolderPath = Path.Combine(Path.GetTempPath(), $"ldClient\\{LogFolderName}");
+
+        private bool _logDirExists = false;
+
+        protected override void CreateLog(string message) {
+
+            if (!_logDirExists) {
+                _logDirExists = Directory.Exists(logFolderPath);
+                if (!_logDirExists) {
+                    Directory.CreateDirectory(logFolderPath);
+                    _logDirExists = true;
+                }
+            }
+
+            var logFilePath = Path.Combine(logFolderPath, LogFileName);
+
+            Rotate(logFilePath);
+
+            using (var sw = File.AppendText(logFilePath)) {
+                sw.WriteLine(message);
+            }
+        }
+
+        private void Rotate(string filePath) {
+            if (!File.Exists(filePath))
+                return;
+
+            var fileInfo = new FileInfo(filePath);
+            if (fileInfo.Length < _logChunkSize)
+                return;
+
+            var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff");
+            var rotatedPath = filePath.Replace(".log", $".{fileTime}");
+            File.Move(filePath, rotatedPath);
+
+            var folderPath = Path.GetDirectoryName(rotatedPath);
+            var logFolderContent = new DirectoryInfo(folderPath).GetFileSystemInfos();
+
+            var chunks = logFolderContent.Where(x => !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase));
+
+            if (chunks.Count() <= _logChunkMaxCount)
+                return;
+
+            var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath), $"{LogFolderName}_{fileTime}"));
+
+            foreach (var chunk in chunks) {
+                var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name);
+                Directory.Move(chunk.FullName, destination);
+            }
+
+            ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath, $"{LogFolderName}_{fileTime}.zip"));
+            Directory.Delete(archiveFolderInfo.FullName, true);
+
+            var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray();
+
+            if (archives.Count() <= _logArchiveMaxCount)
+                return;
+
+            var oldestArchive = archives.OrderBy(x => x.CreationTime).First();
+            var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod);
+            if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) {
+                foreach (var file in logFolderContent) {
+                    file.Delete();
+                }
+            } else
+                File.Delete(oldestArchive.FullName);
+
+        }
+
+        public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]";
+    }
+
+
+}
-- 
GitLab


From d0cf94768067a25abd98e78c3775d418c154774e Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 2 Apr 2022 01:27:27 +0200
Subject: [PATCH 04/67] re #9440 initial config manager definition

---
 ld_client/LDClient/LDClient.csproj       | 13 ++++-
 ld_client/LDClient/appsettings.json      | 17 ++++++
 ld_client/LDClient/utils/ConfigLoader.cs | 72 ++++++++++++++++++++++++
 ld_client/LauterbachDebuggerClient.sln   |  2 +-
 4 files changed, 102 insertions(+), 2 deletions(-)
 create mode 100644 ld_client/LDClient/appsettings.json
 create mode 100644 ld_client/LDClient/utils/ConfigLoader.cs

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
index 9b3c77f..3db4860 100644
--- a/ld_client/LDClient/LDClient.csproj
+++ b/ld_client/LDClient/LDClient.csproj
@@ -7,6 +7,16 @@
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
+  <ItemGroup>
+    <None Remove="appsettings.json" />
+  </ItemGroup>
+
+  <ItemGroup>
+    <EmbeddedResource Include="appsettings.json">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </EmbeddedResource>
+  </ItemGroup>
+
   <ItemGroup>
     <Reference Include="t32apinet">
       <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath>
@@ -14,7 +24,8 @@
   </ItemGroup>
 
   <ItemGroup>
-    <Folder Include="NewFolder\" />
+    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
+    <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
   </ItemGroup>
 
 </Project>
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
new file mode 100644
index 0000000..505db61
--- /dev/null
+++ b/ld_client/LDClient/appsettings.json
@@ -0,0 +1,17 @@
+{
+  "Logging": {
+    "ColorConsole": {
+      "LogLevels": {
+        "Information": "DarkGreen",
+        "Warning": "Cyan",
+        "Error": "Red"
+      }
+    },
+    "LogChunkSize": 1000,
+    "LogChunkMaxCount": 1,
+    "LogArchiveMaxCount": 1,
+    "LogCleanupPeriod": 1000,
+    "LogVerbosityType": 2,
+    "LogFlowType": 1
+  }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
new file mode 100644
index 0000000..d6502ac
--- /dev/null
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.Configuration.Json;
+
+namespace LDClient {
+    internal class ConfigurationLoader {
+
+        private readonly string LOGGING_SECTION = "Logging";
+
+
+        public int LogChunkSize { get; set; }
+        public int LogChunkMaxCount { get; set; }
+        public int LogArchiveMaxCount { get; set; }
+
+        public int LogCleanupPeriod { get; set; }
+
+        private LogVerbosity _logVerbosity = LogVerbosity.Full;
+        public LogVerbosity LogVerbosityType {
+            get {
+                return _logVerbosity;
+            } 
+            set 
+                { _logVerbosity = value; 
+            } 
+        }
+
+        private LogFlow _logFlowType = LogFlow.Console;
+        public LogFlow LogFlowType { 
+            get {
+                return _logFlowType;
+            } 
+            set {
+                _logFlowType = value;
+            } 
+        }
+
+        public ConfigurationLoader() {
+            var configuration = new ConfigurationBuilder()
+                .AddJsonFile("appsettings.json")
+                .Build();
+            ReadAllSettings(configuration);
+        }
+
+        void ReadAllSettings(IConfigurationRoot configuration) {
+
+            try {
+                var logging = configuration.GetSection(LOGGING_SECTION);
+                //TODO: Exception handling
+                LogChunkSize = Int32.Parse(logging["LogChunkSize"]);
+                LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]);
+                LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]);
+                LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]);
+                LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]);
+                LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]);
+
+
+                Console.WriteLine("Configuration successfully loaded!");
+            } catch (FormatException e) {
+                //Console.WriteLine("Error reading app settings");
+                //TODO: remove stacktrace print in production
+                Console.WriteLine("Error during reading of configuration occured!" + e);
+                throw new IOException("Reading of configuration file failed! " + e);
+            }
+        }
+
+    }
+}
diff --git a/ld_client/LauterbachDebuggerClient.sln b/ld_client/LauterbachDebuggerClient.sln
index d62277c..6e2f143 100644
--- a/ld_client/LauterbachDebuggerClient.sln
+++ b/ld_client/LauterbachDebuggerClient.sln
@@ -5,7 +5,7 @@ VisualStudioVersion = 17.1.32210.238
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClient", "LDClient\LDClient.csproj", "{26616C14-A61B-4611-8CD0-D29837FA34E7}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LDClientTests", "LDClientTests\LDClientTests.csproj", "{5A1DB888-70E5-41E8-A900-FC22B51727F8}"
 EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
-- 
GitLab


From 74bd1e40820cf9bf2c808f4946a0dec8f2013d0c Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 2 Apr 2022 18:19:27 +0200
Subject: [PATCH 05/67] re #9439 logger code refactoring

---
 ld_client/LDClient/Program.cs                 |  19 +-
 ld_client/LDClient/appsettings.json           |   8 +-
 ld_client/LDClient/utils/ConfigLoader.cs      |  55 ++---
 ld_client/LDClient/utils/Logger.cs            | 225 ------------------
 ld_client/LDClient/utils/loggers/ALogger.cs   | 109 +++++++++
 .../LDClient/utils/loggers/ConsoleLogger.cs   |   7 +
 .../LDClient/utils/loggers/FileLogger.cs      |  95 ++++++++
 ld_client/LDClient/utils/loggers/LogFlow.cs   |   6 +
 ld_client/LDClient/utils/loggers/LogType.cs   |   7 +
 .../LDClient/utils/loggers/LogVerbosity.cs    |   7 +
 10 files changed, 261 insertions(+), 277 deletions(-)
 delete mode 100644 ld_client/LDClient/utils/Logger.cs
 create mode 100644 ld_client/LDClient/utils/loggers/ALogger.cs
 create mode 100644 ld_client/LDClient/utils/loggers/ConsoleLogger.cs
 create mode 100644 ld_client/LDClient/utils/loggers/FileLogger.cs
 create mode 100644 ld_client/LDClient/utils/loggers/LogFlow.cs
 create mode 100644 ld_client/LDClient/utils/loggers/LogType.cs
 create mode 100644 ld_client/LDClient/utils/loggers/LogVerbosity.cs

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 2d372d9..4030157 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,19 +1,20 @@
-using LDClient;
-using System;
+using LDClient.utils;
+using LDClient.utils.loggers;
 
+namespace LDClient; 
 
-class Program {
+internal class Program {
 
-    public static LDClient.ConfigLoader Config { get; set; }
+    public static ConfigLoader Config { get; set; } = null!;
 
     // Main Method
-    static public void Main() {
-        Config = new LDClient.ConfigLoader();
+    public static void Main() {
+        Config = new ConfigLoader();
 
         while (true) {
-            Logger.Current.Info("Ok");
-            Logger.Current.Debug("Debug");
-            Logger.Current.Error("Error");
+            ALogger.Current.Info("Ok");
+            ALogger.Current.Debug("Debug");
+            ALogger.Current.Error("Error");
         }
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 505db61..01b0de4 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -7,10 +7,10 @@
         "Error": "Red"
       }
     },
-    "LogChunkSize": 1000,
-    "LogChunkMaxCount": 1,
-    "LogArchiveMaxCount": 1,
-    "LogCleanupPeriod": 1000,
+    "LogChunkSize": 2097152,
+    "LogChunkMaxCount": 2,
+    "LogArchiveMaxCount": 10,
+    "LogCleanupPeriod": 10,
     "LogVerbosityType": 2,
     "LogFlowType": 1
   }
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index d6502ac..8005130 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -1,16 +1,9 @@
-using System;
-using System.Collections.Generic;
-using System.Configuration;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using LDClient.utils.loggers;
 using Microsoft.Extensions.Configuration;
-using Microsoft.Extensions.Configuration.Json;
 
-namespace LDClient {
-    internal class ConfigurationLoader {
-
-        private readonly string LOGGING_SECTION = "Logging";
+namespace LDClient.utils {
+    internal class ConfigLoader {
+        private const string LoggingSection = "Logging";
 
 
         public int LogChunkSize { get; set; }
@@ -19,51 +12,35 @@ namespace LDClient {
 
         public int LogCleanupPeriod { get; set; }
 
-        private LogVerbosity _logVerbosity = LogVerbosity.Full;
-        public LogVerbosity LogVerbosityType {
-            get {
-                return _logVerbosity;
-            } 
-            set 
-                { _logVerbosity = value; 
-            } 
-        }
+        public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full;
 
-        private LogFlow _logFlowType = LogFlow.Console;
-        public LogFlow LogFlowType { 
-            get {
-                return _logFlowType;
-            } 
-            set {
-                _logFlowType = value;
-            } 
-        }
+        public LogFlow LogFlowType { get; set; } = LogFlow.Console;
 
-        public ConfigurationLoader() {
+        public ConfigLoader() {
             var configuration = new ConfigurationBuilder()
                 .AddJsonFile("appsettings.json")
                 .Build();
             ReadAllSettings(configuration);
         }
 
-        void ReadAllSettings(IConfigurationRoot configuration) {
+        private void ReadAllSettings(IConfigurationRoot configuration) {
 
             try {
-                var logging = configuration.GetSection(LOGGING_SECTION);
+                var logging = configuration.GetSection(LoggingSection);
                 //TODO: Exception handling
-                LogChunkSize = Int32.Parse(logging["LogChunkSize"]);
-                LogChunkMaxCount = Int32.Parse(logging["LogChunkMaxCount"]);
-                LogArchiveMaxCount = Int32.Parse(logging["LogArchiveMaxCount"]);
-                LogCleanupPeriod = Int32.Parse(logging["LogCleanupPeriod"]);
-                LogFlowType = (LogFlow)Int32.Parse(logging["LogFlowType"]);
-                LogVerbosityType = (LogVerbosity)Int32.Parse(logging["LogVerbosityType"]);
+                LogChunkSize = int.Parse(logging["LogChunkSize"]);
+                LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]);
+                LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]);
+                LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);
+                LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);
+                LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);
 
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
                 //Console.WriteLine("Error reading app settings");
                 //TODO: remove stacktrace print in production
-                Console.WriteLine("Error during reading of configuration occured!" + e);
+                Console.WriteLine("Error during reading of configuration occurred!" + e);
                 throw new IOException("Reading of configuration file failed! " + e);
             }
         }
diff --git a/ld_client/LDClient/utils/Logger.cs b/ld_client/LDClient/utils/Logger.cs
deleted file mode 100644
index aaf0ea1..0000000
--- a/ld_client/LDClient/utils/Logger.cs
+++ /dev/null
@@ -1,225 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO.Compression;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LDClient {
-    enum LogVerbosity {
-        None = 0,
-        Exceptions,
-        Full
-    }
-
-    public enum LogType {
-        Info = 0,
-        Debug,
-        Error
-    }
-
-    enum LogFlow {
-        Console = 0,
-        File
-    }
-
-
-    public abstract class Logger : IDisposable {
-
-        private LogVerbosity _verbosity;
-        private LogFlow _logFlow;
-
-        private Queue<Action> _queue = new Queue<Action>();
-        private ManualResetEvent _hasNewItems = new ManualResetEvent(false);
-        private ManualResetEvent _terminate = new ManualResetEvent(false);
-        private ManualResetEvent _waiting = new ManualResetEvent(false);
-        private Thread _loggingThread;
-
-        private static readonly Lazy<Logger> _lazyLog = new Lazy<Logger>(()
-            => {
-                switch (Program.Config.LogFlowType) {
-                    case LogFlow.File:
-                        return new FileLogger();
-                    case LogFlow.Console:
-                    default:
-                        return new ConsoleLogger();
-
-                }
-            }
-        );
-
-        public static Logger Current => _lazyLog.Value;
-
-        protected Logger() {
-            _verbosity = (LogVerbosity)Program.Config.LogVerbosityType;
-            _logFlow = (LogFlow)Program.Config.LogFlowType;
-            _loggingThread = new Thread(new ThreadStart(ProcessQueue)) { IsBackground = true };
-            _loggingThread.Start();
-        }
-
-        public void Info(string message) {
-            Log(message, LogType.Info);
-        }
-
-        public void Debug(string message) {
-            Log(message, LogType.Debug);
-        }
-
-        public void Error(string message) {
-            Log(message, LogType.Error);
-        }
-
-        public void Error(Exception e) {
-            if (_verbosity != LogVerbosity.None) {
-                Log(UnwrapExceptionMessages(e), LogType.Error);
-            }
-        }
-
-        public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, ";
-
-        protected abstract void CreateLog(string message);
-
-        public void Flush() => _waiting.WaitOne();
-
-        public void Dispose() {
-            _terminate.Set();
-            _loggingThread.Join();
-        }
-
-        protected virtual string ComposeLogRow(string message, LogType logType) =>
-            $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}";
-
-        protected virtual string UnwrapExceptionMessages(Exception ex) {
-            if (ex == null)
-                return string.Empty;
-
-            return $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";
-        }
-
-        private void ProcessQueue() {
-            while (true) {
-                _waiting.Set();
-                int i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });
-                if (i == 1) return;
-                _hasNewItems.Reset();
-                _waiting.Reset();
-
-                Queue<Action> queueCopy;
-                lock (_queue) {
-                    queueCopy = new Queue<Action>(_queue);
-                    _queue.Clear();
-                }
-
-                foreach (var log in queueCopy) {
-                    log();
-                }
-            }
-        }
-
-        private void Log(string message, LogType logType) {
-            if (string.IsNullOrEmpty(message))
-                return;
-
-            var logRow = ComposeLogRow(message, logType);
-            System.Diagnostics.Debug.WriteLine(logRow);
-
-            if (_verbosity == LogVerbosity.Full) {
-                lock (_queue)
-                    _queue.Enqueue(() => CreateLog(logRow));
-
-                _hasNewItems.Set();
-            }
-        }
-    }
-
-    class ConsoleLogger : Logger {
-        protected override void CreateLog(string message) {
-            Console.WriteLine(message);
-        }
-    }
-
-
-    class FileLogger : Logger {
-
-        private const string LogFolderName = "logs";
-        private const string LogFileName = "app_info.log";
-        private readonly int _logChunkSize = Program.Config.LogChunkSize;
-        private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount;
-        private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount;
-        private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod;
-
-        private readonly string logFolderPath = Path.Combine(Path.GetTempPath(), $"ldClient\\{LogFolderName}");
-
-        private bool _logDirExists = false;
-
-        protected override void CreateLog(string message) {
-
-            if (!_logDirExists) {
-                _logDirExists = Directory.Exists(logFolderPath);
-                if (!_logDirExists) {
-                    Directory.CreateDirectory(logFolderPath);
-                    _logDirExists = true;
-                }
-            }
-
-            var logFilePath = Path.Combine(logFolderPath, LogFileName);
-
-            Rotate(logFilePath);
-
-            using (var sw = File.AppendText(logFilePath)) {
-                sw.WriteLine(message);
-            }
-        }
-
-        private void Rotate(string filePath) {
-            if (!File.Exists(filePath))
-                return;
-
-            var fileInfo = new FileInfo(filePath);
-            if (fileInfo.Length < _logChunkSize)
-                return;
-
-            var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff");
-            var rotatedPath = filePath.Replace(".log", $".{fileTime}");
-            File.Move(filePath, rotatedPath);
-
-            var folderPath = Path.GetDirectoryName(rotatedPath);
-            var logFolderContent = new DirectoryInfo(folderPath).GetFileSystemInfos();
-
-            var chunks = logFolderContent.Where(x => !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase));
-
-            if (chunks.Count() <= _logChunkMaxCount)
-                return;
-
-            var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath), $"{LogFolderName}_{fileTime}"));
-
-            foreach (var chunk in chunks) {
-                var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name);
-                Directory.Move(chunk.FullName, destination);
-            }
-
-            ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath, $"{LogFolderName}_{fileTime}.zip"));
-            Directory.Delete(archiveFolderInfo.FullName, true);
-
-            var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray();
-
-            if (archives.Count() <= _logArchiveMaxCount)
-                return;
-
-            var oldestArchive = archives.OrderBy(x => x.CreationTime).First();
-            var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod);
-            if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) {
-                foreach (var file in logFolderContent) {
-                    file.Delete();
-                }
-            } else
-                File.Delete(oldestArchive.FullName);
-
-        }
-
-        public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]";
-    }
-
-
-}
diff --git a/ld_client/LDClient/utils/loggers/ALogger.cs b/ld_client/LDClient/utils/loggers/ALogger.cs
new file mode 100644
index 0000000..260a03d
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/ALogger.cs
@@ -0,0 +1,109 @@
+using System.Globalization;
+
+namespace LDClient.utils.loggers {
+
+    public abstract class ALogger : IDisposable {
+
+        private readonly LogVerbosity _verbosity;
+        private readonly LogFlow _logFlow;
+
+        private readonly Queue<Action> _queue = new();
+        private readonly ManualResetEvent _hasNewItems = new(false);
+        private readonly ManualResetEvent _terminate = new(false);
+        private readonly ManualResetEvent _waiting = new(false);
+        private readonly Thread _loggingThread;
+
+        private static readonly Lazy<ALogger> LazyLog = new(()
+            => {
+                switch (Program.Config.LogFlowType) {
+                    case LogFlow.File:
+                        return new FileLogger();
+                    case LogFlow.Console:
+                    default:
+                        return new ConsoleLogger();
+
+                }
+            }
+        );
+
+        public static ALogger Current => LazyLog.Value;
+
+        protected ALogger() {
+            _verbosity = Program.Config.LogVerbosityType;
+            _logFlow = Program.Config.LogFlowType;
+            _loggingThread = new Thread(ProcessQueue) { IsBackground = true };
+            _loggingThread.Start();
+        }
+
+        public void Info(string message) {
+            Log(message, LogType.Info);
+        }
+
+        public void Debug(string message) {
+            Log(message, LogType.Debug);
+        }
+
+        public void Error(string message) {
+            Log(message, LogType.Error);
+        }
+
+        public void Error(Exception e) {
+            if (_verbosity != LogVerbosity.None) {
+                Log(UnwrapExceptionMessages(e), LogType.Error);
+            }
+        }
+
+        public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, ";
+
+        protected abstract void CreateLog(string message);
+
+        public void Flush() => _waiting.WaitOne();
+
+        public void Dispose() {
+            _terminate.Set();
+            _loggingThread.Join();
+        }
+
+        protected virtual string ComposeLogRow(string message, LogType logType) =>
+            $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}";
+
+        protected virtual string UnwrapExceptionMessages(Exception? ex) =>
+            ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";
+        
+
+        private void ProcessQueue() {
+            while (true) {
+                _waiting.Set();
+                var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });
+                if (i == 1) return;
+                _hasNewItems.Reset();
+                _waiting.Reset();
+
+                Queue<Action> queueCopy;
+                lock (_queue) {
+                    queueCopy = new Queue<Action>(_queue);
+                    _queue.Clear();
+                }
+
+                foreach (var log in queueCopy) {
+                    log();
+                }
+            }
+        }
+
+        private void Log(string message, LogType logType) {
+            if (string.IsNullOrEmpty(message))
+                return;
+
+            var logRow = ComposeLogRow(message, logType);
+            System.Diagnostics.Debug.WriteLine(logRow);
+
+            if (_verbosity == LogVerbosity.Full) {
+                lock (_queue)
+                    _queue.Enqueue(() => CreateLog(logRow));
+
+                _hasNewItems.Set();
+            }
+        }
+    }
+}
diff --git a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs
new file mode 100644
index 0000000..b108ed6
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs
@@ -0,0 +1,7 @@
+namespace LDClient.utils.loggers {
+    public class ConsoleLogger : ALogger {
+        protected override void CreateLog(string message) {
+            Console.WriteLine(message);
+        }
+    }
+}
diff --git a/ld_client/LDClient/utils/loggers/FileLogger.cs b/ld_client/LDClient/utils/loggers/FileLogger.cs
new file mode 100644
index 0000000..d63ab05
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/FileLogger.cs
@@ -0,0 +1,95 @@
+using System.IO.Compression;
+
+namespace LDClient.utils.loggers; 
+
+public class FileLogger : ALogger {
+
+    private const string LogFolderName = "logs";
+    private const string LogFileName = "app_info.log";
+    private readonly int _logChunkSize = Program.Config.LogChunkSize;
+    private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount;
+    private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount;
+    private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod;
+
+    private const string LogFolderPath = $"ldClient\\{LogFolderName}";
+
+    private bool _logDirExists;
+
+    protected override void CreateLog(string message) {
+
+        if (!_logDirExists) {
+            _logDirExists = Directory.Exists(LogFolderPath);
+            if (!_logDirExists) {
+                Directory.CreateDirectory(LogFolderPath);
+                _logDirExists = true;
+            }
+        }
+
+        var logFilePath = Path.Combine(LogFolderPath, LogFileName);
+
+        Rotate(logFilePath);
+
+        using var sw = File.AppendText(logFilePath);
+        sw.WriteLine(message);
+    }
+
+    private void Rotate(string filePath) {
+        if (!File.Exists(filePath)) {
+            return;
+        }
+
+        var fileInfo = new FileInfo(filePath);
+        if (fileInfo.Length < _logChunkSize) {
+            return;
+        }
+        var fileTime = DateTime.Now.ToString("dd-MM-yyyy,hh-mm-ss,fff");
+        var rotatedPath = filePath.Replace(".log", $".{fileTime}");
+        File.Move(filePath, rotatedPath);
+
+        var folderPath = Path.GetDirectoryName(rotatedPath);
+        var logFolderContent = new DirectoryInfo(folderPath ?? string.Empty).GetFileSystemInfos();
+
+        var chunks = logFolderContent.Where(x => 
+            !x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase));
+
+        if (chunks.Count() <= _logChunkMaxCount) {
+            return;
+        }
+
+        Archive(chunks, rotatedPath, fileTime, folderPath);
+        DeleteOldArchives(logFolderContent);
+    }
+
+    private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) {
+
+        var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPath, $"{LogFolderName}_{fileTime}"));
+
+        foreach (var chunk in chunks) {
+            var destination = Path.Combine(archiveFolderInfo.FullName, chunk.Name);
+            Directory.Move(chunk.FullName, destination);
+        }
+
+        ZipFile.CreateFromDirectory(archiveFolderInfo.FullName, Path.Combine(folderPath ?? LogFolderPath, $"{LogFolderName}_{fileTime}.zip"));
+        Directory.Delete(archiveFolderInfo.FullName, true);
+    }
+
+    private void DeleteOldArchives(FileSystemInfo[] logFolderContent) {
+
+        var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray();
+
+        if (archives.Length <= _logArchiveMaxCount)
+            return;
+
+        var oldestArchive = archives.OrderBy(x => x.CreationTime).First();
+        var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod);
+        if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) {
+            foreach (var file in logFolderContent) {
+                file.Delete();
+            }
+        } else {
+            File.Delete(oldestArchive.FullName);
+        }
+    }
+
+    public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]";
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/loggers/LogFlow.cs b/ld_client/LDClient/utils/loggers/LogFlow.cs
new file mode 100644
index 0000000..5041b12
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/LogFlow.cs
@@ -0,0 +1,6 @@
+namespace LDClient.utils.loggers {
+    public enum LogFlow {
+        Console = 0,
+        File
+    }
+}
diff --git a/ld_client/LDClient/utils/loggers/LogType.cs b/ld_client/LDClient/utils/loggers/LogType.cs
new file mode 100644
index 0000000..370057f
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/LogType.cs
@@ -0,0 +1,7 @@
+namespace LDClient.utils.loggers {
+    public enum LogType {
+        Info = 0,
+        Debug,
+        Error
+    }
+}
diff --git a/ld_client/LDClient/utils/loggers/LogVerbosity.cs b/ld_client/LDClient/utils/loggers/LogVerbosity.cs
new file mode 100644
index 0000000..03c292b
--- /dev/null
+++ b/ld_client/LDClient/utils/loggers/LogVerbosity.cs
@@ -0,0 +1,7 @@
+namespace LDClient.utils.loggers {
+    public enum LogVerbosity {
+        None = 0,
+        Exceptions,
+        Full
+    }
+}
-- 
GitLab


From 58cf6a6f304a0b4de9ce5529e788b1ca69411094 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 9 Apr 2022 22:12:50 +0200
Subject: [PATCH 06/67] re #9438 Added api configuration values

---
 ld_client/LDClient/appsettings.json      | 14 ++++++++++++--
 ld_client/LDClient/utils/ConfigLoader.cs | 18 ++++++++++++++++++
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 01b0de4..68c8b0b 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -12,6 +12,16 @@
     "LogArchiveMaxCount": 10,
     "LogCleanupPeriod": 10,
     "LogVerbosityType": 2,
-    "LogFlowType": 1
-  }
+    "LogFlowType": 0
+  },
+
+  "Network": {
+    "ApiBaseAddress": "http://192.168.0.22",
+    "ApiLDEndPoint": "/lauterbach-debugger-logs/",
+    "ApiPort": 8000,
+    "ApiRetryPeriod": 1,
+
+    "DebuggerAddress": "localhost",
+    "DebuggerPort": 20000
+  } 
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 8005130..681165a 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -4,6 +4,7 @@ using Microsoft.Extensions.Configuration;
 namespace LDClient.utils {
     internal class ConfigLoader {
         private const string LoggingSection = "Logging";
+        private const string NetworkSection = "Network";
 
 
         public int LogChunkSize { get; set; }
@@ -16,6 +17,14 @@ namespace LDClient.utils {
 
         public LogFlow LogFlowType { get; set; } = LogFlow.Console;
 
+        public string ApiBaseAddress { get; set; }
+        public string ApiUsbEndPoint { get; set; }
+        public uint ApiPort { get; set; }
+        public uint ApiRetryPeriod { get; set; }
+
+        public string DebuggerAddress { get; set; }
+        public int DebuggerPort { get; set; }
+
         public ConfigLoader() {
             var configuration = new ConfigurationBuilder()
                 .AddJsonFile("appsettings.json")
@@ -34,7 +43,16 @@ namespace LDClient.utils {
                 LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);
                 LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);
                 LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);
+                
+                var network = configuration.GetSection(NetworkSection);
+                ApiBaseAddress = network["ApiBaseAddress"];
+                ApiUsbEndPoint = network["ApiLDEndPoint"];
+                ApiPort = uint.Parse(network["ApiPort"]);
+                ApiRetryPeriod = uint.Parse(network["ApiRetryPeriod"]);
+
 
+                DebuggerAddress = network["DebuggerAddress"];
+                DebuggerPort = int.Parse(network["DebuggerPort"]);
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
-- 
GitLab


From 202135f9cdbffb5cc7ef7079a87b9dce97e91257 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 9 Apr 2022 22:42:33 +0200
Subject: [PATCH 07/67] re #9438 Added api data definition

---
 .../LDClient/network/data/ConnectionStatus.cs | 11 +++++++
 .../LDClient/network/data/DebuggerInfo.cs     |  9 ++++++
 ld_client/LDClient/network/data/Payload.cs    | 29 +++++++++++++++++++
 3 files changed, 49 insertions(+)
 create mode 100644 ld_client/LDClient/network/data/ConnectionStatus.cs
 create mode 100644 ld_client/LDClient/network/data/DebuggerInfo.cs
 create mode 100644 ld_client/LDClient/network/data/Payload.cs

diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs
new file mode 100644
index 0000000..f5ea275
--- /dev/null
+++ b/ld_client/LDClient/network/data/ConnectionStatus.cs
@@ -0,0 +1,11 @@
+using System.Runtime.Serialization;
+
+namespace LDClient.network.data {
+    public enum ConnectionStatus {
+        [EnumMember(Value = "connected")]
+        Connected,
+        [EnumMember(Value = "disconnected")]
+        Disconnected
+
+    }
+}
diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs
new file mode 100644
index 0000000..cb38d91
--- /dev/null
+++ b/ld_client/LDClient/network/data/DebuggerInfo.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace LDClient.network.data {
+    public class DebuggerInfo {
+        
+        [JsonPropertyName("serial_number")]
+        public string SerialNumber { get; set; }
+    }
+}
diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs
new file mode 100644
index 0000000..1e65c6d
--- /dev/null
+++ b/ld_client/LDClient/network/data/Payload.cs
@@ -0,0 +1,29 @@
+using System.Text.Json.Serialization;
+using Newtonsoft.Json;
+
+namespace LDClient.network.data {
+    [JsonObject(MemberSerialization.OptIn)]
+    public class Payload {
+
+        [JsonPropertyName("username")]
+        public string UserName { get; set; }
+
+        [JsonPropertyName("hostname")]
+        public string HostName { get; set; }
+
+        [JsonPropertyName("timestamp")]
+        //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")]
+        public DateTime TimeStamp { get; set; }
+
+        [JsonPropertyName("head_device")]
+        public DebuggerInfo HeadDevice { get; set; }
+
+
+        [JsonPropertyName("body_device")]
+        public DebuggerInfo  BodyDevice { get; set; }
+        
+        [JsonPropertyName("status")]
+        //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
+        public ConnectionStatus Status { get; set; }
+    }
+}
-- 
GitLab


From 3c82c2ade08466fb88410bfa551bdb0534adf65a Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 9 Apr 2022 22:45:40 +0200
Subject: [PATCH 08/67] re #9438 Added API client + example data

---
 ld_client/LDClient/network/ApiClient.cs  | 75 ++++++++++++++++++++++++
 ld_client/LDClient/network/IApiClient.cs |  7 +++
 2 files changed, 82 insertions(+)
 create mode 100644 ld_client/LDClient/network/ApiClient.cs
 create mode 100644 ld_client/LDClient/network/IApiClient.cs

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
new file mode 100644
index 0000000..d56582e
--- /dev/null
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -0,0 +1,75 @@
+using System.Diagnostics;
+using System.Net.Http.Json;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using LDClient.network.data;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+
+namespace LDClient.network {
+    public class ApiClient : IApiClient {
+        
+        public static readonly Payload ExampleInfo = new() {
+            UserName = "honikCz",
+            HostName = "Bramborak",
+            TimeStamp = DateTime.Parse("2022-03-21 18:05:00.168895"),
+            HeadDevice = new DebuggerInfo {
+                SerialNumber = "C12345678912"
+            },
+            BodyDevice = new DebuggerInfo {
+                SerialNumber = "C98765432198"
+            },
+            Status = ConnectionStatus.Connected
+        };
+
+
+        private readonly string _uri;
+        private readonly HttpClient _client;
+        private readonly uint _retryPeriod;
+
+
+        public ApiClient(string url, uint port, string path, uint retryPeriod) {
+            _uri = $"{url}:{port}{path}";
+            _retryPeriod = retryPeriod;
+            
+            _client = new HttpClient();
+
+        }
+
+        public async Task SendPayloadAsync(Payload payload) {
+            try {
+                Stopwatch stopWatch = new();
+                stopWatch.Start();
+
+                var json = JsonConvert.SerializeObject(ExampleInfo);
+                if (json is null) {
+                    Program.DefaultLogger.Error($"Failed to serialize object: {ExampleInfo}");
+                    return;
+                }
+                var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {
+                    Converters = {
+                        new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
+                    }
+
+                });
+                stopWatch.Stop();
+                Response2Log(json, response, stopWatch.ElapsedMilliseconds);
+
+                response.EnsureSuccessStatusCode();
+                var serverResponse = await response.Content.ReadAsStringAsync();
+                CheckResponse(serverResponse);
+            } catch (Exception e) {
+                Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}");
+            }
+        }
+        
+        private static bool CheckResponse(string response) {
+            dynamic json = JObject.Parse(response);
+
+            if (json.statusCode < 400) {
+                return true;
+            }
+            throw new Exception($"Server responded with error code: {json.statusCode}");
+        }
+    }
+}
diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs
new file mode 100644
index 0000000..fc7ceaa
--- /dev/null
+++ b/ld_client/LDClient/network/IApiClient.cs
@@ -0,0 +1,7 @@
+using LDClient.network.data;
+
+namespace LDClient.network {
+    public interface IApiClient {
+        public Task SendPayloadAsync(Payload payload);
+    }
+}
-- 
GitLab


From 4b0f0b3608268d8dd95cec53292e70003b6f9899 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 9 Apr 2022 22:47:24 +0200
Subject: [PATCH 09/67] re #9438 project structure definition + main example

---
 ld_client/LDClient/LDClient.csproj |  3 +++
 ld_client/LDClient/Program.cs      | 20 ++++++++++----------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
index 3db4860..10ede20 100644
--- a/ld_client/LDClient/LDClient.csproj
+++ b/ld_client/LDClient/LDClient.csproj
@@ -24,7 +24,10 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
+    <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
+    <PackageReference Include="RestSharp" Version="107.3.0" />
     <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
   </ItemGroup>
 
diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 4030157..a05e5e5 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,20 +1,20 @@
-using LDClient.utils;
+using LDClient.network;
+using LDClient.utils;
 using LDClient.utils.loggers;
 
 namespace LDClient; 
 
 internal class Program {
 
-    public static ConfigLoader Config { get; set; } = null!;
+    public static ConfigLoader Config { get; set; } = new();
+    public static ALogger DefaultLogger { get; } = ALogger.Current;
 
-    // Main Method
-    public static void Main() {
-        Config = new ConfigLoader();
+    public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress,
+        Config.ApiPort, Config.ApiUsbEndPoint, Config.ApiRetryPeriod);
 
-        while (true) {
-            ALogger.Current.Info("Ok");
-            ALogger.Current.Debug("Debug");
-            ALogger.Current.Error("Error");
-        }
+    // Main Method
+    public static async Task Main() {
+        await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo);
+        Console.WriteLine("Finished!");
     }
 }
\ No newline at end of file
-- 
GitLab


From 0ba79cc3867c606a7245f5a1e501ebaea11756a5 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 9 Apr 2022 23:03:16 +0200
Subject: [PATCH 10/67] re #9438 added function for logging of server response

---
 ld_client/LDClient/network/ApiClient.cs | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index d56582e..532fe3c 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -71,5 +71,18 @@ namespace LDClient.network {
             }
             throw new Exception($"Server responded with error code: {json.statusCode}");
         }
+        
+        private static void Response2Log(string json, HttpResponseMessage response, long durationMs) {
+            var responseToLog = new {
+                statusCode = response.StatusCode,
+                content = response.Content,
+                headers = response.Headers,
+                errorMessage = response.RequestMessage,
+            };
+
+            Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" +
+                                 $"Request body: {json},\n" +
+                                 $"Response: {JsonConvert.SerializeObject(responseToLog)}");
+        }
     }
 }
-- 
GitLab


From c2cc7813c0259a24fabc8b65f09de399ccc0c479 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 19:48:12 +0200
Subject: [PATCH 11/67] re #9441 Added configuration properties + library added
 to project structure

---
 ld_client/LDClient/LDClient.csproj       |  2 ++
 ld_client/LDClient/appsettings.json      | 17 ++++++++----
 ld_client/LDClient/utils/ConfigLoader.cs | 34 +++++++++++++++++++-----
 3 files changed, 42 insertions(+), 11 deletions(-)

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
index 10ede20..c575ea0 100644
--- a/ld_client/LDClient/LDClient.csproj
+++ b/ld_client/LDClient/LDClient.csproj
@@ -24,11 +24,13 @@
   </ItemGroup>
 
   <ItemGroup>
+    <PackageReference Include="DiskQueue" Version="1.5.0" />
     <PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
     <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
     <PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
     <PackageReference Include="RestSharp" Version="107.3.0" />
     <PackageReference Include="System.Configuration.ConfigurationManager" Version="6.0.0" />
+    <PackageReference Include="System.Management" Version="6.0.0" />
   </ItemGroup>
 
 </Project>
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 68c8b0b..7884a5e 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -16,12 +16,19 @@
   },
 
   "Network": {
-    "ApiBaseAddress": "http://192.168.0.22",
+    "ApiBaseAddress": "http://127.0.0.1",
     "ApiLDEndPoint": "/lauterbach-debugger-logs/",
-    "ApiPort": 8000,
-    "ApiRetryPeriod": 1,
-
+    "ApiPort": 8000
+  },
+  "Cache": {
+    "RetryPeriod": 1,
+    "MaxEntries": 20,
+    "MaxRetries": 5,
+    "CacheFileName": "cache"
+  },
+  "DebuggerDetection": {
     "DebuggerAddress": "localhost",
-    "DebuggerPort": 20000
+    "DebuggerPort": 20000,
+    "DebuggerProcessName": "t32mtc"
   } 
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 681165a..9ef7ed9 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -5,8 +5,10 @@ namespace LDClient.utils {
     internal class ConfigLoader {
         private const string LoggingSection = "Logging";
         private const string NetworkSection = "Network";
+        private const string CacheSection = "Cache";
+        private const string DDSection = "DebuggerDetection";
 
-
+        #region Logger
         public int LogChunkSize { get; set; }
         public int LogChunkMaxCount { get; set; }
         public int LogArchiveMaxCount { get; set; }
@@ -16,14 +18,27 @@ namespace LDClient.utils {
         public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full;
 
         public LogFlow LogFlowType { get; set; } = LogFlow.Console;
+        #endregion
 
+        #region Api
         public string ApiBaseAddress { get; set; }
         public string ApiUsbEndPoint { get; set; }
         public uint ApiPort { get; set; }
-        public uint ApiRetryPeriod { get; set; }
 
+        #endregion
+
+        #region Cache
+        public string CacheFileName { get; set; }
+        public uint MaxRetries { get; set; }
+        public uint MaxEntries { get; set; }
+        public uint RetryPeriod { get; set; }
+        #endregion
+
+        #region Detection
         public string DebuggerAddress { get; set; }
         public int DebuggerPort { get; set; }
+        public string DebuggerProcessName { get; set; }
+        #endregion
 
         public ConfigLoader() {
             var configuration = new ConfigurationBuilder()
@@ -48,11 +63,19 @@ namespace LDClient.utils {
                 ApiBaseAddress = network["ApiBaseAddress"];
                 ApiUsbEndPoint = network["ApiLDEndPoint"];
                 ApiPort = uint.Parse(network["ApiPort"]);
-                ApiRetryPeriod = uint.Parse(network["ApiRetryPeriod"]);
 
 
-                DebuggerAddress = network["DebuggerAddress"];
-                DebuggerPort = int.Parse(network["DebuggerPort"]);
+                var cache = configuration.GetSection(CacheSection);
+                RetryPeriod = uint.Parse(cache["RetryPeriod"]);
+                MaxEntries = uint.Parse(cache["MaxEntries"]);
+                MaxRetries = uint.Parse(cache["MaxRetries"]);
+                CacheFileName = cache["CacheFileName"];
+
+
+                var debugger = configuration.GetSection(DDSection);
+                DebuggerAddress = debugger["DebuggerAddress"];
+                DebuggerPort = int.Parse(debugger["DebuggerPort"]);
+                DebuggerProcessName = debugger["DebuggerProcessName"];
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
@@ -62,6 +85,5 @@ namespace LDClient.utils {
                 throw new IOException("Reading of configuration file failed! " + e);
             }
         }
-
     }
 }
-- 
GitLab


From 88eab964e5194d198574a198888740b5744205e0 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 19:58:37 +0200
Subject: [PATCH 12/67] re #9441 definition of new Api client functions,
 implementation and added needed variables

---
 ld_client/LDClient/network/ApiClient.cs  | 30 ++++++++++++++++++++----
 ld_client/LDClient/network/IApiClient.cs |  2 ++
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 532fe3c..15e38e4 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -1,10 +1,10 @@
 using System.Diagnostics;
 using System.Net.Http.Json;
+using System.Text;
 using System.Text.Json;
 using System.Text.Json.Serialization;
+using DiskQueue;
 using LDClient.network.data;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
 
 namespace LDClient.network {
     public class ApiClient : IApiClient {
@@ -22,17 +22,27 @@ namespace LDClient.network {
             Status = ConnectionStatus.Connected
         };
 
+        private bool _running;
+
 
         private readonly string _uri;
         private readonly HttpClient _client;
+        private readonly IPersistentQueue _cache;
         private readonly uint _retryPeriod;
+        private readonly uint _maxEntries;
+        private readonly uint _maxRetries;
+        
 
 
-        public ApiClient(string url, uint port, string path, uint retryPeriod) {
+        public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries,
+            string cacheFilename) {
             _uri = $"{url}:{port}{path}";
             _retryPeriod = retryPeriod;
-            
+            _maxEntries = maxEntries;
+            _maxRetries = maxRetries;
+
             _client = new HttpClient();
+            _cache = new PersistentQueue(cacheFilename);
 
         }
 
@@ -83,6 +93,18 @@ namespace LDClient.network {
             Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" +
                                  $"Request body: {json},\n" +
                                  $"Response: {JsonConvert.SerializeObject(responseToLog)}");
+
+        public async void Run() {
+            Program.DefaultLogger.Info("Api Client thread has started");
+            _running = true;
+            while (_running) {
+                await ResendPayloadsAsync();
+                Thread.Sleep((int)_retryPeriod);
+            }
+        }
+
+        public void Stop() {
+            _running = false;
         }
     }
 }
diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs
index fc7ceaa..f5ea700 100644
--- a/ld_client/LDClient/network/IApiClient.cs
+++ b/ld_client/LDClient/network/IApiClient.cs
@@ -3,5 +3,7 @@
 namespace LDClient.network {
     public interface IApiClient {
         public Task SendPayloadAsync(Payload payload);
+        public void Run();
+        public void Stop();
     }
 }
-- 
GitLab


From eda1e8c74a34dde8184b960627c82cc7083d482d Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 19:59:33 +0200
Subject: [PATCH 13/67] re #9441 Added core of cache manager

---
 ld_client/LDClient/network/ApiClient.cs | 39 +++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 15e38e4..152a962 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -94,6 +94,45 @@ namespace LDClient.network {
                                  $"Request body: {json},\n" +
                                  $"Response: {JsonConvert.SerializeObject(responseToLog)}");
 
+        private async Task ResendPayloadsAsync() {
+            var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);
+            var payloads = new List<Payload>();
+
+            using (var session = _cache.OpenSession()) {
+                for (var i = 0; i < numberOfPayloadsToResend; i++) {
+                    var rawBytes = session.Dequeue();
+                    var payload = JsonSerializer.Deserialize<Payload>(rawBytes);
+                    if (payload is not null) {
+                        payloads.Add(payload);
+                    }
+                }
+                session.Flush();
+            }
+
+            if (payloads.Count > 0) {
+                Program.DefaultLogger.Debug($"ResendPayloadAsync -> {payloads.Count} unsent payloads");
+                var tasks = new List<Task>();
+                foreach (var payload in payloads) {
+                    Program.DefaultLogger.Info($"Resending {payload}.");
+                    tasks.Add(SendPayloadAsync(payload));
+                }
+                await Task.WhenAll(tasks);
+            }
+        }
+
+
+        private void CachePayload(Payload payload) {
+            Program.DefaultLogger.Info($"Storing {payload} into the cache.");
+            var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue;
+            using var session = _cache.OpenSession();
+            if (numberOfCachedPayloads >= _maxEntries) {
+                session.Dequeue();
+            }
+            var payloadJson = JsonSerializer.Serialize(payload);
+            session.Enqueue(Encoding.UTF8.GetBytes(payloadJson));
+            session.Flush();
+        }
+
         public async void Run() {
             Program.DefaultLogger.Info("Api Client thread has started");
             _running = true;
-- 
GitLab


From 522ba9b4be3d9a9deeccdfe61b1685661b8e7f32 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 20:01:04 +0200
Subject: [PATCH 14/67] re #9441 manager refactoring - removal of useless
 functions and variables

---
 ld_client/LDClient/network/ApiClient.cs | 29 +++++++------------------
 1 file changed, 8 insertions(+), 21 deletions(-)

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 152a962..dbbbf7b 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -50,12 +50,7 @@ namespace LDClient.network {
             try {
                 Stopwatch stopWatch = new();
                 stopWatch.Start();
-
-                var json = JsonConvert.SerializeObject(ExampleInfo);
-                if (json is null) {
-                    Program.DefaultLogger.Error($"Failed to serialize object: {ExampleInfo}");
-                    return;
-                }
+                
                 var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {
                     Converters = {
                         new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
@@ -63,26 +58,16 @@ namespace LDClient.network {
 
                 });
                 stopWatch.Stop();
-                Response2Log(json, response, stopWatch.ElapsedMilliseconds);
+                CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds);
 
                 response.EnsureSuccessStatusCode();
-                var serverResponse = await response.Content.ReadAsStringAsync();
-                CheckResponse(serverResponse);
             } catch (Exception e) {
                 Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}");
+                CachePayload(payload);
             }
         }
-        
-        private static bool CheckResponse(string response) {
-            dynamic json = JObject.Parse(response);
 
-            if (json.statusCode < 400) {
-                return true;
-            }
-            throw new Exception($"Server responded with error code: {json.statusCode}");
-        }
-        
-        private static void Response2Log(string json, HttpResponseMessage response, long durationMs) {
+        private static void CreateRequestLog(Payload payload, HttpResponseMessage response, long durationMs) {
             var responseToLog = new {
                 statusCode = response.StatusCode,
                 content = response.Content,
@@ -91,8 +76,10 @@ namespace LDClient.network {
             };
 
             Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" +
-                                 $"Request body: {json},\n" +
-                                 $"Response: {JsonConvert.SerializeObject(responseToLog)}");
+                                 $"Request body: {payload},\n" +
+                                 $"Response: {responseToLog}");
+        }
+        
 
         private async Task ResendPayloadsAsync() {
             var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);
-- 
GitLab


From aaad9ad4328109c8f294c8d7e44e6d78f9b40630 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 20:05:10 +0200
Subject: [PATCH 15/67] re #9441 Main example + Payload feature for better
 manipulation

---
 ld_client/LDClient/Program.cs              | 23 +++++++++++++++++++---
 ld_client/LDClient/network/data/Payload.cs | 23 +++++++++++++++++++++-
 2 files changed, 42 insertions(+), 4 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index a05e5e5..3f4b77f 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,4 +1,4 @@
-using LDClient.network;
+using LDClient.network;
 using LDClient.utils;
 using LDClient.utils.loggers;
 
@@ -10,11 +10,28 @@ internal class Program {
     public static ALogger DefaultLogger { get; } = ALogger.Current;
 
     public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress,
-        Config.ApiPort, Config.ApiUsbEndPoint, Config.ApiRetryPeriod);
+        Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries,
+        Config.MaxRetries, Config.CacheFileName);
 
     // Main Method
     public static async Task Main() {
+
+        var apiClientThread = new Thread(DefaultApiClient.Run) {
+            IsBackground = true
+        };
+        apiClientThread.Start();
+
+        DefaultLogger.Debug("Main -> starting SendPayloadAsync");
         await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo);
-        Console.WriteLine("Finished!");
+
+
+        DefaultLogger.Debug("Main -> lets slack for a bit");
+        Thread.Sleep(30000);
+
+        DefaultLogger.Debug("Main -> stopping the ApiClient");
+        DefaultApiClient.Stop();
+        apiClientThread.Join();
+        DefaultLogger.Debug("Main -> finished");
+    }
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs
index 1e65c6d..30672d7 100644
--- a/ld_client/LDClient/network/data/Payload.cs
+++ b/ld_client/LDClient/network/data/Payload.cs
@@ -1,5 +1,7 @@
-using System.Text.Json.Serialization;
+using System.Text.Json;
+using System.Text.Json.Serialization;
 using Newtonsoft.Json;
+using JsonSerializer = System.Text.Json.JsonSerializer;
 
 namespace LDClient.network.data {
     [JsonObject(MemberSerialization.OptIn)]
@@ -25,5 +27,24 @@ namespace LDClient.network.data {
         [JsonPropertyName("status")]
         //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
         public ConnectionStatus Status { get; set; }
+
+
+        public override string ToString() {
+            return ParseToJson(this);
+        }
+
+        public string ParseToJson() {
+            return Payload.ParseToJson(this);
+        }
+
+        public static string ParseToJson(Payload payload) {
+            var options = new JsonSerializerOptions {
+                Converters = {
+                    new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
+                }
+            };
+
+            return JsonSerializer.Serialize(payload, options);
+        }
     }
 }
-- 
GitLab


From 914776bd00caddafaf81be8bb5d2e3f48f186169 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 22:57:37 +0200
Subject: [PATCH 16/67] re #9433 Added needed configuration for detection

---
 ld_client/LDClient/appsettings.json      | 12 +++++++-----
 ld_client/LDClient/utils/ConfigLoader.cs | 18 +++++++++++-------
 2 files changed, 18 insertions(+), 12 deletions(-)

diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 7884a5e..910d880 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -21,14 +21,16 @@
     "ApiPort": 8000
   },
   "Cache": {
-    "RetryPeriod": 1,
+    "RetryPeriod": 10000,
     "MaxEntries": 20,
     "MaxRetries": 5,
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
-    "DebuggerAddress": "localhost",
-    "DebuggerPort": 20000,
-    "DebuggerProcessName": "t32mtc"
-  } 
+    "T32Address": "localhost",
+    "T32Port": 20000,
+    "T32ProcessName": "t32mtc",
+    "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt",
+    "DetectionPeriod": 5000
+  }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 9ef7ed9..b45b9f8 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -35,9 +35,11 @@ namespace LDClient.utils {
         #endregion
 
         #region Detection
-        public string DebuggerAddress { get; set; }
-        public int DebuggerPort { get; set; }
-        public string DebuggerProcessName { get; set; }
+        public string T32Address { get; set; }
+        public int T32Port { get; set; }
+        public string T32ProcessName { get; set; }
+        public uint DetectionPeriod { get; set; }
+        public string T32InfoLocation { get; set; }
         #endregion
 
         public ConfigLoader() {
@@ -58,7 +60,7 @@ namespace LDClient.utils {
                 LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);
                 LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);
                 LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);
-                
+
                 var network = configuration.GetSection(NetworkSection);
                 ApiBaseAddress = network["ApiBaseAddress"];
                 ApiUsbEndPoint = network["ApiLDEndPoint"];
@@ -73,9 +75,11 @@ namespace LDClient.utils {
 
 
                 var debugger = configuration.GetSection(DDSection);
-                DebuggerAddress = debugger["DebuggerAddress"];
-                DebuggerPort = int.Parse(debugger["DebuggerPort"]);
-                DebuggerProcessName = debugger["DebuggerProcessName"];
+                T32Address = debugger["T32Address"];
+                T32Port = int.Parse(debugger["T32Port"]);
+                T32ProcessName = debugger["T32ProcessName"];
+                T32InfoLocation = debugger["T32InfoLocation"];
+                DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
-- 
GitLab


From 4056867185713b32bf144b32a6a17cff78e961a5 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 23:00:05 +0200
Subject: [PATCH 17/67] re #9433 Abstract detection definition added

---
 ld_client/LDClient/detection/IDetection.cs | 15 +++++++++++++++
 1 file changed, 15 insertions(+)
 create mode 100644 ld_client/LDClient/detection/IDetection.cs

diff --git a/ld_client/LDClient/detection/IDetection.cs b/ld_client/LDClient/detection/IDetection.cs
new file mode 100644
index 0000000..4d42eea
--- /dev/null
+++ b/ld_client/LDClient/detection/IDetection.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    internal interface IDetection {
+
+        public void DetectAsync();
+
+        public void RunPeriodicDetection();
+        public void StopPeriodicDetection();
+    }
+}
-- 
GitLab


From ad51fa1a94cbb500dfb71b490e6c5b0b1f0384d2 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 23:00:48 +0200
Subject: [PATCH 18/67] re #9433 Added possible detection by process name

---
 .../LDClient/detection/ProcessDetection.cs    | 92 +++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 ld_client/LDClient/detection/ProcessDetection.cs

diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
new file mode 100644
index 0000000..77ebca2
--- /dev/null
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -0,0 +1,92 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System;
+using System.Management;
+
+namespace LDClient.detection {
+    public class ProcessDetection : IDetection {
+
+        private const string ProcessStartQuery = "SELECT * FROM Win32_ProcessStartTrace";
+        private const string ProcessStopQuery = "SELECT * FROM Win32_ProcessStopTrace";
+
+        private ManagementEventWatcher _stopWatch;
+
+        private bool _isRunning;
+
+        private readonly string _processName;
+        private readonly uint _detectionPeriod;
+        private bool _processActive;
+        public ProcessDetection(string processName, uint detectionPeriod) {
+            this._processName = processName;
+            this._detectionPeriod = detectionPeriod;
+        }
+
+
+        public void DetectAsync() {
+            var processes = Process.GetProcessesByName(_processName);
+            Program.DefaultLogger.Info($"Found {processes.Length} processes with name: {_processName}");
+            var processFound = false;
+            foreach (var process in processes) {
+                if (process.ProcessName.Equals(_processName)) {
+                    if (!_processActive) {
+                        Program.DefaultLogger.Info($"Process started: {_processName}");
+                    }
+                    _processActive = true;
+                    processFound = true;
+                    break;
+                }
+                Console.WriteLine(process);
+            }
+
+            if (!processFound) {
+                if (_processActive) {
+                    Program.DefaultLogger.Info($"Process stopped: {_processName}");
+                }
+                _processActive = false;
+            }
+        }
+
+
+        public void RunPeriodicDetection() {
+
+            Program.DefaultLogger.Info("Process periodic detector has started");
+            _isRunning = true;
+            while (_isRunning) {
+                DetectAsync();
+                Thread.Sleep((int)_detectionPeriod);
+            }
+        }
+
+        public void StopPeriodicDetection() {
+            _isRunning = false;
+        }
+
+
+        public void RegisterProcessListeners() {
+            ManagementEventWatcher startWatch = new ManagementEventWatcher(
+                new WqlEventQuery(ProcessStartQuery));
+            startWatch.EventArrived += startWatch_EventArrived;
+            startWatch.Start();
+
+            _stopWatch = new ManagementEventWatcher(
+                new WqlEventQuery(ProcessStopQuery));
+            _stopWatch.EventArrived += stopWatch_EventArrived;
+            _stopWatch.Start();
+        }
+
+        void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) {
+            var processName = e.NewEvent.Properties["ProcessName"].Value.ToString();
+            if (processName.Equals(_processName + ".exe")) {
+                Program.DefaultLogger.Info($"Process stopped: {processName}");
+            }
+        }
+
+        void startWatch_EventArrived(object sender, EventArrivedEventArgs e) {
+            var processName = e.NewEvent.Properties["ProcessName"].Value.ToString();
+            if (processName.Equals(_processName + ".exe")) {
+                Program.DefaultLogger.Info($"Process started: {processName}");
+            }
+        }
+    }
+}
-- 
GitLab


From 56f7f54615ae955d4f533863fc5072dfa7bb2336 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 23:01:27 +0200
Subject: [PATCH 19/67] re #9433 Added possible detection by port listening

---
 .../LDClient/detection/NetworkDetection.cs    | 49 +++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 ld_client/LDClient/detection/NetworkDetection.cs

diff --git a/ld_client/LDClient/detection/NetworkDetection.cs b/ld_client/LDClient/detection/NetworkDetection.cs
new file mode 100644
index 0000000..83b0bcc
--- /dev/null
+++ b/ld_client/LDClient/detection/NetworkDetection.cs
@@ -0,0 +1,49 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    public class NetworkDetection : IDetection {
+
+        private readonly uint _port;
+
+        private bool _isRunning;
+        
+        private readonly uint _detectionPeriod;
+
+        public NetworkDetection(uint port, uint detectionPeriod) {
+            this._port = port;
+            this._detectionPeriod = detectionPeriod;
+        }
+
+        public void DetectAsync() {
+
+            var listeners = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
+
+            Program.DefaultLogger.Debug($"NetworkDetection -> Checking all currently listening.");
+            foreach (var listener in listeners) {
+                //Program.DefaultLogger.Debug($"{listener.Address}:{listener.Port}");
+                if (listener.Port == _port) {
+                    Program.DefaultLogger.Info($"Found some process listening on {listener.Address}:{_port}");
+                }
+            }
+
+        }
+
+
+        public void RunPeriodicDetection() {
+            Program.DefaultLogger.Info("Network periodic detector has started");
+            _isRunning = true;
+            while (_isRunning) {
+                DetectAsync();
+                Thread.Sleep((int)_detectionPeriod);
+            }
+        }
+
+        public void StopPeriodicDetection() {
+            _isRunning = false;
+        }
+    }
+}
-- 
GitLab


From f5a08dd55a0848dc146f6f9d70ebfbd415daf981 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 10 Apr 2022 23:02:09 +0200
Subject: [PATCH 20/67] re #9433 detection definition in Main

---
 ld_client/LDClient/Program.cs | 39 +++++++++++++++++++++++++++++------
 1 file changed, 33 insertions(+), 6 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 3f4b77f..0eb6443 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,8 +1,11 @@
+using System.Runtime.InteropServices;
+using System.Security.Principal;
+using LDClient.detection;
 using LDClient.network;
 using LDClient.utils;
 using LDClient.utils.loggers;
 
-namespace LDClient; 
+namespace LDClient;
 
 internal class Program {
 
@@ -13,25 +16,49 @@ internal class Program {
         Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries,
         Config.MaxRetries, Config.CacheFileName);
 
+
+    private static NetworkDetection _netDetect = new(Config.ApiPort, Config.DetectionPeriod);
+    private static ProcessDetection _procDetect = new(Config.T32ProcessName, Config.DetectionPeriod);
+
+
     // Main Method
     public static async Task Main() {
-
         var apiClientThread = new Thread(DefaultApiClient.Run) {
             IsBackground = true
         };
+        DefaultLogger.Debug("Main -> starting the ApiClient");
         apiClientThread.Start();
 
-        DefaultLogger.Debug("Main -> starting SendPayloadAsync");
-        await DefaultApiClient.SendPayloadAsync(ApiClient.ExampleInfo);
+        var admin = IsAdministrator();
+        DefaultLogger.Debug($"Is program executed with admin rights? {admin}");
 
+        var networkTread = new Thread(_netDetect.RunPeriodicDetection);
+        networkTread.Start();
+        if (admin) {
+            _procDetect.RegisterProcessListeners();
 
-        DefaultLogger.Debug("Main -> lets slack for a bit");
-        Thread.Sleep(30000);
+        } else {
+            var processThread = new Thread(_procDetect.RunPeriodicDetection);
+            processThread.Start();
+            processThread.Join();
+        }
+
+        networkTread.Join();
 
         DefaultLogger.Debug("Main -> stopping the ApiClient");
         DefaultApiClient.Stop();
         apiClientThread.Join();
         DefaultLogger.Debug("Main -> finished");
     }
+
+    public static bool IsAdministrator() {
+        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
+            var identity = WindowsIdentity.GetCurrent();
+            var principal = new WindowsPrincipal(identity);
+            return principal.IsInRole(WindowsBuiltInRole.Administrator);
+
+        } else {
+            return false;
+        }
     }
 }
\ No newline at end of file
-- 
GitLab


From bab6f59d70db4045421ad2f1705b60f59d1b0073 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Fri, 15 Apr 2022 14:24:08 +0200
Subject: [PATCH 21/67] re #9565 Implemented DebuggerInfoParser, added IoUtils
 for reading the content of a file

---
 .../LDClient/detection/DebuggerInfoParser.cs  | 21 +++++++++++++++++++
 ld_client/LDClient/utils/IoUtils.cs           |  9 ++++++++
 2 files changed, 30 insertions(+)
 create mode 100644 ld_client/LDClient/detection/DebuggerInfoParser.cs
 create mode 100644 ld_client/LDClient/utils/IoUtils.cs

diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs
new file mode 100644
index 0000000..3f07e32
--- /dev/null
+++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs
@@ -0,0 +1,21 @@
+using System.Text.RegularExpressions;
+
+namespace LDClient.detection {
+
+    public static class DebuggerInfoParser {
+
+        private const int ExpectedNumberOfMatches = 2;
+        
+        private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)");
+        
+        public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) {
+            var matches = SerialNumberRegex.Matches(dataTxt);
+
+            if (matches.Count != ExpectedNumberOfMatches) {
+                throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})");
+            }
+            
+            return (matches[0].ToString(), matches[1].ToString());
+        }
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/IoUtils.cs b/ld_client/LDClient/utils/IoUtils.cs
new file mode 100644
index 0000000..7bf3a65
--- /dev/null
+++ b/ld_client/LDClient/utils/IoUtils.cs
@@ -0,0 +1,9 @@
+namespace LDClient.utils {
+
+    public static class IoUtils {
+
+        public static string ReadFile(string filename) {
+            return File.ReadAllLines(filename).Aggregate("", (current, line) => $"{current}{line}\n");
+        }
+    }
+}
\ No newline at end of file
-- 
GitLab


From 30c849e48a7421a525b5aa6685c5b5ed26d8bb92 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sat, 16 Apr 2022 11:26:19 +0200
Subject: [PATCH 22/67] re #9567 Made sure that  there is only one running
 process of the application.

---
 ld_client/LDClient/Program.cs | 62 +++++++++++++++++++++--------------
 1 file changed, 37 insertions(+), 25 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 0eb6443..a161b8d 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -5,40 +5,52 @@ using LDClient.network;
 using LDClient.utils;
 using LDClient.utils.loggers;
 
+using static System.Diagnostics.Process;
+using static System.Reflection.Assembly;
+
 namespace LDClient;
 
-internal class Program {
+internal static class Program {
 
-    public static ConfigLoader Config { get; set; } = new();
+    public static ConfigLoader Config { get; } = new();
     public static ALogger DefaultLogger { get; } = ALogger.Current;
-
-    public static IApiClient DefaultApiClient { get; set; } = new ApiClient(Config.ApiBaseAddress,
-        Config.ApiPort, Config.ApiUsbEndPoint, Config.RetryPeriod, Config.MaxEntries,
-        Config.MaxRetries, Config.CacheFileName);
-
-
-    private static NetworkDetection _netDetect = new(Config.ApiPort, Config.DetectionPeriod);
-    private static ProcessDetection _procDetect = new(Config.T32ProcessName, Config.DetectionPeriod);
-
-
+    private static IApiClient? DefaultApiClient { get; set; }
+    private static readonly NetworkDetection NetDetect = new(Config.ApiPort, Config.DetectionPeriod);
+    private static readonly ProcessDetection ProcDetect = new(Config.T32ProcessName, Config.DetectionPeriod);
+    
     // Main Method
-    public static async Task Main() {
+    public static int Main() {
+        var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1;
+        if (exists) {
+            DefaultLogger.Error("Another instance of the application is already running");
+            return 1;
+        }
+        
+        DefaultApiClient = new ApiClient(
+            Config.ApiBaseAddress,
+            Config.ApiPort, 
+            Config.ApiUsbEndPoint, 
+            Config.RetryPeriod, Config.MaxEntries,
+            Config.MaxRetries, 
+            Config.CacheFileName
+        );
+        
+        DefaultLogger.Debug("Main -> starting the ApiClient");
         var apiClientThread = new Thread(DefaultApiClient.Run) {
             IsBackground = true
         };
-        DefaultLogger.Debug("Main -> starting the ApiClient");
         apiClientThread.Start();
 
         var admin = IsAdministrator();
         DefaultLogger.Debug($"Is program executed with admin rights? {admin}");
 
-        var networkTread = new Thread(_netDetect.RunPeriodicDetection);
+        var networkTread = new Thread(NetDetect.RunPeriodicDetection);
         networkTread.Start();
+        
         if (admin) {
-            _procDetect.RegisterProcessListeners();
-
+            ProcDetect.RegisterProcessListeners();
         } else {
-            var processThread = new Thread(_procDetect.RunPeriodicDetection);
+            var processThread = new Thread(ProcDetect.RunPeriodicDetection);
             processThread.Start();
             processThread.Join();
         }
@@ -49,16 +61,16 @@ internal class Program {
         DefaultApiClient.Stop();
         apiClientThread.Join();
         DefaultLogger.Debug("Main -> finished");
+        
+        return 0;
     }
 
-    public static bool IsAdministrator() {
-        if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
-            var identity = WindowsIdentity.GetCurrent();
-            var principal = new WindowsPrincipal(identity);
-            return principal.IsInRole(WindowsBuiltInRole.Administrator);
-
-        } else {
+    private static bool IsAdministrator() {
+        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
             return false;
         }
+        var identity = WindowsIdentity.GetCurrent();
+        var principal = new WindowsPrincipal(identity);
+        return principal.IsInRole(WindowsBuiltInRole.Administrator);
     }
 }
\ No newline at end of file
-- 
GitLab


From 4a9e70db3786db264ffb03947b3e835a67654731 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sun, 17 Apr 2022 10:03:06 +0200
Subject: [PATCH 23/67] re #9566 Created mocks for simulating an LD-debugger

---
 ld_client/Mock/ld/CMakeLists.txt      |  7 ++++
 ld_client/Mock/ld/ld_mock.cpp         | 11 ++++++
 ld_client/Mock/t32rem/CMakeLists.txt  |  7 ++++
 ld_client/Mock/t32rem/t32rem_mock.cpp | 57 +++++++++++++++++++++++++++
 4 files changed, 82 insertions(+)
 create mode 100644 ld_client/Mock/ld/CMakeLists.txt
 create mode 100644 ld_client/Mock/ld/ld_mock.cpp
 create mode 100644 ld_client/Mock/t32rem/CMakeLists.txt
 create mode 100644 ld_client/Mock/t32rem/t32rem_mock.cpp

diff --git a/ld_client/Mock/ld/CMakeLists.txt b/ld_client/Mock/ld/CMakeLists.txt
new file mode 100644
index 0000000..9886e96
--- /dev/null
+++ b/ld_client/Mock/ld/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(ld_mock)
+
+set(CMAKE_CXX_STANDARD 17)
+
+add_executable(${PROJECT_NAME} ld_mock.cpp)
diff --git a/ld_client/Mock/ld/ld_mock.cpp b/ld_client/Mock/ld/ld_mock.cpp
new file mode 100644
index 0000000..78e7b5b
--- /dev/null
+++ b/ld_client/Mock/ld/ld_mock.cpp
@@ -0,0 +1,11 @@
+#include <chrono>
+#include <thread>
+
+static constexpr int LOOP_DELAY_S = 10;
+
+int main() {
+    while (true) {
+        std::this_thread::sleep_for(std::chrono::milliseconds(LOOP_DELAY_S * 1000));
+    }
+    return 0;
+}
diff --git a/ld_client/Mock/t32rem/CMakeLists.txt b/ld_client/Mock/t32rem/CMakeLists.txt
new file mode 100644
index 0000000..916a768
--- /dev/null
+++ b/ld_client/Mock/t32rem/CMakeLists.txt
@@ -0,0 +1,7 @@
+cmake_minimum_required(VERSION 3.0)
+
+project(t32rem_mock)
+
+set(CMAKE_CXX_STANDARD 17)
+
+add_executable(${PROJECT_NAME} t32rem_mock.cpp)
diff --git a/ld_client/Mock/t32rem/t32rem_mock.cpp b/ld_client/Mock/t32rem/t32rem_mock.cpp
new file mode 100644
index 0000000..5c05734
--- /dev/null
+++ b/ld_client/Mock/t32rem/t32rem_mock.cpp
@@ -0,0 +1,57 @@
+// t32rem.exe localhost port=20000 VERSION.HARDWARE
+#include <chrono>
+#include <thread>
+#include <random>
+#include <fstream>
+#include <iostream>
+#include <cstring>
+
+static constexpr int EXPECTED_NUMBER_OF_ARGUMENTS = 4;
+static constexpr const char *OUTPUT_FILE_NAME = "output.txt";
+static constexpr const char *DEBUGGER_INFO =
+        "B::version.hardware\n"
+        "PowerDebug USB 3.0 via USB 3.0\n"
+        "   Serial Number: C21070308132\n"
+        "   Firmware R.2021.02 (136263)\n"
+        "   Instance: 1.\n"
+        "   Automotive Debug Cable\n"
+        "      Serial Number: C17040231820\n";
+
+static constexpr int MIN_SEC_DELAY = 1;
+static constexpr int MAX_SEC_DELAY = 10;
+
+int main(int argc, char *argv[]) {
+    if (argc != EXPECTED_NUMBER_OF_ARGUMENTS) {
+        std::cout << "Invalid number of arguments\n";
+        std::cout << "The mock is meant to be called with the following arguments: localhost port=20000 VERSION.HARDWARE\n";
+        return 1;
+    }
+    if (strcmp(argv[1], "localhost") != 0) {
+        std::cout << "Invalid first argument (expected 'localhost')\n";
+        return 2;
+    }
+    if (strcmp(argv[2], "port=20000") != 0) {
+        std::cout << "Invalid second argument (expected 'port=20000')\n";
+        return 2;
+    }
+    if (strcmp(argv[3], "VERSION.HARDWARE") != 0) {
+        std::cout << "Invalid third argument (expected 'VERSION.HARDWARE')\n";
+        return 2;
+    }
+
+    std::random_device rd;
+    std::mt19937 mt(rd());
+    std::uniform_int_distribution<uint32_t> distribution(MIN_SEC_DELAY, MAX_SEC_DELAY);
+    uint32_t delay_s = distribution(mt);
+    std::this_thread::sleep_for(std::chrono::milliseconds(delay_s * 1000));
+
+    std::ofstream file(OUTPUT_FILE_NAME);
+    if (!file) {
+        std::cout << "Fail to open the output file\n";
+        return 3;
+    }
+    file << DEBUGGER_INFO;
+    file.close();
+
+    return 0;
+}
-- 
GitLab


From f281acacfc4892b73d2f71743167be2c1ebb1a84 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sun, 17 Apr 2022 12:08:38 +0200
Subject: [PATCH 24/67] re #9566 Added InfoFetcher.cs, modified some other
 files (a bit of refactoring)

---
 ld_client/LDClient/Program.cs                 | 52 ++++-------
 ld_client/LDClient/appsettings.json           |  5 +-
 ld_client/LDClient/detection/IDetection.cs    | 15 ---
 .../LDClient/detection/IProcessDetection.cs   |  7 ++
 ld_client/LDClient/detection/InfoFetcher.cs   | 72 +++++++++++++++
 .../LDClient/detection/NetworkDetection.cs    | 49 ----------
 .../LDClient/detection/ProcessDetection.cs    | 92 -------------------
 .../detection/ProcessProcessDetection.cs      | 87 ++++++++++++++++++
 ld_client/LDClient/network/ApiClient.cs       | 35 +------
 ld_client/LDClient/network/IApiClient.cs      |  3 +-
 ld_client/LDClient/network/data/Payload.cs    | 10 +-
 ld_client/LDClient/utils/ConfigLoader.cs      | 53 +++++------
 12 files changed, 225 insertions(+), 255 deletions(-)
 delete mode 100644 ld_client/LDClient/detection/IDetection.cs
 create mode 100644 ld_client/LDClient/detection/IProcessDetection.cs
 create mode 100644 ld_client/LDClient/detection/InfoFetcher.cs
 delete mode 100644 ld_client/LDClient/detection/NetworkDetection.cs
 delete mode 100644 ld_client/LDClient/detection/ProcessDetection.cs
 create mode 100644 ld_client/LDClient/detection/ProcessProcessDetection.cs

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index a161b8d..577a284 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,5 +1,3 @@
-using System.Runtime.InteropServices;
-using System.Security.Principal;
 using LDClient.detection;
 using LDClient.network;
 using LDClient.utils;
@@ -15,10 +13,13 @@ internal static class Program {
     public static ConfigLoader Config { get; } = new();
     public static ALogger DefaultLogger { get; } = ALogger.Current;
     private static IApiClient? DefaultApiClient { get; set; }
-    private static readonly NetworkDetection NetDetect = new(Config.ApiPort, Config.DetectionPeriod);
-    private static readonly ProcessDetection ProcDetect = new(Config.T32ProcessName, Config.DetectionPeriod);
     
-    // Main Method
+    private static readonly InfoFetcher InfoFetcher = new(
+        5,
+        1000,
+        "output.txt"
+    );
+    
     public static int Main() {
         var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1;
         if (exists) {
@@ -35,42 +36,27 @@ internal static class Program {
             Config.CacheFileName
         );
         
+        IProcessDetection processProcessDetection = new ProcessProcessDetection(
+            Config.T32ProcessName,
+            Config.DetectionPeriod,
+            InfoFetcher,
+            DefaultApiClient
+        );
+        
         DefaultLogger.Debug("Main -> starting the ApiClient");
         var apiClientThread = new Thread(DefaultApiClient.Run) {
             IsBackground = true
         };
         apiClientThread.Start();
 
-        var admin = IsAdministrator();
-        DefaultLogger.Debug($"Is program executed with admin rights? {admin}");
+        var processThread = new Thread(processProcessDetection.RunPeriodicDetection) {
+            IsBackground = true
+        };
+        processThread.Start();
 
-        var networkTread = new Thread(NetDetect.RunPeriodicDetection);
-        networkTread.Start();
-        
-        if (admin) {
-            ProcDetect.RegisterProcessListeners();
-        } else {
-            var processThread = new Thread(ProcDetect.RunPeriodicDetection);
-            processThread.Start();
-            processThread.Join();
+        while (true) {
+            Thread.Sleep(10 * 1000);
         }
-
-        networkTread.Join();
-
-        DefaultLogger.Debug("Main -> stopping the ApiClient");
-        DefaultApiClient.Stop();
-        apiClientThread.Join();
-        DefaultLogger.Debug("Main -> finished");
-        
         return 0;
     }
-
-    private static bool IsAdministrator() {
-        if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) {
-            return false;
-        }
-        var identity = WindowsIdentity.GetCurrent();
-        var principal = new WindowsPrincipal(identity);
-        return principal.IsInRole(WindowsBuiltInRole.Administrator);
-    }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 910d880..ad06abf 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -14,7 +14,6 @@
     "LogVerbosityType": 2,
     "LogFlowType": 0
   },
-
   "Network": {
     "ApiBaseAddress": "http://127.0.0.1",
     "ApiLDEndPoint": "/lauterbach-debugger-logs/",
@@ -27,9 +26,7 @@
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
-    "T32Address": "localhost",
-    "T32Port": 20000,
-    "T32ProcessName": "t32mtc",
+    "T32ProcessName": "ld_mock",
     "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt",
     "DetectionPeriod": 5000
   }
diff --git a/ld_client/LDClient/detection/IDetection.cs b/ld_client/LDClient/detection/IDetection.cs
deleted file mode 100644
index 4d42eea..0000000
--- a/ld_client/LDClient/detection/IDetection.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LDClient.detection {
-    internal interface IDetection {
-
-        public void DetectAsync();
-
-        public void RunPeriodicDetection();
-        public void StopPeriodicDetection();
-    }
-}
diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs
new file mode 100644
index 0000000..26782e1
--- /dev/null
+++ b/ld_client/LDClient/detection/IProcessDetection.cs
@@ -0,0 +1,7 @@
+namespace LDClient.detection {
+    
+    internal interface IProcessDetection {
+        
+        public void RunPeriodicDetection();
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
new file mode 100644
index 0000000..c224b31
--- /dev/null
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -0,0 +1,72 @@
+using System.Diagnostics;
+using LDClient.utils;
+
+namespace LDClient.detection {
+
+    public class InfoFetcher {
+
+        private const string F32RemExecutable = "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock";
+        private const string F32RemArguments = "localhost port=20000 VERSION.HARDWARE";
+        private const string UndefinedSerialNumber = "number";
+
+        private readonly int _maxAttempts;
+        private readonly int _waitPeriodMs;
+        private readonly string _infoFilePath;
+
+        public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber;
+        public string BodySerialNumber { get; private set; } = UndefinedSerialNumber;
+
+        public InfoFetcher(int maxAttempts, int waitPeriodMs, string infoFilePath) {
+            _maxAttempts = maxAttempts;
+            _waitPeriodMs = waitPeriodMs;
+            _infoFilePath = infoFilePath;
+        }
+
+        public async Task<bool> FetchDataAsync() {
+            Program.DefaultLogger.Info("Fetching data from the debugger.");
+            var success = await SendRetrieveInfoCommandAsync(F32RemExecutable, F32RemArguments);
+            if (!success) {
+                Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
+                return false;
+            }
+            for (var i = 0; i < _maxAttempts; i++) {
+                Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");
+                if (RetrieveDebuggerInfo(_infoFilePath)) {
+                    Program.DefaultLogger.Info($"Info file has been parsed successfully.");
+                    return true;
+                }
+                await Task.Delay(_waitPeriodMs);
+            }
+            Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
+            return false;
+        }
+
+        private bool RetrieveDebuggerInfo(string filePath) {
+            try {
+                var fileContent = IoUtils.ReadFile(filePath);
+                var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
+                HeadSerialNumber = headSerialNumber;
+                BodySerialNumber = bodySerialNumber;
+                File.Delete(filePath);
+            } catch (Exception exception) {
+                Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
+                return false;
+            }
+            return true;
+        }
+
+        private static async Task<bool> SendRetrieveInfoCommandAsync(string executableFile, string arguments) {
+            var t32RemProcess = new Process();
+            t32RemProcess.StartInfo.FileName = executableFile;
+            t32RemProcess.StartInfo.Arguments = arguments;
+            try {
+                t32RemProcess.Start();
+                await t32RemProcess.WaitForExitAsync();
+            } catch (Exception exception) {
+                Program.DefaultLogger.Error($"Failed to run {executableFile}. {exception.Message}");
+                return false;
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/NetworkDetection.cs b/ld_client/LDClient/detection/NetworkDetection.cs
deleted file mode 100644
index 83b0bcc..0000000
--- a/ld_client/LDClient/detection/NetworkDetection.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace LDClient.detection {
-    public class NetworkDetection : IDetection {
-
-        private readonly uint _port;
-
-        private bool _isRunning;
-        
-        private readonly uint _detectionPeriod;
-
-        public NetworkDetection(uint port, uint detectionPeriod) {
-            this._port = port;
-            this._detectionPeriod = detectionPeriod;
-        }
-
-        public void DetectAsync() {
-
-            var listeners = System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners();
-
-            Program.DefaultLogger.Debug($"NetworkDetection -> Checking all currently listening.");
-            foreach (var listener in listeners) {
-                //Program.DefaultLogger.Debug($"{listener.Address}:{listener.Port}");
-                if (listener.Port == _port) {
-                    Program.DefaultLogger.Info($"Found some process listening on {listener.Address}:{_port}");
-                }
-            }
-
-        }
-
-
-        public void RunPeriodicDetection() {
-            Program.DefaultLogger.Info("Network periodic detector has started");
-            _isRunning = true;
-            while (_isRunning) {
-                DetectAsync();
-                Thread.Sleep((int)_detectionPeriod);
-            }
-        }
-
-        public void StopPeriodicDetection() {
-            _isRunning = false;
-        }
-    }
-}
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
deleted file mode 100644
index 77ebca2..0000000
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ /dev/null
@@ -1,92 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System;
-using System.Management;
-
-namespace LDClient.detection {
-    public class ProcessDetection : IDetection {
-
-        private const string ProcessStartQuery = "SELECT * FROM Win32_ProcessStartTrace";
-        private const string ProcessStopQuery = "SELECT * FROM Win32_ProcessStopTrace";
-
-        private ManagementEventWatcher _stopWatch;
-
-        private bool _isRunning;
-
-        private readonly string _processName;
-        private readonly uint _detectionPeriod;
-        private bool _processActive;
-        public ProcessDetection(string processName, uint detectionPeriod) {
-            this._processName = processName;
-            this._detectionPeriod = detectionPeriod;
-        }
-
-
-        public void DetectAsync() {
-            var processes = Process.GetProcessesByName(_processName);
-            Program.DefaultLogger.Info($"Found {processes.Length} processes with name: {_processName}");
-            var processFound = false;
-            foreach (var process in processes) {
-                if (process.ProcessName.Equals(_processName)) {
-                    if (!_processActive) {
-                        Program.DefaultLogger.Info($"Process started: {_processName}");
-                    }
-                    _processActive = true;
-                    processFound = true;
-                    break;
-                }
-                Console.WriteLine(process);
-            }
-
-            if (!processFound) {
-                if (_processActive) {
-                    Program.DefaultLogger.Info($"Process stopped: {_processName}");
-                }
-                _processActive = false;
-            }
-        }
-
-
-        public void RunPeriodicDetection() {
-
-            Program.DefaultLogger.Info("Process periodic detector has started");
-            _isRunning = true;
-            while (_isRunning) {
-                DetectAsync();
-                Thread.Sleep((int)_detectionPeriod);
-            }
-        }
-
-        public void StopPeriodicDetection() {
-            _isRunning = false;
-        }
-
-
-        public void RegisterProcessListeners() {
-            ManagementEventWatcher startWatch = new ManagementEventWatcher(
-                new WqlEventQuery(ProcessStartQuery));
-            startWatch.EventArrived += startWatch_EventArrived;
-            startWatch.Start();
-
-            _stopWatch = new ManagementEventWatcher(
-                new WqlEventQuery(ProcessStopQuery));
-            _stopWatch.EventArrived += stopWatch_EventArrived;
-            _stopWatch.Start();
-        }
-
-        void stopWatch_EventArrived(object sender, EventArrivedEventArgs e) {
-            var processName = e.NewEvent.Properties["ProcessName"].Value.ToString();
-            if (processName.Equals(_processName + ".exe")) {
-                Program.DefaultLogger.Info($"Process stopped: {processName}");
-            }
-        }
-
-        void startWatch_EventArrived(object sender, EventArrivedEventArgs e) {
-            var processName = e.NewEvent.Properties["ProcessName"].Value.ToString();
-            if (processName.Equals(_processName + ".exe")) {
-                Program.DefaultLogger.Info($"Process started: {processName}");
-            }
-        }
-    }
-}
diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs
new file mode 100644
index 0000000..d30f311
--- /dev/null
+++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs
@@ -0,0 +1,87 @@
+using System.Diagnostics;
+using LDClient.network;
+using LDClient.network.data;
+
+namespace LDClient.detection {
+   
+	 public class ProcessProcessDetection : IProcessDetection {
+        
+        private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
+        
+        private readonly string _processName;
+        private readonly uint _detectionPeriodMs;
+        private bool _processIsActive;
+        private bool _failedToRetrieveData;
+        private Payload? _lastlyConnected;
+
+        private readonly InfoFetcher _infoFetcher;
+        private readonly IApiClient _apiClient;
+
+        public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) {
+            _processName = processName;
+            _detectionPeriodMs = detectionPeriodMs;
+            _infoFetcher = infoFetcher;
+            _apiClient = apiClient;
+            _failedToRetrieveData = false;
+        }
+
+        private async Task<bool> RetrieveDataFromDebugger() {
+            var success = await _infoFetcher.FetchDataAsync();
+            if (success) {
+                _lastlyConnected = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat);
+            }
+            return success;
+        }
+
+        private async Task DebuggerDisconnected() {
+            if (_lastlyConnected is not null) {
+                _lastlyConnected.Status = ConnectionStatus.Disconnected;
+                _lastlyConnected.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
+                await _apiClient.SendPayloadAsync(_lastlyConnected);
+                _lastlyConnected = null;
+            }
+        }
+
+        private async Task DetectProcessAsync() {
+            var processExists = Process.GetProcessesByName(_processName).Length > 0;
+
+            if (processExists && !_processIsActive) {
+                Program.DefaultLogger.Info($"Process started: {_processName}");
+                if (!_failedToRetrieveData) {
+                    _failedToRetrieveData = !await RetrieveDataFromDebugger();
+                }
+            } else if (!processExists && _processIsActive) {
+                Program.DefaultLogger.Info($"Process stopped: {_processName}");
+                _failedToRetrieveData = false;
+                await DebuggerDisconnected();
+            }
+            _processIsActive = processExists;
+        }
+        
+        private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
+            Payload payload = new() {
+                UserName = Environment.UserName,
+                HostName = Environment.MachineName,
+                TimeStamp = DateTime.Now.ToString(datetimeFormat),
+                HeadDevice = new DebuggerInfo {
+                    SerialNumber = headSerialNumber
+                },
+                BodyDevice = new DebuggerInfo {
+                    SerialNumber = bodySerialNumber
+                },
+                Status = ConnectionStatus.Connected
+            };
+            await _apiClient.SendPayloadAsync(payload);
+            return payload;
+        }
+        
+        public async void RunPeriodicDetection() {
+            Program.DefaultLogger.Info("Process periodic detector has started");
+            while (true) {
+                await DetectProcessAsync();
+                Thread.Sleep((int)_detectionPeriodMs);
+            }
+            // ReSharper disable once FunctionNeverReturns
+        }
+    }
+}
diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index dbbbf7b..61766cf 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -7,24 +7,9 @@ using DiskQueue;
 using LDClient.network.data;
 
 namespace LDClient.network {
+    
     public class ApiClient : IApiClient {
         
-        public static readonly Payload ExampleInfo = new() {
-            UserName = "honikCz",
-            HostName = "Bramborak",
-            TimeStamp = DateTime.Parse("2022-03-21 18:05:00.168895"),
-            HeadDevice = new DebuggerInfo {
-                SerialNumber = "C12345678912"
-            },
-            BodyDevice = new DebuggerInfo {
-                SerialNumber = "C98765432198"
-            },
-            Status = ConnectionStatus.Connected
-        };
-
-        private bool _running;
-
-
         private readonly string _uri;
         private readonly HttpClient _client;
         private readonly IPersistentQueue _cache;
@@ -32,8 +17,6 @@ namespace LDClient.network {
         private readonly uint _maxEntries;
         private readonly uint _maxRetries;
         
-
-
         public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries,
             string cacheFilename) {
             _uri = $"{url}:{port}{path}";
@@ -43,7 +26,6 @@ namespace LDClient.network {
 
             _client = new HttpClient();
             _cache = new PersistentQueue(cacheFilename);
-
         }
 
         public async Task SendPayloadAsync(Payload payload) {
@@ -55,7 +37,6 @@ namespace LDClient.network {
                     Converters = {
                         new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
                     }
-
                 });
                 stopWatch.Stop();
                 CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds);
@@ -80,7 +61,6 @@ namespace LDClient.network {
                                  $"Response: {responseToLog}");
         }
         
-
         private async Task ResendPayloadsAsync() {
             var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);
             var payloads = new List<Payload>();
@@ -106,8 +86,7 @@ namespace LDClient.network {
                 await Task.WhenAll(tasks);
             }
         }
-
-
+        
         private void CachePayload(Payload payload) {
             Program.DefaultLogger.Info($"Storing {payload} into the cache.");
             var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue;
@@ -122,15 +101,11 @@ namespace LDClient.network {
 
         public async void Run() {
             Program.DefaultLogger.Info("Api Client thread has started");
-            _running = true;
-            while (_running) {
+            while (true) {
                 await ResendPayloadsAsync();
-                Thread.Sleep((int)_retryPeriod);
+                Thread.Sleep((int) _retryPeriod);
             }
-        }
-
-        public void Stop() {
-            _running = false;
+            // ReSharper disable once FunctionNeverReturns
         }
     }
 }
diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs
index f5ea700..5574d23 100644
--- a/ld_client/LDClient/network/IApiClient.cs
+++ b/ld_client/LDClient/network/IApiClient.cs
@@ -1,9 +1,10 @@
 using LDClient.network.data;
 
 namespace LDClient.network {
+    
     public interface IApiClient {
+        
         public Task SendPayloadAsync(Payload payload);
         public void Run();
-        public void Stop();
     }
 }
diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs
index 30672d7..57b5755 100644
--- a/ld_client/LDClient/network/data/Payload.cs
+++ b/ld_client/LDClient/network/data/Payload.cs
@@ -8,21 +8,21 @@ namespace LDClient.network.data {
     public class Payload {
 
         [JsonPropertyName("username")]
-        public string UserName { get; set; }
+        public string? UserName { get; set; }
 
         [JsonPropertyName("hostname")]
-        public string HostName { get; set; }
+        public string? HostName { get; set; }
 
         [JsonPropertyName("timestamp")]
         //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")]
-        public DateTime TimeStamp { get; set; }
+        public string? TimeStamp { get; set; }
 
         [JsonPropertyName("head_device")]
-        public DebuggerInfo HeadDevice { get; set; }
+        public DebuggerInfo? HeadDevice { get; set; }
 
 
         [JsonPropertyName("body_device")]
-        public DebuggerInfo  BodyDevice { get; set; }
+        public DebuggerInfo?  BodyDevice { get; set; }
         
         [JsonPropertyName("status")]
         //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index b45b9f8..a84708d 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -2,44 +2,47 @@
 using Microsoft.Extensions.Configuration;
 
 namespace LDClient.utils {
+    
     internal class ConfigLoader {
+        
         private const string LoggingSection = "Logging";
         private const string NetworkSection = "Network";
         private const string CacheSection = "Cache";
-        private const string DDSection = "DebuggerDetection";
+        private const string DdSection = "DebuggerDetection";
 
         #region Logger
-        public int LogChunkSize { get; set; }
-        public int LogChunkMaxCount { get; set; }
-        public int LogArchiveMaxCount { get; set; }
-
-        public int LogCleanupPeriod { get; set; }
-
-        public LogVerbosity LogVerbosityType { get; set; } = LogVerbosity.Full;
-
-        public LogFlow LogFlowType { get; set; } = LogFlow.Console;
+        
+        public int LogChunkSize { get; private set; }
+        public int LogChunkMaxCount { get; private set; }
+        public int LogArchiveMaxCount { get; private set; }
+
+        public int LogCleanupPeriod { get; private set; }
+        public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full;
+        public LogFlow LogFlowType { get; private set; } = LogFlow.Console;
+        
         #endregion
 
         #region Api
-        public string ApiBaseAddress { get; set; }
-        public string ApiUsbEndPoint { get; set; }
-        public uint ApiPort { get; set; }
+        
+        public string ApiBaseAddress { get; private set; }
+        public string ApiUsbEndPoint { get; private set; }
+        public uint ApiPort { get; private set; }
 
         #endregion
 
         #region Cache
-        public string CacheFileName { get; set; }
-        public uint MaxRetries { get; set; }
-        public uint MaxEntries { get; set; }
-        public uint RetryPeriod { get; set; }
+        
+        public string CacheFileName { get; private set; }
+        public uint MaxRetries { get; private set; }
+        public uint MaxEntries { get; private set; }
+        public uint RetryPeriod { get; private set; }
+        
         #endregion
 
         #region Detection
-        public string T32Address { get; set; }
-        public int T32Port { get; set; }
-        public string T32ProcessName { get; set; }
-        public uint DetectionPeriod { get; set; }
-        public string T32InfoLocation { get; set; }
+        public string T32ProcessName { get; private set; }
+        public uint DetectionPeriod { get; private set; }
+        public string T32InfoLocation { get; private set; }
         #endregion
 
         public ConfigLoader() {
@@ -49,7 +52,7 @@ namespace LDClient.utils {
             ReadAllSettings(configuration);
         }
 
-        private void ReadAllSettings(IConfigurationRoot configuration) {
+        private void ReadAllSettings(IConfiguration configuration) {
 
             try {
                 var logging = configuration.GetSection(LoggingSection);
@@ -74,9 +77,7 @@ namespace LDClient.utils {
                 CacheFileName = cache["CacheFileName"];
 
 
-                var debugger = configuration.GetSection(DDSection);
-                T32Address = debugger["T32Address"];
-                T32Port = int.Parse(debugger["T32Port"]);
+                var debugger = configuration.GetSection(DdSection);
                 T32ProcessName = debugger["T32ProcessName"];
                 T32InfoLocation = debugger["T32InfoLocation"];
                 DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);
-- 
GitLab


From 6dab02506aa03a14324e3633765716e1f8bbbff3 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sun, 17 Apr 2022 18:20:02 +0200
Subject: [PATCH 25/67] re #9566 Moved magic values into the configuration
 file.

---
 ld_client/LDClient/Program.cs                 | 17 ++++++++++-------
 ld_client/LDClient/appsettings.json           |  8 ++++++--
 ld_client/LDClient/detection/InfoFetcher.cs   | 19 +++++++++++--------
 .../detection/ProcessProcessDetection.cs      | 19 ++++++++++---------
 ld_client/LDClient/utils/ConfigLoader.cs      | 19 +++++++++++++------
 ld_client/Mock/t32rem/t32rem_mock.cpp         |  2 +-
 6 files changed, 51 insertions(+), 33 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 577a284..253ec64 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -10,19 +10,22 @@ namespace LDClient;
 
 internal static class Program {
 
+    private const int MainLoopDelayMs = 30000; 
+
     public static ConfigLoader Config { get; } = new();
     public static ALogger DefaultLogger { get; } = ALogger.Current;
     private static IApiClient? DefaultApiClient { get; set; }
     
     private static readonly InfoFetcher InfoFetcher = new(
-        5,
-        1000,
-        "output.txt"
+        Config.FetchInfoMaxAttempts,
+        Config.FetchInfoAttemptPeriod,
+        Config.T32InfoLocation,
+        Config.F32RemExecutable,
+        Config.F32RemArguments
     );
     
     public static int Main() {
-        var exists = GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1;
-        if (exists) {
+        if (GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1) {
             DefaultLogger.Error("Another instance of the application is already running");
             return 1;
         }
@@ -43,7 +46,6 @@ internal static class Program {
             DefaultApiClient
         );
         
-        DefaultLogger.Debug("Main -> starting the ApiClient");
         var apiClientThread = new Thread(DefaultApiClient.Run) {
             IsBackground = true
         };
@@ -55,8 +57,9 @@ internal static class Program {
         processThread.Start();
 
         while (true) {
-            Thread.Sleep(10 * 1000);
+            Thread.Sleep(MainLoopDelayMs);
         }
+        
         return 0;
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index ad06abf..f882d0c 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -26,8 +26,12 @@
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
+    "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock",
+    "F32RemArguments": "localhost port=20000 VERSION.HARDWARE",
     "T32ProcessName": "ld_mock",
-    "T32InfoLocation": "C:\\app\\tools\\T32\\results\\ldResult.txt",
-    "DetectionPeriod": 5000
+    "T32InfoLocation": "ldResult.txt",
+    "DetectionPeriod": 5000,
+    "FetchInfoMaxAttempts": 5,
+    "FetchInfoAttemptPeriod": 1000
   }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index c224b31..0a5d3e6 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -4,27 +4,30 @@ using LDClient.utils;
 namespace LDClient.detection {
 
     public class InfoFetcher {
-
-        private const string F32RemExecutable = "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock";
-        private const string F32RemArguments = "localhost port=20000 VERSION.HARDWARE";
+        
         private const string UndefinedSerialNumber = "number";
 
-        private readonly int _maxAttempts;
-        private readonly int _waitPeriodMs;
+        private readonly string _f32RemExecutable;
+        private readonly string _f32RemArguments;
+        
+        private readonly uint _maxAttempts;
+        private readonly uint _waitPeriodMs;
         private readonly string _infoFilePath;
 
         public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber;
         public string BodySerialNumber { get; private set; } = UndefinedSerialNumber;
 
-        public InfoFetcher(int maxAttempts, int waitPeriodMs, string infoFilePath) {
+        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string f32RemArguments) {
             _maxAttempts = maxAttempts;
             _waitPeriodMs = waitPeriodMs;
             _infoFilePath = infoFilePath;
+            _f32RemExecutable = f32RemExecutable;
+            _f32RemArguments = f32RemArguments;
         }
 
         public async Task<bool> FetchDataAsync() {
             Program.DefaultLogger.Info("Fetching data from the debugger.");
-            var success = await SendRetrieveInfoCommandAsync(F32RemExecutable, F32RemArguments);
+            var success = await SendRetrieveInfoCommandAsync(_f32RemExecutable, _f32RemArguments);
             if (!success) {
                 Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
                 return false;
@@ -35,7 +38,7 @@ namespace LDClient.detection {
                     Program.DefaultLogger.Info($"Info file has been parsed successfully.");
                     return true;
                 }
-                await Task.Delay(_waitPeriodMs);
+                await Task.Delay((int)_waitPeriodMs);
             }
             Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
             return false;
diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs
index d30f311..69ab0dc 100644
--- a/ld_client/LDClient/detection/ProcessProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs
@@ -1,4 +1,5 @@
 using System.Diagnostics;
+using System.Text.Json;
 using LDClient.network;
 using LDClient.network.data;
 
@@ -7,12 +8,12 @@ namespace LDClient.detection {
 	 public class ProcessProcessDetection : IProcessDetection {
         
         private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
-        
+
         private readonly string _processName;
         private readonly uint _detectionPeriodMs;
         private bool _processIsActive;
         private bool _failedToRetrieveData;
-        private Payload? _lastlyConnected;
+        private Payload? _lastConnectedPayload;
 
         private readonly InfoFetcher _infoFetcher;
         private readonly IApiClient _apiClient;
@@ -28,17 +29,17 @@ namespace LDClient.detection {
         private async Task<bool> RetrieveDataFromDebugger() {
             var success = await _infoFetcher.FetchDataAsync();
             if (success) {
-                _lastlyConnected = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat);
+                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat);
             }
             return success;
         }
-
+        
         private async Task DebuggerDisconnected() {
-            if (_lastlyConnected is not null) {
-                _lastlyConnected.Status = ConnectionStatus.Disconnected;
-                _lastlyConnected.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
-                await _apiClient.SendPayloadAsync(_lastlyConnected);
-                _lastlyConnected = null;
+            if (_lastConnectedPayload is not null) {
+                _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
+                _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
+                await _apiClient.SendPayloadAsync(_lastConnectedPayload);
+                _lastConnectedPayload = null;
             }
         }
 
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index a84708d..5709adc 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -1,4 +1,5 @@
-using LDClient.utils.loggers;
+using System.Runtime.InteropServices;
+using LDClient.utils.loggers;
 using Microsoft.Extensions.Configuration;
 
 namespace LDClient.utils {
@@ -15,7 +16,6 @@ namespace LDClient.utils {
         public int LogChunkSize { get; private set; }
         public int LogChunkMaxCount { get; private set; }
         public int LogArchiveMaxCount { get; private set; }
-
         public int LogCleanupPeriod { get; private set; }
         public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full;
         public LogFlow LogFlowType { get; private set; } = LogFlow.Console;
@@ -43,6 +43,11 @@ namespace LDClient.utils {
         public string T32ProcessName { get; private set; }
         public uint DetectionPeriod { get; private set; }
         public string T32InfoLocation { get; private set; }
+        public string F32RemExecutable { get; private set; }
+        public string F32RemArguments { get; private set; }
+        public uint FetchInfoMaxAttempts { get; private set;  }
+        public uint FetchInfoAttemptPeriod { get; private set; }
+        
         #endregion
 
         public ConfigLoader() {
@@ -68,19 +73,21 @@ namespace LDClient.utils {
                 ApiBaseAddress = network["ApiBaseAddress"];
                 ApiUsbEndPoint = network["ApiLDEndPoint"];
                 ApiPort = uint.Parse(network["ApiPort"]);
-
-
+                
                 var cache = configuration.GetSection(CacheSection);
                 RetryPeriod = uint.Parse(cache["RetryPeriod"]);
                 MaxEntries = uint.Parse(cache["MaxEntries"]);
                 MaxRetries = uint.Parse(cache["MaxRetries"]);
                 CacheFileName = cache["CacheFileName"];
-
-
+                
                 var debugger = configuration.GetSection(DdSection);
                 T32ProcessName = debugger["T32ProcessName"];
                 T32InfoLocation = debugger["T32InfoLocation"];
                 DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);
+                F32RemExecutable = debugger["F32RemExecutable"];
+                F32RemArguments = debugger["F32RemArguments"];
+                FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]);
+                FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]);
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
diff --git a/ld_client/Mock/t32rem/t32rem_mock.cpp b/ld_client/Mock/t32rem/t32rem_mock.cpp
index 5c05734..0d601f4 100644
--- a/ld_client/Mock/t32rem/t32rem_mock.cpp
+++ b/ld_client/Mock/t32rem/t32rem_mock.cpp
@@ -7,7 +7,7 @@
 #include <cstring>
 
 static constexpr int EXPECTED_NUMBER_OF_ARGUMENTS = 4;
-static constexpr const char *OUTPUT_FILE_NAME = "output.txt";
+static constexpr const char *OUTPUT_FILE_NAME = "ldResult.txt";
 static constexpr const char *DEBUGGER_INFO =
         "B::version.hardware\n"
         "PowerDebug USB 3.0 via USB 3.0\n"
-- 
GitLab


From 08616eff184beaa5e3f8c3668b9612f7febfce82 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Mon, 18 Apr 2022 09:59:54 +0200
Subject: [PATCH 26/67] re #9566 Removed IoUtils.cs since it was being used
 only in one place.

---
 ld_client/LDClient/detection/InfoFetcher.cs             | 3 +--
 ld_client/LDClient/detection/ProcessProcessDetection.cs | 3 +--
 ld_client/LDClient/utils/IoUtils.cs                     | 9 ---------
 3 files changed, 2 insertions(+), 13 deletions(-)
 delete mode 100644 ld_client/LDClient/utils/IoUtils.cs

diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index 0a5d3e6..f5a0dde 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -1,5 +1,4 @@
 using System.Diagnostics;
-using LDClient.utils;
 
 namespace LDClient.detection {
 
@@ -46,7 +45,7 @@ namespace LDClient.detection {
 
         private bool RetrieveDebuggerInfo(string filePath) {
             try {
-                var fileContent = IoUtils.ReadFile(filePath);
+                var fileContent = File.ReadAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
                 var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
                 HeadSerialNumber = headSerialNumber;
                 BodySerialNumber = bodySerialNumber;
diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessProcessDetection.cs
index 69ab0dc..0ca4007 100644
--- a/ld_client/LDClient/detection/ProcessProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessProcessDetection.cs
@@ -1,5 +1,4 @@
 using System.Diagnostics;
-using System.Text.Json;
 using LDClient.network;
 using LDClient.network.data;
 
@@ -33,7 +32,7 @@ namespace LDClient.detection {
             }
             return success;
         }
-        
+
         private async Task DebuggerDisconnected() {
             if (_lastConnectedPayload is not null) {
                 _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
diff --git a/ld_client/LDClient/utils/IoUtils.cs b/ld_client/LDClient/utils/IoUtils.cs
deleted file mode 100644
index 7bf3a65..0000000
--- a/ld_client/LDClient/utils/IoUtils.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace LDClient.utils {
-
-    public static class IoUtils {
-
-        public static string ReadFile(string filename) {
-            return File.ReadAllLines(filename).Aggregate("", (current, line) => $"{current}{line}\n");
-        }
-    }
-}
\ No newline at end of file
-- 
GitLab


From e51590bee040f5acacedb7f3a1b58c951bc4b3f1 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 21 Apr 2022 09:53:04 +0200
Subject: [PATCH 27/67] re #9568 Fixed a typo in the filename.

---
 .../detection/{ProcessProcessDetection.cs => ProcessDetection.cs} | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename ld_client/LDClient/detection/{ProcessProcessDetection.cs => ProcessDetection.cs} (100%)

diff --git a/ld_client/LDClient/detection/ProcessProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
similarity index 100%
rename from ld_client/LDClient/detection/ProcessProcessDetection.cs
rename to ld_client/LDClient/detection/ProcessDetection.cs
-- 
GitLab


From 4dcc6c07a7c03999e5fefeea3314cbb01300167b Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 21 Apr 2022 10:58:24 +0200
Subject: [PATCH 28/67] re #9568 Added all 4 commands (arguments) to be sent to
 the debugger into the configuration file.

---
 ld_client/LDClient/Program.cs               |  4 ++-
 ld_client/LDClient/appsettings.json         | 13 ++++++--
 ld_client/LDClient/detection/InfoFetcher.cs | 37 ++++++++++++++-------
 ld_client/LDClient/utils/ConfigLoader.cs    | 10 ++++--
 4 files changed, 45 insertions(+), 19 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 253ec64..c58d5b8 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -21,7 +21,9 @@ internal static class Program {
         Config.FetchInfoAttemptPeriod,
         Config.T32InfoLocation,
         Config.F32RemExecutable,
-        Config.F32RemArguments
+        Config.F32RemArguments,
+        Config.T32RemSuccessExitCode,
+        Config.T32RemWaitTimeoutMs
     );
     
     public static int Main() {
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index f882d0c..0104ce2 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -26,12 +26,19 @@
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
+    "F32RemArguments" : [
+      "localhost port=20000 printer.filetype ASCIIE",
+      "localhost port=20000 printer.open C:\\Users\\pulta\\Desktop\\testResult.txt",
+      "localhost port=20000 WinPrint.version.hardware",
+      "localhost port=20000 printer.close"
+    ],
     "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock",
-    "F32RemArguments": "localhost port=20000 VERSION.HARDWARE",
     "T32ProcessName": "ld_mock",
-    "T32InfoLocation": "ldResult.txt",
+    "T32InfoLocation": "C:\\Users\\pulta\\Desktop\\testResult.txt",
     "DetectionPeriod": 5000,
     "FetchInfoMaxAttempts": 5,
-    "FetchInfoAttemptPeriod": 1000
+    "FetchInfoAttemptPeriod": 1000,
+    "T32RemSuccessExitCode": 0,
+    "T32RemWaitTimeoutMs": 2000
   }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index f5a0dde..ffa36b7 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -7,7 +7,9 @@ namespace LDClient.detection {
         private const string UndefinedSerialNumber = "number";
 
         private readonly string _f32RemExecutable;
-        private readonly string _f32RemArguments;
+        private readonly string[] _f32RemArguments;
+        private readonly int _f32SuccessExitCode;
+        private readonly int _f32WaitTimeoutMs;
         
         private readonly uint _maxAttempts;
         private readonly uint _waitPeriodMs;
@@ -16,17 +18,19 @@ namespace LDClient.detection {
         public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber;
         public string BodySerialNumber { get; private set; } = UndefinedSerialNumber;
 
-        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string f32RemArguments) {
+        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {
             _maxAttempts = maxAttempts;
             _waitPeriodMs = waitPeriodMs;
             _infoFilePath = infoFilePath;
             _f32RemExecutable = f32RemExecutable;
             _f32RemArguments = f32RemArguments;
+            _f32SuccessExitCode = f32SuccessExitCode;
+            _f32WaitTimeoutMs = f32WaitTimeoutMs;
         }
 
         public async Task<bool> FetchDataAsync() {
             Program.DefaultLogger.Info("Fetching data from the debugger.");
-            var success = await SendRetrieveInfoCommandAsync(_f32RemExecutable, _f32RemArguments);
+            var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs);
             if (!success) {
                 Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
                 return false;
@@ -57,17 +61,26 @@ namespace LDClient.detection {
             return true;
         }
 
-        private static async Task<bool> SendRetrieveInfoCommandAsync(string executableFile, string arguments) {
-            var t32RemProcess = new Process();
-            t32RemProcess.StartInfo.FileName = executableFile;
-            t32RemProcess.StartInfo.Arguments = arguments;
-            try {
-                t32RemProcess.Start();
-                await t32RemProcess.WaitForExitAsync();
-            } catch (Exception exception) {
-                Program.DefaultLogger.Error($"Failed to run {executableFile}. {exception.Message}");
+        private static bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int successExitCode, int waitTimeoutMs) {
+            if (arguments == null) {
+                Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given");
                 return false;
             }
+            foreach (var argument in arguments) {
+                var t32RemProcess = new Process();
+                t32RemProcess.StartInfo.FileName = executableFile;
+                t32RemProcess.StartInfo.Arguments = argument;
+                try {
+                    t32RemProcess.Start();
+                    t32RemProcess.WaitForExit(waitTimeoutMs);
+                    if (t32RemProcess.ExitCode != successExitCode) {
+                        return false;
+                    }
+                } catch (Exception exception) {
+                    Program.DefaultLogger.Error($"Failed to run {executableFile} {argument}. {exception.Message}");
+                    return false;
+                }
+            }
             return true;
         }
     }
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 5709adc..b4ff02f 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -44,10 +44,12 @@ namespace LDClient.utils {
         public uint DetectionPeriod { get; private set; }
         public string T32InfoLocation { get; private set; }
         public string F32RemExecutable { get; private set; }
-        public string F32RemArguments { get; private set; }
         public uint FetchInfoMaxAttempts { get; private set;  }
         public uint FetchInfoAttemptPeriod { get; private set; }
-        
+        public string[] F32RemArguments { get; private set; }
+        public int T32RemSuccessExitCode { get; private set; }
+        public int T32RemWaitTimeoutMs { get; private set; }
+
         #endregion
 
         public ConfigLoader() {
@@ -85,9 +87,11 @@ namespace LDClient.utils {
                 T32InfoLocation = debugger["T32InfoLocation"];
                 DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);
                 F32RemExecutable = debugger["F32RemExecutable"];
-                F32RemArguments = debugger["F32RemArguments"];
                 FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]);
                 FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]);
+                T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]);
+                T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]);
+                F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray();
 
                 Console.WriteLine("Configuration successfully loaded!");
             } catch (FormatException e) {
-- 
GitLab


From b10bb2634e9ecc275dae86d67902fb5193a6f6ba Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Fri, 22 Apr 2022 08:58:50 +0200
Subject: [PATCH 29/67] re #9568 Broke config loader down into separate
 methods.

---
 ld_client/LDClient/Program.cs                 |  2 -
 .../LDClient/network/data/ConnectionStatus.cs |  3 +-
 .../LDClient/network/data/DebuggerInfo.cs     |  2 +-
 ld_client/LDClient/network/data/Payload.cs    |  3 +-
 ld_client/LDClient/utils/ConfigLoader.cs      | 69 ++++++++++++-------
 5 files changed, 50 insertions(+), 29 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index c58d5b8..fc2fb03 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -61,7 +61,5 @@ internal static class Program {
         while (true) {
             Thread.Sleep(MainLoopDelayMs);
         }
-        
-        return 0;
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs
index f5ea275..9cd1ded 100644
--- a/ld_client/LDClient/network/data/ConnectionStatus.cs
+++ b/ld_client/LDClient/network/data/ConnectionStatus.cs
@@ -1,11 +1,12 @@
 using System.Runtime.Serialization;
 
 namespace LDClient.network.data {
+    
     public enum ConnectionStatus {
+        
         [EnumMember(Value = "connected")]
         Connected,
         [EnumMember(Value = "disconnected")]
         Disconnected
-
     }
 }
diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs
index cb38d91..9402110 100644
--- a/ld_client/LDClient/network/data/DebuggerInfo.cs
+++ b/ld_client/LDClient/network/data/DebuggerInfo.cs
@@ -4,6 +4,6 @@ namespace LDClient.network.data {
     public class DebuggerInfo {
         
         [JsonPropertyName("serial_number")]
-        public string SerialNumber { get; set; }
+        public string? SerialNumber { get; set; }
     }
 }
diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs
index 57b5755..ae7302a 100644
--- a/ld_client/LDClient/network/data/Payload.cs
+++ b/ld_client/LDClient/network/data/Payload.cs
@@ -4,6 +4,7 @@ using Newtonsoft.Json;
 using JsonSerializer = System.Text.Json.JsonSerializer;
 
 namespace LDClient.network.data {
+    
     [JsonObject(MemberSerialization.OptIn)]
     public class Payload {
 
@@ -14,7 +15,6 @@ namespace LDClient.network.data {
         public string? HostName { get; set; }
 
         [JsonPropertyName("timestamp")]
-        //[Newtonsoft.Json.JsonConverter(typeof(DateFormatConverter), "yyyy-MM-dd HH:mm:ss.ffffff")]
         public string? TimeStamp { get; set; }
 
         [JsonPropertyName("head_device")]
@@ -25,7 +25,6 @@ namespace LDClient.network.data {
         public DebuggerInfo?  BodyDevice { get; set; }
         
         [JsonPropertyName("status")]
-        //[Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
         public ConnectionStatus Status { get; set; }
 
 
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index b4ff02f..b57a506 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -1,10 +1,12 @@
-using System.Runtime.InteropServices;
-using LDClient.utils.loggers;
+using LDClient.utils.loggers;
 using Microsoft.Extensions.Configuration;
 
 namespace LDClient.utils {
     
     internal class ConfigLoader {
+
+        private const int ErrorExitCode = 1;
+        private const string ConfigFile = "appsettings.json";
         
         private const string LoggingSection = "Logging";
         private const string NetworkSection = "Network";
@@ -24,15 +26,15 @@ namespace LDClient.utils {
 
         #region Api
         
-        public string ApiBaseAddress { get; private set; }
-        public string ApiUsbEndPoint { get; private set; }
+        public string ApiBaseAddress { get; private set; } = null!;
+        public string ApiUsbEndPoint { get; private set; } = null!;
         public uint ApiPort { get; private set; }
 
         #endregion
 
         #region Cache
         
-        public string CacheFileName { get; private set; }
+        public string CacheFileName { get; private set; } = null!;
         public uint MaxRetries { get; private set; }
         public uint MaxEntries { get; private set; }
         public uint RetryPeriod { get; private set; }
@@ -40,13 +42,13 @@ namespace LDClient.utils {
         #endregion
 
         #region Detection
-        public string T32ProcessName { get; private set; }
+        public string T32ProcessName { get; private set; } = null!;
         public uint DetectionPeriod { get; private set; }
-        public string T32InfoLocation { get; private set; }
-        public string F32RemExecutable { get; private set; }
+        public string T32InfoLocation { get; private set; } = null!;
+        public string F32RemExecutable { get; private set; } = null!;
         public uint FetchInfoMaxAttempts { get; private set;  }
         public uint FetchInfoAttemptPeriod { get; private set; }
-        public string[] F32RemArguments { get; private set; }
+        public string[] F32RemArguments { get; private set; } = null!;
         public int T32RemSuccessExitCode { get; private set; }
         public int T32RemWaitTimeoutMs { get; private set; }
 
@@ -54,34 +56,59 @@ namespace LDClient.utils {
 
         public ConfigLoader() {
             var configuration = new ConfigurationBuilder()
-                .AddJsonFile("appsettings.json")
+                .AddJsonFile(ConfigFile)
                 .Build();
-            ReadAllSettings(configuration);
-        }
 
-        private void ReadAllSettings(IConfiguration configuration) {
+            ReadLoggerSection(configuration);
+            ReadApiSection(configuration);
+            ReadCacheSection(configuration);
+            ReadDebuggerSection(configuration);
+            
+            Console.WriteLine("Configuration successfully loaded!");
+        }
 
+        private void ReadLoggerSection(IConfiguration configuration) {
             try {
                 var logging = configuration.GetSection(LoggingSection);
-                //TODO: Exception handling
                 LogChunkSize = int.Parse(logging["LogChunkSize"]);
                 LogChunkMaxCount = int.Parse(logging["LogChunkMaxCount"]);
                 LogArchiveMaxCount = int.Parse(logging["LogArchiveMaxCount"]);
                 LogCleanupPeriod = int.Parse(logging["LogCleanupPeriod"]);
                 LogFlowType = (LogFlow)int.Parse(logging["LogFlowType"]);
                 LogVerbosityType = (LogVerbosity)int.Parse(logging["LogVerbosityType"]);
+            } catch (Exception e) {
+                Console.WriteLine(e.Message);
+                Environment.Exit(ErrorExitCode);
+            }
+        }
 
+        private void ReadApiSection(IConfiguration configuration) {
+            try {
                 var network = configuration.GetSection(NetworkSection);
                 ApiBaseAddress = network["ApiBaseAddress"];
                 ApiUsbEndPoint = network["ApiLDEndPoint"];
                 ApiPort = uint.Parse(network["ApiPort"]);
-                
+            } catch (Exception e) {
+                Console.WriteLine(e.Message);
+                Environment.Exit(ErrorExitCode);
+            }
+        }
+
+        private void ReadCacheSection(IConfiguration configuration) {
+            try {
                 var cache = configuration.GetSection(CacheSection);
                 RetryPeriod = uint.Parse(cache["RetryPeriod"]);
                 MaxEntries = uint.Parse(cache["MaxEntries"]);
                 MaxRetries = uint.Parse(cache["MaxRetries"]);
                 CacheFileName = cache["CacheFileName"];
-                
+            } catch (Exception e) {
+                Console.WriteLine(e.Message);
+                Environment.Exit(ErrorExitCode);
+            }
+        }
+
+        private void ReadDebuggerSection(IConfiguration configuration) {
+            try {
                 var debugger = configuration.GetSection(DdSection);
                 T32ProcessName = debugger["T32ProcessName"];
                 T32InfoLocation = debugger["T32InfoLocation"];
@@ -92,13 +119,9 @@ namespace LDClient.utils {
                 T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]);
                 T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]);
                 F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray();
-
-                Console.WriteLine("Configuration successfully loaded!");
-            } catch (FormatException e) {
-                //Console.WriteLine("Error reading app settings");
-                //TODO: remove stacktrace print in production
-                Console.WriteLine("Error during reading of configuration occurred!" + e);
-                throw new IOException("Reading of configuration file failed! " + e);
+            } catch (Exception e) {
+                Console.WriteLine(e);
+                Environment.Exit(ErrorExitCode);
             }
         }
     }
-- 
GitLab


From 33c231a4432727c0fed200278aadc43c61a1228b Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sat, 23 Apr 2022 14:49:19 +0200
Subject: [PATCH 30/67] re #9568 Fixed formatting

---
 ld_client/LDClient/detection/InfoFetcher.cs      | 1 -
 ld_client/LDClient/detection/ProcessDetection.cs | 8 ++++----
 ld_client/LDClient/network/ApiClient.cs          | 5 ++---
 ld_client/LDClient/utils/ConfigLoader.cs         | 1 -
 4 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index ffa36b7..86f601e 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -10,7 +10,6 @@ namespace LDClient.detection {
         private readonly string[] _f32RemArguments;
         private readonly int _f32SuccessExitCode;
         private readonly int _f32WaitTimeoutMs;
-        
         private readonly uint _maxAttempts;
         private readonly uint _waitPeriodMs;
         private readonly string _infoFilePath;
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
index 0ca4007..fb68c65 100644
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -4,19 +4,19 @@ using LDClient.network.data;
 
 namespace LDClient.detection {
    
-	 public class ProcessProcessDetection : IProcessDetection {
+	 public sealed class ProcessProcessDetection : IProcessDetection {
         
         private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
 
         private readonly string _processName;
         private readonly uint _detectionPeriodMs;
+        private readonly InfoFetcher _infoFetcher;
+        private readonly IApiClient _apiClient;
+        
         private bool _processIsActive;
         private bool _failedToRetrieveData;
         private Payload? _lastConnectedPayload;
 
-        private readonly InfoFetcher _infoFetcher;
-        private readonly IApiClient _apiClient;
-
         public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) {
             _processName = processName;
             _detectionPeriodMs = detectionPeriodMs;
diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 61766cf..01043bf 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -8,7 +8,7 @@ using LDClient.network.data;
 
 namespace LDClient.network {
     
-    public class ApiClient : IApiClient {
+    public sealed class ApiClient : IApiClient {
         
         private readonly string _uri;
         private readonly HttpClient _client;
@@ -17,8 +17,7 @@ namespace LDClient.network {
         private readonly uint _maxEntries;
         private readonly uint _maxRetries;
         
-        public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries,
-            string cacheFilename) {
+        public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) {
             _uri = $"{url}:{port}{path}";
             _retryPeriod = retryPeriod;
             _maxEntries = maxEntries;
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index b57a506..a2a5627 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -7,7 +7,6 @@ namespace LDClient.utils {
 
         private const int ErrorExitCode = 1;
         private const string ConfigFile = "appsettings.json";
-        
         private const string LoggingSection = "Logging";
         private const string NetworkSection = "Network";
         private const string CacheSection = "Cache";
-- 
GitLab


From 19c2a5c43d5f8e4972e82fb2764e55f96251a27a Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 23 Apr 2022 15:26:37 +0200
Subject: [PATCH 31/67] re #9568 Fixed a typo in the config file

---
 ld_client/LDClient/appsettings.json         | 12 ++++++------
 ld_client/LDClient/detection/InfoFetcher.cs |  7 ++++++-
 ld_client/LDClient/utils/ConfigLoader.cs    |  2 +-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 0104ce2..4826407 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -26,15 +26,15 @@
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
-    "F32RemArguments" : [
+    "F32RemArguments": [
       "localhost port=20000 printer.filetype ASCIIE",
-      "localhost port=20000 printer.open C:\\Users\\pulta\\Desktop\\testResult.txt",
+      "localhost port=20000 printer.open C:\\app\\result.txt",
       "localhost port=20000 WinPrint.version.hardware",
-      "localhost port=20000 printer.close"
+      "localhost port=20000 printer.close "
     ],
-    "F32RemExecutable": "/home/silhavyj/School/KIV-ASWI/aswi2022bug-thugs/ld_client/Mock/t32rem/build/t32rem_mock",
-    "T32ProcessName": "ld_mock",
-    "T32InfoLocation": "C:\\Users\\pulta\\Desktop\\testResult.txt",
+    "F32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe",
+    "T32ProcessName": "t32mtc",
+    "T32InfoLocation": "C:\\app\\result.txt",
     "DetectionPeriod": 5000,
     "FetchInfoMaxAttempts": 5,
     "FetchInfoAttemptPeriod": 1000,
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index 86f601e..0d2a206 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -1,4 +1,5 @@
 using System.Diagnostics;
+using LDClient.utils.loggers;
 
 namespace LDClient.detection {
 
@@ -71,8 +72,12 @@ namespace LDClient.detection {
                 t32RemProcess.StartInfo.Arguments = argument;
                 try {
                     t32RemProcess.Start();
-                    t32RemProcess.WaitForExit(waitTimeoutMs);
+                    if (!t32RemProcess.WaitForExit(waitTimeoutMs)) {
+                        Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {waitTimeoutMs} ms");
+                        return false;
+                    }
                     if (t32RemProcess.ExitCode != successExitCode) {
+                        Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
                         return false;
                     }
                 } catch (Exception exception) {
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index a2a5627..251e663 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -117,7 +117,7 @@ namespace LDClient.utils {
                 FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]);
                 T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]);
                 T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]);
-                F32RemArguments = configuration.GetSection($"{DdSection}:F32RemCommands").GetChildren().Select(key => key.Value).ToArray();
+                F32RemArguments = configuration.GetSection($"{DdSection}:F32RemArguments").GetChildren().Select(key => key.Value).ToArray();
             } catch (Exception e) {
                 Console.WriteLine(e);
                 Environment.Exit(ErrorExitCode);
-- 
GitLab


From 1413374d99651ee252e421493bc54ab5ae7f261f Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 24 Apr 2022 22:23:25 +0200
Subject: [PATCH 32/67] re #9571 Added installation readme to the LD client

---
 ld_client/readme.md | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)
 create mode 100644 ld_client/readme.md

diff --git a/ld_client/readme.md b/ld_client/readme.md
new file mode 100644
index 0000000..13bb880
--- /dev/null
+++ b/ld_client/readme.md
@@ -0,0 +1,44 @@
+# Automatic detection and documentation of connected Lauterbach Debugger and connected head device - LD Client - Bug Thugs
+
+---
+
+- [Description](#description)
+- [Requirements](#requirements)
+  * [Windows](#windows)
+- [Build](#build)
+- [Execution](#execution)
+
+---
+
+## Description
+
+This client application periodically searches for running process of TRACE32 PowerView. 
+Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and connected head device.
+The serial numbers from the info file is parsed and along with a timestamp and computer-related information, is sent to the server (API).
+If the application fails to send the data, it will store the payload in a disk-based cache.
+The client then periodically accesses the cache in order to resend the failed payloads to the server.   
+
+## Requirements
+
+In order to successfully run the application, the user needs to have .NET 6.0 installed on their machine. 
+It can be downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
+
+## Build/Publish
+
+If you have .NET 6.0 installed on your machine and its binaries are included in the system variables, you can simply execute following command in the LDClient subfolder:
+```
+dotnet publish -c Release -o build -p:PublishSingleFile=true --self-contained true -r win-x86
+```
+
+If everything goes well, a file called `LDClient.exe` with all its needed dependencies should be created under 'build'.
+
+You can also build this application by opening the solution of this project in MSVC a using one of its build tools.
+
+## Execution
+
+
+After everything is successfully setup, you can simply run the application by running the following command from the terminal.
+
+```
+LDClient.exe
+```
\ No newline at end of file
-- 
GitLab


From c73d715c82735311aa531fa020fbc2645097aa58 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 24 Apr 2022 22:30:02 +0200
Subject: [PATCH 33/67] re #9571 fixed typo and text refactoring

---
 ld_client/readme.md | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/ld_client/readme.md b/ld_client/readme.md
index 13bb880..80347ad 100644
--- a/ld_client/readme.md
+++ b/ld_client/readme.md
@@ -1,4 +1,4 @@
-# Automatic detection and documentation of connected Lauterbach Debugger and connected head device - LD Client - Bug Thugs
+# Automatic detection and documentation of connected Lauterbach Debugger and its head device - LD Client - Bug Thugs
 
 ---
 
@@ -13,15 +13,15 @@
 ## Description
 
 This client application periodically searches for running process of TRACE32 PowerView. 
-Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and connected head device.
-The serial numbers from the info file is parsed and along with a timestamp and computer-related information, is sent to the server (API).
+Upon detection the application tries to execute t32rem.exe program with specific parameters which generates info file about currently connected Lauterbach Debbuger and its head device.
+The serial numbers from the info file are then parsed and along with a timestamp and computer-related information, is sent to the server (API).
 If the application fails to send the data, it will store the payload in a disk-based cache.
 The client then periodically accesses the cache in order to resend the failed payloads to the server.   
 
 ## Requirements
 
-In order to successfully run the application, the user needs to have .NET 6.0 installed on their machine. 
-It can be downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
+In order to successfully run the application the user needs to have .NET 6.0 installed on their machine. 
+It can be simply downloaded from the official site of the Microsoft (https://dotnet.microsoft.com/en-us/download/dotnet/6.0).
 
 ## Build/Publish
 
@@ -30,9 +30,9 @@ If you have .NET 6.0 installed on your machine and its binaries are included in
 dotnet publish -c Release -o build -p:PublishSingleFile=true --self-contained true -r win-x86
 ```
 
-If everything goes well, a file called `LDClient.exe` with all its needed dependencies should be created under 'build'.
+If everything goes well, a file called `LDClient.exe` with all its needed dependencies and configuration files should be created under folder 'build'.
 
-You can also build this application by opening the solution of this project in MSVC a using one of its build tools.
+You can also build this application by opening the solution of this project in MSVC and using one of its build tools.
 
 ## Execution
 
-- 
GitLab


From 0932a9e214cb251a9e986c9fcaea8d14354ce5b8 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 22:36:16 +0200
Subject: [PATCH 34/67] re #9443 refactoring of detection classes

---
 .../LDClient/detection/DebuggerInfoParser.cs  |  2 +-
 ld_client/LDClient/detection/IInfoFetcher.cs  | 15 +++++++
 ld_client/LDClient/detection/IProcessUtils.cs | 13 ++++++
 ld_client/LDClient/detection/InfoFetcher.cs   | 37 ++++++++---------
 .../LDClient/detection/ProcessDetection.cs    | 18 +++++----
 ld_client/LDClient/detection/ProcessUtils.cs  | 40 +++++++++++++++++++
 6 files changed, 96 insertions(+), 29 deletions(-)
 create mode 100644 ld_client/LDClient/detection/IInfoFetcher.cs
 create mode 100644 ld_client/LDClient/detection/IProcessUtils.cs
 create mode 100644 ld_client/LDClient/detection/ProcessUtils.cs

diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs
index 3f07e32..dec8bd0 100644
--- a/ld_client/LDClient/detection/DebuggerInfoParser.cs
+++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs
@@ -15,7 +15,7 @@ namespace LDClient.detection {
                 throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})");
             }
             
-            return (matches[0].ToString(), matches[1].ToString());
+            return (matches[1].ToString().Trim(), matches[0].ToString().Trim());
         }
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs
new file mode 100644
index 0000000..e48005c
--- /dev/null
+++ b/ld_client/LDClient/detection/IInfoFetcher.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    public interface IInfoFetcher {
+
+        public string HeadSerialNumber { get; set; }
+        public string BodySerialNumber { get; set; }
+
+        public Task<bool> FetchDataAsync();
+    }
+}
diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs
new file mode 100644
index 0000000..b900375
--- /dev/null
+++ b/ld_client/LDClient/detection/IProcessUtils.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    public interface IProcessUtils {
+        public bool IsProcessRunning(string name);
+
+        public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode);
+    }
+}
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index 0d2a206..07ddba1 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -1,9 +1,10 @@
 using System.Diagnostics;
+using LDClient.utils;
 using LDClient.utils.loggers;
 
 namespace LDClient.detection {
 
-    public class InfoFetcher {
+    public class InfoFetcher : IInfoFetcher {
         
         private const string UndefinedSerialNumber = "number";
 
@@ -15,10 +16,15 @@ namespace LDClient.detection {
         private readonly uint _waitPeriodMs;
         private readonly string _infoFilePath;
 
-        public string HeadSerialNumber { get; private set; } = UndefinedSerialNumber;
-        public string BodySerialNumber { get; private set; } = UndefinedSerialNumber;
+        public IProcessUtils ProcessUtils;
+        public IFileUtils FileUtils;
 
-        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {
+        public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;
+        public string BodySerialNumber { get; set; } = UndefinedSerialNumber;
+
+
+        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
+            string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {
             _maxAttempts = maxAttempts;
             _waitPeriodMs = waitPeriodMs;
             _infoFilePath = infoFilePath;
@@ -26,6 +32,9 @@ namespace LDClient.detection {
             _f32RemArguments = f32RemArguments;
             _f32SuccessExitCode = f32SuccessExitCode;
             _f32WaitTimeoutMs = f32WaitTimeoutMs;
+            ProcessUtils = new ProcessUtils();
+            FileUtils = new FileUtils();
+
         }
 
         public async Task<bool> FetchDataAsync() {
@@ -49,7 +58,7 @@ namespace LDClient.detection {
 
         private bool RetrieveDebuggerInfo(string filePath) {
             try {
-                var fileContent = File.ReadAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
+                var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
                 var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
                 HeadSerialNumber = headSerialNumber;
                 BodySerialNumber = bodySerialNumber;
@@ -61,27 +70,13 @@ namespace LDClient.detection {
             return true;
         }
 
-        private static bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int successExitCode, int waitTimeoutMs) {
+        private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) {
             if (arguments == null) {
                 Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given");
                 return false;
             }
             foreach (var argument in arguments) {
-                var t32RemProcess = new Process();
-                t32RemProcess.StartInfo.FileName = executableFile;
-                t32RemProcess.StartInfo.Arguments = argument;
-                try {
-                    t32RemProcess.Start();
-                    if (!t32RemProcess.WaitForExit(waitTimeoutMs)) {
-                        Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {waitTimeoutMs} ms");
-                        return false;
-                    }
-                    if (t32RemProcess.ExitCode != successExitCode) {
-                        Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
-                        return false;
-                    }
-                } catch (Exception exception) {
-                    Program.DefaultLogger.Error($"Failed to run {executableFile} {argument}. {exception.Message}");
+                if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) {
                     return false;
                 }
             }
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
index fb68c65..27d5333 100644
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -4,25 +4,29 @@ using LDClient.network.data;
 
 namespace LDClient.detection {
    
-	 public sealed class ProcessProcessDetection : IProcessDetection {
+	 public sealed class ProcessDetection : IProcessDetection {
         
         private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
 
         private readonly string _processName;
         private readonly uint _detectionPeriodMs;
-        private readonly InfoFetcher _infoFetcher;
+        private readonly IInfoFetcher _infoFetcher;
         private readonly IApiClient _apiClient;
-        
+        private readonly IProcessUtils _processUtils;
+
         private bool _processIsActive;
         private bool _failedToRetrieveData;
         private Payload? _lastConnectedPayload;
 
-        public ProcessProcessDetection(string processName, uint detectionPeriodMs, InfoFetcher infoFetcher, IApiClient apiClient) {
+        public bool DetectionRunning = false;
+
+        public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils) {
             _processName = processName;
             _detectionPeriodMs = detectionPeriodMs;
             _infoFetcher = infoFetcher;
             _apiClient = apiClient;
             _failedToRetrieveData = false;
+            _processUtils = processUtils;
         }
 
         private async Task<bool> RetrieveDataFromDebugger() {
@@ -43,7 +47,7 @@ namespace LDClient.detection {
         }
 
         private async Task DetectProcessAsync() {
-            var processExists = Process.GetProcessesByName(_processName).Length > 0;
+            var processExists = _processUtils.IsProcessRunning(_processName);
 
             if (processExists && !_processIsActive) {
                 Program.DefaultLogger.Info($"Process started: {_processName}");
@@ -77,11 +81,11 @@ namespace LDClient.detection {
         
         public async void RunPeriodicDetection() {
             Program.DefaultLogger.Info("Process periodic detector has started");
-            while (true) {
+            DetectionRunning = true;
+            while (DetectionRunning) {
                 await DetectProcessAsync();
                 Thread.Sleep((int)_detectionPeriodMs);
             }
-            // ReSharper disable once FunctionNeverReturns
         }
     }
 }
diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs
new file mode 100644
index 0000000..b707f66
--- /dev/null
+++ b/ld_client/LDClient/detection/ProcessUtils.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    public class ProcessUtils : IProcessUtils{
+
+        public bool IsProcessRunning(string name) {
+            return Process.GetProcessesByName(name).Length > 0;
+        }
+
+
+        public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) {
+
+            var t32RemProcess = new Process();
+            t32RemProcess.StartInfo.FileName = fileName;
+            t32RemProcess.StartInfo.Arguments = argument;
+            try {
+                t32RemProcess.Start();
+                if (!t32RemProcess.WaitForExit(timeout)) {
+                    Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms");
+                    return false;
+                }
+                if (t32RemProcess.ExitCode != desiredExitCode) {
+                    Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
+                    return false;
+                }
+            } catch (Exception exception) {
+                Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}");
+                return false;
+            }
+
+            return true;
+        }
+
+    }
+}
-- 
GitLab


From afafbc228e11c3ded27483ae225f9da1496d6f43 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 22:37:59 +0200
Subject: [PATCH 35/67] re #9443 refactoring of network and other utils for the
 purpose of testing

---
 ld_client/LDClient/Program.cs             |  5 ++--
 ld_client/LDClient/appsettings.json       |  4 +--
 ld_client/LDClient/network/ApiClient.cs   | 16 +++++-------
 ld_client/LDClient/network/HttpClient.cs  | 32 +++++++++++++++++++++++
 ld_client/LDClient/network/IHttpClient.cs | 13 +++++++++
 ld_client/LDClient/utils/FileUtils.cs     | 13 +++++++++
 ld_client/LDClient/utils/IFileUtils.cs    | 12 +++++++++
 7 files changed, 81 insertions(+), 14 deletions(-)
 create mode 100644 ld_client/LDClient/network/HttpClient.cs
 create mode 100644 ld_client/LDClient/network/IHttpClient.cs
 create mode 100644 ld_client/LDClient/utils/FileUtils.cs
 create mode 100644 ld_client/LDClient/utils/IFileUtils.cs

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index fc2fb03..bbd4322 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -41,11 +41,12 @@ internal static class Program {
             Config.CacheFileName
         );
         
-        IProcessDetection processProcessDetection = new ProcessProcessDetection(
+        IProcessDetection processProcessDetection = new ProcessDetection(
             Config.T32ProcessName,
             Config.DetectionPeriod,
             InfoFetcher,
-            DefaultApiClient
+            DefaultApiClient,
+            new ProcessUtils()
         );
         
         var apiClientThread = new Thread(DefaultApiClient.Run) {
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 4826407..3a3a702 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -15,8 +15,8 @@
     "LogFlowType": 0
   },
   "Network": {
-    "ApiBaseAddress": "http://127.0.0.1",
-    "ApiLDEndPoint": "/lauterbach-debugger-logs/",
+    "ApiBaseAddress": "http://192.168.0.22",
+    "ApiLDEndPoint": "/api/v1/ld-logs",
     "ApiPort": 8000
   },
   "Cache": {
diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 01043bf..c06a69f 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -10,20 +10,20 @@ namespace LDClient.network {
     
     public sealed class ApiClient : IApiClient {
         
-        private readonly string _uri;
-        private readonly HttpClient _client;
-        private readonly IPersistentQueue _cache;
+        public IHttpClient _client;
+        public IPersistentQueue _cache;
+        
         private readonly uint _retryPeriod;
         private readonly uint _maxEntries;
         private readonly uint _maxRetries;
         
         public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) {
-            _uri = $"{url}:{port}{path}";
+            var uri = $"{url}:{port}{path}";
             _retryPeriod = retryPeriod;
             _maxEntries = maxEntries;
             _maxRetries = maxRetries;
 
-            _client = new HttpClient();
+            _client = new HttpClient(uri);
             _cache = new PersistentQueue(cacheFilename);
         }
 
@@ -32,11 +32,7 @@ namespace LDClient.network {
                 Stopwatch stopWatch = new();
                 stopWatch.Start();
                 
-                var response = await _client.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {
-                    Converters = {
-                        new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
-                    }
-                });
+                var response = await _client.PostAsJsonAsync(payload);
                 stopWatch.Stop();
                 CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds);
 
diff --git a/ld_client/LDClient/network/HttpClient.cs b/ld_client/LDClient/network/HttpClient.cs
new file mode 100644
index 0000000..fa6f3d1
--- /dev/null
+++ b/ld_client/LDClient/network/HttpClient.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http.Json;
+using System.Text;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+using LDClient.network.data;
+
+namespace LDClient.network {
+    public class HttpClient : IHttpClient{
+
+        private readonly System.Net.Http.HttpClient _httpClient;
+
+        private readonly string _uri;
+        public HttpClient(string uri) {
+
+            _httpClient = new System.Net.Http.HttpClient();
+            _uri = uri;
+        }
+
+        public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload) {
+            return _httpClient.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {
+                Converters = {
+                    new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
+                }
+            });
+
+        }
+    }
+}
diff --git a/ld_client/LDClient/network/IHttpClient.cs b/ld_client/LDClient/network/IHttpClient.cs
new file mode 100644
index 0000000..daf0c60
--- /dev/null
+++ b/ld_client/LDClient/network/IHttpClient.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using LDClient.network.data;
+
+namespace LDClient.network {
+    public interface IHttpClient {
+
+        public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload);
+    }
+}
diff --git a/ld_client/LDClient/utils/FileUtils.cs b/ld_client/LDClient/utils/FileUtils.cs
new file mode 100644
index 0000000..abd3e98
--- /dev/null
+++ b/ld_client/LDClient/utils/FileUtils.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.utils {
+    public class FileUtils : IFileUtils {
+        public string[] ReadFileAllLines(string file) {
+            return File.ReadAllLines(file);
+        }
+    }
+}
diff --git a/ld_client/LDClient/utils/IFileUtils.cs b/ld_client/LDClient/utils/IFileUtils.cs
new file mode 100644
index 0000000..f3daf17
--- /dev/null
+++ b/ld_client/LDClient/utils/IFileUtils.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.utils {
+    public interface IFileUtils {
+
+        public string[] ReadFileAllLines(string file);
+    }
+}
-- 
GitLab


From df1c36d1c7266507db0b1f466ec3e17c2c2e96d1 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 23:13:22 +0200
Subject: [PATCH 36/67] re #9443 added implemented tests for DebuggerInfoParser

---
 .../detection/DebuggerInfoParserTests.cs      | 66 +++++++++++++++++++
 1 file changed, 66 insertions(+)
 create mode 100644 ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs

diff --git a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs
new file mode 100644
index 0000000..6f6fa52
--- /dev/null
+++ b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs
@@ -0,0 +1,66 @@
+using System;
+using LDClient.detection;
+using NUnit.Framework;
+
+namespace LDClientTests.detection {
+    public class DebuggerInfoParserTests {
+
+        public static readonly string CorrectFileContent =
+            "B::version.hardware \r\n\r\n" +
+            "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+            "   Serial Number: C12345678912 \r\n\r\n" +
+            "   Firmware R.2021.02 (136263) \r\n\r\n" +
+            "   Instance: 1. \r\n\r\n" +
+            "   Automotive Debug Cable \r\n\r\n" +
+            "      Serial Number: C98765432198 ";
+
+        public static readonly string HeadSerialNumber = "C98765432198";
+        public static readonly string BodySerialNumber = "C12345678912";
+
+
+        [Test]
+        [TestCase("B::version.hardware \r\n\r\n" +
+                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+                  "   Serial Number: C12345678912 \r\n\r\n" +
+                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
+                  "   Instance: 1. \r\n\r\n" +
+                  "   Automotive Debug Cable \r\n\r\n" +
+                  "      Serial Number: C12345678912 ", "C12345678912", "C12345678912")]
+        [TestCase("B::version.hardware \r\n\r\n" +
+                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+                  "   Serial Number: C1awfaw484 \r\n\r\n" +
+                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
+                  "   Instance: 1. \r\n\r\n" +
+                  "   Automotive Debug Cable \r\n\r\n" +
+                  "      Serial Number: C16468551", "C16468551", "C1awfaw484")]
+        public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) {
+            var (headResult, bodyResult) = DebuggerInfoParser.Parse(file);
+
+            Assert.AreEqual(expectedHead, headResult);
+            Assert.AreEqual(expectedBody, bodyResult);
+        }
+
+
+        [Test]
+        [TestCase("B::version.hardware \r\n\r\n" +
+                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+                  "   Serial Number: C12345678912 \r\n\r\n" +
+                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
+                  "   Instance: 1. \r\n\r\n" +
+                  "   Automotive Debug Cable \r\n\r\n" +
+                  "      Serial Number: C12345678912 \n" +
+                  "      Serial Number: C12345678912 ")]
+        [TestCase("B::version.hardware \r\n\r\n" +
+                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+                  "   Serial Number: C1awfaw484 \r\n\r\n" +
+                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
+                  "   Instance: 1. \r\n\r\n" +
+                  "   Automotive Debug Cable \r\n\r\n" +
+                  "      Serial Numbeeeer: C16468551")]
+        public void Parse_IncorrectValues_ThrowException(string file) {
+            Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file));
+        }
+
+
+    }
+}
-- 
GitLab


From cbf3b0c6f3564e7edf3e23519fe6732187a9179e Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 23:55:54 +0200
Subject: [PATCH 37/67] re #9443 Added implementation of InfoFetcher tests

---
 ld_client/LDClientTests/LDClientTests.csproj  |   5 +
 ld_client/LDClientTests/UnitTest1.cs          |  15 ---
 .../detection/DebuggerInfoParserTests.cs      | 106 ++++++++--------
 .../detection/InfoFetcherTests.cs             | 117 ++++++++++++++++++
 4 files changed, 175 insertions(+), 68 deletions(-)
 delete mode 100644 ld_client/LDClientTests/UnitTest1.cs
 create mode 100644 ld_client/LDClientTests/detection/InfoFetcherTests.cs

diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj
index 5085235..6ba14ca 100644
--- a/ld_client/LDClientTests/LDClientTests.csproj
+++ b/ld_client/LDClientTests/LDClientTests.csproj
@@ -9,9 +9,14 @@
 
   <ItemGroup>
     <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.11.0" />
+    <PackageReference Include="Moq" Version="4.17.2" />
     <PackageReference Include="NUnit" Version="3.13.2" />
     <PackageReference Include="NUnit3TestAdapter" Version="4.0.0" />
     <PackageReference Include="coverlet.collector" Version="3.1.0" />
   </ItemGroup>
 
+  <ItemGroup>
+    <ProjectReference Include="..\LDClient\LDClient.csproj" />
+  </ItemGroup>
+
 </Project>
diff --git a/ld_client/LDClientTests/UnitTest1.cs b/ld_client/LDClientTests/UnitTest1.cs
deleted file mode 100644
index 03cf433..0000000
--- a/ld_client/LDClientTests/UnitTest1.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using NUnit.Framework;
-
-namespace LDClientTests {
-    public class Tests {
-        [SetUp]
-        public void Setup() {
-
-        }
-
-        [Test]
-        public void Test1() {
-            Assert.Pass();
-        }
-    }
-}
\ No newline at end of file
diff --git a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs
index 6f6fa52..e6fa016 100644
--- a/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs
+++ b/ld_client/LDClientTests/detection/DebuggerInfoParserTests.cs
@@ -2,65 +2,65 @@
 using LDClient.detection;
 using NUnit.Framework;
 
-namespace LDClientTests.detection {
-    public class DebuggerInfoParserTests {
+namespace LDClientTests.detection; 
 
-        public static readonly string CorrectFileContent =
-            "B::version.hardware \r\n\r\n" +
-            "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
-            "   Serial Number: C12345678912 \r\n\r\n" +
-            "   Firmware R.2021.02 (136263) \r\n\r\n" +
-            "   Instance: 1. \r\n\r\n" +
-            "   Automotive Debug Cable \r\n\r\n" +
-            "      Serial Number: C98765432198 ";
+public class DebuggerInfoParserTests {
 
-        public static readonly string HeadSerialNumber = "C98765432198";
-        public static readonly string BodySerialNumber = "C12345678912";
+    public static readonly string CorrectFileContent =
+        "B::version.hardware \r\n\r\n" +
+        "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+        "   Serial Number: C12345678912 \r\n\r\n" +
+        "   Firmware R.2021.02 (136263) \r\n\r\n" +
+        "   Instance: 1. \r\n\r\n" +
+        "   Automotive Debug Cable \r\n\r\n" +
+        "      Serial Number: C98765432198 ";
 
+    public static readonly string HeadSerialNumber = "C98765432198";
+    public static readonly string BodySerialNumber = "C12345678912";
 
-        [Test]
-        [TestCase("B::version.hardware \r\n\r\n" +
-                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
-                  "   Serial Number: C12345678912 \r\n\r\n" +
-                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
-                  "   Instance: 1. \r\n\r\n" +
-                  "   Automotive Debug Cable \r\n\r\n" +
-                  "      Serial Number: C12345678912 ", "C12345678912", "C12345678912")]
-        [TestCase("B::version.hardware \r\n\r\n" +
-                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
-                  "   Serial Number: C1awfaw484 \r\n\r\n" +
-                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
-                  "   Instance: 1. \r\n\r\n" +
-                  "   Automotive Debug Cable \r\n\r\n" +
-                  "      Serial Number: C16468551", "C16468551", "C1awfaw484")]
-        public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) {
-            var (headResult, bodyResult) = DebuggerInfoParser.Parse(file);
 
-            Assert.AreEqual(expectedHead, headResult);
-            Assert.AreEqual(expectedBody, bodyResult);
-        }
+    [Test]
+    [TestCase("B::version.hardware \r\n\r\n" +
+              "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+              "   Serial Number: C12345678912 \r\n\r\n" +
+              "   Firmware R.2021.02 (136263) \r\n\r\n" +
+              "   Instance: 1. \r\n\r\n" +
+              "   Automotive Debug Cable \r\n\r\n" +
+              "      Serial Number: C12345678912 ", "C12345678912", "C12345678912")]
+    [TestCase("B::version.hardware \r\n\r\n" +
+              "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+              "   Serial Number: C1awfaw484 \r\n\r\n" +
+              "   Firmware R.2021.02 (136263) \r\n\r\n" +
+              "   Instance: 1. \r\n\r\n" +
+              "   Automotive Debug Cable \r\n\r\n" +
+              "      Serial Number: C16468551", "C16468551", "C1awfaw484")]
+    public void Parse_CorrectValues_ReturnSerials(string file, string expectedHead, string expectedBody) {
+        var (headResult, bodyResult) = DebuggerInfoParser.Parse(file);
 
-
-        [Test]
-        [TestCase("B::version.hardware \r\n\r\n" +
-                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
-                  "   Serial Number: C12345678912 \r\n\r\n" +
-                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
-                  "   Instance: 1. \r\n\r\n" +
-                  "   Automotive Debug Cable \r\n\r\n" +
-                  "      Serial Number: C12345678912 \n" +
-                  "      Serial Number: C12345678912 ")]
-        [TestCase("B::version.hardware \r\n\r\n" +
-                  "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
-                  "   Serial Number: C1awfaw484 \r\n\r\n" +
-                  "   Firmware R.2021.02 (136263) \r\n\r\n" +
-                  "   Instance: 1. \r\n\r\n" +
-                  "   Automotive Debug Cable \r\n\r\n" +
-                  "      Serial Numbeeeer: C16468551")]
-        public void Parse_IncorrectValues_ThrowException(string file) {
-            Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file));
-        }
+        Assert.AreEqual(expectedHead, headResult);
+        Assert.AreEqual(expectedBody, bodyResult);
+    }
 
 
+    [Test]
+    [TestCase("B::version.hardware \r\n\r\n" +
+              "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+              "   Serial Number: C12345678912 \r\n\r\n" +
+              "   Firmware R.2021.02 (136263) \r\n\r\n" +
+              "   Instance: 1. \r\n\r\n" +
+              "   Automotive Debug Cable \r\n\r\n" +
+              "      Serial Number: C12345678912 \n" +
+              "      Serial Number: C12345678912 ")]
+    [TestCase("B::version.hardware \r\n\r\n" +
+              "PowerDebug USB 3.0 via USB 3.0 \r\n\r\n" +
+              "   Serial Number: C1awfaw484 \r\n\r\n" +
+              "   Firmware R.2021.02 (136263) \r\n\r\n" +
+              "   Instance: 1. \r\n\r\n" +
+              "   Automotive Debug Cable \r\n\r\n" +
+              "      Serial Numbeeeer: C16468551")]
+    public void Parse_IncorrectValues_ThrowException(string file) {
+        Assert.Throws<ArgumentException>(() => DebuggerInfoParser.Parse(file));
     }
-}
+
+
+}
\ No newline at end of file
diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
new file mode 100644
index 0000000..03c62a9
--- /dev/null
+++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
@@ -0,0 +1,117 @@
+using System.IO;
+using System.Threading.Tasks;
+using LDClient.detection;
+using LDClient.utils;
+using Moq;
+using NUnit.Framework;
+
+namespace LDClientTests.detection; 
+
+internal class InfoFetcherTests {
+    private InfoFetcher _defaultFetcher;
+    private InfoFetcher _fetcherWithoutPars;
+        
+
+    private readonly string[] _defaultArguments = new[] { "argument 1", "argument 2" , "argument 3"};
+    private const uint DefaultMaxAttempts = 5;
+
+    private Mock<IProcessUtils> _mockProcessUtils;
+    private Mock<IFileUtils> _mockFileUtils;
+
+    [SetUp]
+    public void Setup() {
+        _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict);
+
+        _mockFileUtils = new Mock<IFileUtils>(MockBehavior.Strict);
+    
+
+        _defaultFetcher = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
+            _defaultArguments, 0, 50) {
+            FileUtils = _mockFileUtils.Object,
+            ProcessUtils = _mockProcessUtils.Object
+        };
+
+
+        _fetcherWithoutPars = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
+            null, 0, 50) {
+            FileUtils = _mockFileUtils.Object,
+            ProcessUtils = _mockProcessUtils.Object
+        };
+    }
+
+    [Test]
+    public async Task FetchDataAsync_ExecuteAll_ExecutedAndFetched() {
+
+        _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>())).Returns(true);
+        _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).
+            Returns(DebuggerInfoParserTests.CorrectFileContent.Split("\n"));
+
+
+        var result = await _defaultFetcher.FetchDataAsync();
+
+        Assert.IsTrue(result);
+        _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length));
+
+        Assert.AreEqual(DebuggerInfoParserTests.BodySerialNumber, _defaultFetcher.BodySerialNumber);
+        Assert.AreEqual(DebuggerInfoParserTests.HeadSerialNumber, _defaultFetcher.HeadSerialNumber);
+
+    }
+
+
+
+    [Test]
+    public async Task FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed() {
+
+        _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>())).Returns(false);
+        _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).
+            Returns(new []{""});
+
+
+        var result = await _defaultFetcher.FetchDataAsync();
+
+
+        Assert.IsFalse(result);
+        _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(1));
+        _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never);
+    }
+
+    [Test]
+    public async Task FetchDataAsync_ExecuteWithoutParameters_NotExecuted() {
+        _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>())).Returns(false);
+        _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).
+            Returns(new[] { "" });
+
+        var result = await _fetcherWithoutPars.FetchDataAsync();
+            
+        Assert.IsFalse(result);
+        _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>()), Times.Never);
+        _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Never);
+
+    }
+
+
+    [Test]
+    public async Task FetchDataAsync_ExecuteInfoNotCreated_FetchFailed() {
+        _mockProcessUtils.Setup(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>())).Returns(true);
+        _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).Throws(new FileNotFoundException());
+
+        var result = await _defaultFetcher.FetchDataAsync();
+        Assert.IsFalse(result);
+
+        _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
+            It.IsAny<int>(), It.IsAny<int>()), Times.Exactly(_defaultArguments.Length));
+        _mockFileUtils.Verify(x => x.ReadFileAllLines(It.IsAny<string>()), Times.Exactly((int)DefaultMaxAttempts));
+
+    }
+
+
+
+
+}
\ No newline at end of file
-- 
GitLab


From e979e18d05fe0abbae145662d978fe3d42c3c1f8 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 23:56:25 +0200
Subject: [PATCH 38/67] re #9443 Added implementation of ProcessDetection tests

---
 .../detection/ProcessDetectionTests.cs        | 132 ++++++++++++++++++
 1 file changed, 132 insertions(+)
 create mode 100644 ld_client/LDClientTests/detection/ProcessDetectionTests.cs

diff --git a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs
new file mode 100644
index 0000000..6c6a2da
--- /dev/null
+++ b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs
@@ -0,0 +1,132 @@
+using System.Threading;
+using System.Threading.Tasks;
+using LDClient.detection;
+using LDClient.network;
+using LDClient.network.data;
+using Moq;
+using NUnit.Framework;
+
+namespace LDClientTests.detection; 
+
+public class ProcessDetectionTests {
+
+    private ProcessDetection _processDetection;
+
+
+    private Mock<IApiClient> _mockApiClient;
+    private Mock<IInfoFetcher> _mockInfoFetcher;
+    private Mock<IProcessUtils> _mockProcessUtils;
+
+    private readonly string _defaultSerialNumber = "C12345678912";
+        
+
+    [SetUp]
+    public void Setup() {
+        _mockApiClient = new Mock<IApiClient>(MockBehavior.Strict);
+        _mockApiClient.Setup(x => x.SendPayloadAsync(It.IsAny<Payload>())).Returns(Task.CompletedTask);
+
+
+        _mockInfoFetcher = new Mock<IInfoFetcher>(MockBehavior.Strict);
+        _mockInfoFetcher.Setup(x => x.BodySerialNumber).Returns(_defaultSerialNumber);
+        _mockInfoFetcher.Setup(x => x.HeadSerialNumber).Returns(_defaultSerialNumber);
+
+        _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict);
+            
+
+        _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object);
+    }
+
+
+    private void StartAndStopDetection(int timeout) {
+        var detectionThread = new Thread(_processDetection.RunPeriodicDetection);
+
+        detectionThread.Start();
+
+        Thread.Sleep(timeout);
+
+        _processDetection.DetectionRunning = false;
+        detectionThread.Join();
+    }
+
+    [Test]
+    [Timeout(1000)]
+    public void RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent() {
+        _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(false));
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);
+
+
+        StartAndStopDetection(500);
+
+        _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Never);
+        _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);
+    }
+
+    [Test]
+    [Timeout(1000)]
+    public void RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent() {
+        _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);
+
+
+        StartAndStopDetection(500);
+
+        _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Once);
+        _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);
+    }
+
+
+
+    [Test]
+    [Timeout(1000)]
+    public void RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent() {
+        _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);
+
+        var detectionThread = new Thread(_processDetection.RunPeriodicDetection);
+
+        detectionThread.Start();
+
+        Thread.Sleep(250);
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);
+
+        Thread.Sleep(250);
+
+        _processDetection.DetectionRunning = false;
+        detectionThread.Join();
+
+        _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(2));
+        _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Once);
+    }
+
+
+
+    [Test]
+    [Timeout(2000)]
+    public void RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent() {
+        _mockInfoFetcher.Setup(x => x.FetchDataAsync()).Returns(Task.FromResult(true));
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);
+
+        var detectionThread = new Thread(_processDetection.RunPeriodicDetection);
+
+        detectionThread.Start();
+
+        Thread.Sleep(200);
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);
+
+        Thread.Sleep(200);
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(true);
+
+
+        Thread.Sleep(200);
+        _mockProcessUtils.Setup(x => x.IsProcessRunning(It.IsAny<string>())).Returns(false);
+        Thread.Sleep(200);
+
+        _processDetection.DetectionRunning = false;
+        detectionThread.Join();
+
+        _mockApiClient.Verify(x => x.SendPayloadAsync(It.IsAny<Payload>()), Times.Exactly(4));
+        _mockInfoFetcher.Verify(x => x.FetchDataAsync(), Times.Exactly(2));
+    }
+
+
+}
\ No newline at end of file
-- 
GitLab


From fa084fc4f32997f4fc3c6c989cb95bd4968bf44a Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 25 Apr 2022 23:57:30 +0200
Subject: [PATCH 39/67] re #9443 ApiClient refactoring for better testing

---
 ld_client/LDClient/Program.cs           |  3 ++-
 ld_client/LDClient/network/ApiClient.cs | 20 +++++++++++---------
 2 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index bbd4322..d8a7cb4 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -1,3 +1,4 @@
+using DiskQueue;
 using LDClient.detection;
 using LDClient.network;
 using LDClient.utils;
@@ -38,7 +39,7 @@ internal static class Program {
             Config.ApiUsbEndPoint, 
             Config.RetryPeriod, Config.MaxEntries,
             Config.MaxRetries, 
-            Config.CacheFileName
+            new PersistentQueue(Config.CacheFileName)
         );
         
         IProcessDetection processProcessDetection = new ProcessDetection(
diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index c06a69f..b5ca456 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -11,20 +11,22 @@ namespace LDClient.network {
     public sealed class ApiClient : IApiClient {
         
         public IHttpClient _client;
-        public IPersistentQueue _cache;
-        
+
+        public bool ClientRunning;
+
         private readonly uint _retryPeriod;
         private readonly uint _maxEntries;
         private readonly uint _maxRetries;
-        
-        public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, string cacheFilename) {
+        private readonly IPersistentQueue _cache;
+
+        public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache) {
             var uri = $"{url}:{port}{path}";
             _retryPeriod = retryPeriod;
             _maxEntries = maxEntries;
             _maxRetries = maxRetries;
 
             _client = new HttpClient(uri);
-            _cache = new PersistentQueue(cacheFilename);
+            _cache = cache;
         }
 
         public async Task SendPayloadAsync(Payload payload) {
@@ -59,8 +61,8 @@ namespace LDClient.network {
         private async Task ResendPayloadsAsync() {
             var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);
             var payloads = new List<Payload>();
-
-            using (var session = _cache.OpenSession()) {
+            if (numberOfPayloadsToResend > 0) {
+                using var session = _cache.OpenSession();
                 for (var i = 0; i < numberOfPayloadsToResend; i++) {
                     var rawBytes = session.Dequeue();
                     var payload = JsonSerializer.Deserialize<Payload>(rawBytes);
@@ -96,11 +98,11 @@ namespace LDClient.network {
 
         public async void Run() {
             Program.DefaultLogger.Info("Api Client thread has started");
-            while (true) {
+            ClientRunning = true;
+            while (ClientRunning) {
                 await ResendPayloadsAsync();
                 Thread.Sleep((int) _retryPeriod);
             }
-            // ReSharper disable once FunctionNeverReturns
         }
     }
 }
-- 
GitLab


From 22974ce09c5e1e7fd6cf30b6bfc1a2a06f7d365c Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Tue, 26 Apr 2022 21:29:21 +0200
Subject: [PATCH 40/67] re #9443 Added implementation of tests for ApiClient

---
 ld_client/LDClientTests/LDClientTests.csproj  |   2 +-
 .../LDClientTests/network/ApiClientTests.cs   | 167 ++++++++++++++++++
 2 files changed, 168 insertions(+), 1 deletion(-)
 create mode 100644 ld_client/LDClientTests/network/ApiClientTests.cs

diff --git a/ld_client/LDClientTests/LDClientTests.csproj b/ld_client/LDClientTests/LDClientTests.csproj
index 6ba14ca..59f6a24 100644
--- a/ld_client/LDClientTests/LDClientTests.csproj
+++ b/ld_client/LDClientTests/LDClientTests.csproj
@@ -1,4 +1,4 @@
-<Project Sdk="Microsoft.NET.Sdk">
+<Project Sdk="Microsoft.NET.Sdk">
 
   <PropertyGroup>
     <TargetFramework>net6.0</TargetFramework>
diff --git a/ld_client/LDClientTests/network/ApiClientTests.cs b/ld_client/LDClientTests/network/ApiClientTests.cs
new file mode 100644
index 0000000..5210030
--- /dev/null
+++ b/ld_client/LDClientTests/network/ApiClientTests.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Json;
+using System.Runtime.CompilerServices;
+using System.Text;
+using System.Text.Json;
+using System.Threading;
+using System.Threading.Tasks;
+using DiskQueue;
+using LDClient.network;
+using LDClient.network.data;
+using Moq;
+using Newtonsoft.Json.Serialization;
+using NUnit.Framework;
+using NUnit.Framework.Internal;
+
+
+namespace LDClientTests.network {
+    internal class ApiClientTests {
+
+        private ApiClient _client;
+
+        
+        private Mock<IHttpClient> _httpClientMock;
+
+        private Mock<IPersistentQueue> _cacheMock;
+        private Mock<IPersistentQueueSession> _cacheSessionMock;
+
+        public static readonly Payload ExamplePayload = new() {
+            UserName = "honikCz",
+            HostName = "Bramborak",
+            TimeStamp = "2022-03-21 18:05:00",
+            HeadDevice = new DebuggerInfo {
+                SerialNumber = "C12345678912"
+            },
+            BodyDevice = new DebuggerInfo {
+                SerialNumber = "C98765432198"
+            },
+            Status = ConnectionStatus.Connected
+        };
+        
+        public static readonly string ApiUrl = "http://127.0.0.1";
+        public static readonly string ApiEndPoint = "/lauterbach-debugger-logs/";
+        public static readonly uint ApiPort = 8000;
+        public static readonly uint ApiRetryPeriod = 50;
+        public static readonly uint ApiMaxEntries = 10;
+        public static readonly uint ApiMaxRetries = 5;
+        
+        
+        [SetUp]
+        public void Setup() {
+            
+            _httpClientMock = new Mock<IHttpClient>(MockBehavior.Strict);
+            _cacheMock = new Mock<IPersistentQueue>(MockBehavior.Strict);
+
+            _cacheSessionMock = new Mock<IPersistentQueueSession>(MockBehavior.Strict);
+            _cacheSessionMock.Setup(x => x.Dequeue()).Returns(JsonSerializer.SerializeToUtf8Bytes(ExamplePayload));
+            _cacheSessionMock.Setup(x => x.Dispose()).Callback(() => { });
+            _cacheSessionMock.Setup(p => p.Enqueue(It.IsAny<byte[]>())).Callback(() => { });
+            _cacheSessionMock.Setup(p => p.Flush()).Callback(() => { });
+
+            _cacheMock.Setup(p => p.OpenSession()).Returns(_cacheSessionMock.Object);
+
+            _client = new ApiClient(ApiUrl, ApiPort, ApiEndPoint, ApiRetryPeriod, ApiMaxEntries, ApiMaxRetries, _cacheMock.Object) {
+                _client = _httpClientMock.Object
+            };
+        }
+
+
+        [Test]
+        public async Task SendPayloadAsync_SendingSuccess_PayloadSent() {
+            _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))
+                .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
+
+            await _client.SendPayloadAsync(ExamplePayload);
+
+            _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once);
+        }
+
+
+        [Test]
+        [TestCase(15, true)]
+        [TestCase(0, false)]
+        public async Task SendPayloadAsync_SendingFailure_PayloadSaved2Cache(int itemsInQueueCount, bool isDequeueHappening) {
+
+            _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))
+                .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));
+            _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(itemsInQueueCount);
+
+            await _client.SendPayloadAsync(ExamplePayload);
+            
+            _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Once);
+            _httpClientMock.Verify(x => x.PostAsJsonAsync(It.IsAny<Payload>()), Times.Once);
+            _cacheSessionMock.Verify(x => x.Flush(), Times.Once);
+            
+            _cacheSessionMock.Verify(x => x.Dequeue(), isDequeueHappening ? Times.Once : Times.Never);
+        }
+
+
+        [Test]
+        [Timeout(1000)]
+        public void Run_EmptyCache_NothingSent() {
+            //nothing in cache 
+            _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(0);
+            _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))
+                .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));
+
+            var clientThread = new Thread(_client.Run);
+
+            clientThread.Start();
+            Thread.Sleep(400);
+            _client.ClientRunning = false;
+            //_processDetection.DetectionRunning = false;
+            clientThread.Join();
+
+            _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Never);
+            _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never);
+            _cacheSessionMock.Verify(p => p.Flush(), Times.Never);
+            _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce);
+
+        }
+
+        /// <summary>
+        /// Some tests here can fail due to not long enough sleep period.
+        /// 
+        /// </summary>
+        /// <param name="itemsInQueueCount"></param>
+        /// <param name="flushedHappened"></param>
+        /// <param name="testSleep"></param>
+        [Test]
+        [Timeout(5000)]
+        [TestCase(100, 20, 2000)]
+        [TestCase(15, 3, 600)]
+        [TestCase(1, 1, 200)]
+        [TestCase(6, 2, 400)]
+        public void Run_CacheContainX_SentX(int itemsInQueueCount, int flushedHappened, int testSleep) {
+
+            var cacheItemCount = itemsInQueueCount;
+            //nothing in cache 
+            _cacheMock.Setup(p => p.EstimatedCountOfItemsInQueue).Returns(() => { return cacheItemCount; });
+            _httpClientMock.Setup(p => p.PostAsJsonAsync(It.IsAny<Payload>()))
+                .Returns(Task.FromResult(new HttpResponseMessage(System.Net.HttpStatusCode.OK)));
+            _cacheSessionMock.Setup(x => x.Dequeue())
+                .Returns(() => {
+                    --cacheItemCount;
+                    return JsonSerializer.SerializeToUtf8Bytes(ExamplePayload);
+                });
+
+            var clientThread = new Thread(_client.Run);
+
+            clientThread.Start();
+            Thread.Sleep(testSleep);
+            _client.ClientRunning = false;
+            //_processDetection.DetectionRunning = false;
+            clientThread.Join();
+
+            _httpClientMock.Verify(p => p.PostAsJsonAsync(It.IsAny<Payload>()), Times.Exactly(itemsInQueueCount));
+            _cacheSessionMock.Verify(p => p.Enqueue(It.IsAny<byte[]>()), Times.Never);
+            _cacheSessionMock.Verify(p => p.Flush(), Times.Exactly(flushedHappened));
+            _cacheMock.Verify(p => p.EstimatedCountOfItemsInQueue, Times.AtLeastOnce);
+        }
+        
+
+    }
+}
-- 
GitLab


From 7b6b75a3ce9b740dbca019d788798e2959c05652 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Wed, 27 Apr 2022 11:08:42 +0200
Subject: [PATCH 41/67] re #9573 Added a sequence and UML diagram

---
 .../ASWI_SequenceDiagram.drawio               |   1 +
 .../ASWI_SequenceDiagram.drawio.pdf           | Bin 0 -> 47537 bytes
 ld_client/doc/uml/ld_uml.pdf                  | Bin 0 -> 37852 bytes
 ld_client/doc/uml/ld_uml.txt                  | 154 ++++++++++++++++++
 4 files changed, 155 insertions(+)
 create mode 100644 ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio
 create mode 100644 ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf
 create mode 100644 ld_client/doc/uml/ld_uml.pdf
 create mode 100644 ld_client/doc/uml/ld_uml.txt

diff --git a/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio
new file mode 100644
index 0000000..dc3bd8e
--- /dev/null
+++ b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio
@@ -0,0 +1 @@
+<mxfile host="Electron" modified="2022-04-27T08:58:36.177Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/16.5.1 Chrome/96.0.4664.110 Electron/16.0.7 Safari/537.36" etag="pkxSyWU8jUEetNVYmsDH" version="16.5.1" type="device"><diagram id="kgpKYQtTHZ0yAKxKKP6v" name="Page-1">7Vxtd9o4Fv41nDP7AY5fwXwkkHRmNnuaJum0O98UI8BbYxFbNNBfv5Is27IkGwN2QqZlzpxaV7Js3/vovukqPXu63n2IwWb1HzSHYc8y5ruePetZljmyDfIPpew5xfCslLKMgzmnFYSH4AfMBnLqNpjDpDQQIxTiYFMm+iiKoI9LNBDH6KU8bIHC8lM3YAkVwoMPQpX6JZjjVUr1XKOg/w6D5Sp7smnwnjXIBnNCsgJz9CKQ7OuePY0RwunVejeFIeVexpf0vpuK3vzFYhjhJjfY0fbqZheP/f2tsYk+fnm0wIc+n+U7CLf8g3v25I9ogW4g9lcw5q+O9xk/yFds6OV2Hd4GCxgGEWldbWAcrCEm4+1ZyMl3Be2KSAcDQqP9JmuHIdgkwROb1iCUGPrbOAm+w3uYpCBgVLSN5nDOWzkHWQPH6FsuEzrpIgjDKQpRzN7UXrj0P0onDxfo6S+fQegZsh/pUVmb8QnGGO4EEmf1B4jIp8Z7MoT3WhnyOfA93nwpQGQ6bkpbCQByHD4QcOAu86kL2ZILLt4jRG2popaFu0FBhNlz3aueO5MEi2K8QksUgVAU7VEiUhlbi8rG3M44uZeYL3LbUJmdE89h9ifv+9/B1z+Hn5N4/tV//Ph9/6fTH2mYPQwxR2OJ68PnLco6+in2J2TAeLMr+sjVkv57B+KE8NoybgJyN5+RvGA6aTpGkSrhIaWv8DrkYigjP0JsDYvLh5NAGCwj0vSJuJiwqUQCohwnvGMdzOf0MVcvqwDDhw3w6TNfiC1QkFEh0qZoqBS9Vxa9Y6qiH2pE34bktW/r6jTqo22tsf+OlekcQG/ha5Wm78GnRTtK0zUPK03dOu5OaTrvR2m6R3O7zOzcczmgNE2rBWabt8Pdx7vnyI6//nux2n14TibP/WziOm7DOXHPeLPg7XVBlXhbjLlFaMM5+j+I8Z77mmCLUVk7wl2Av/Lb6fV/6fXAln68c7YTRs72QkOQt6AAm4oxQdvYhzXMMr10IGVIrbRjGAJMdEHZNdbIjt96R/FcoGRYgZJsBgziJcT8pgIAkzgGe2EYXyWVjzEd/XMKPKUzFujKP7ER4LznT/0H49sf7l+fruP+7y/26sdffVP1iaY8jrCM21mVJT3WfIZwgeuMZ0LsZhAtb9mwmVNQ7vmqoyREbl+ETE2syI0wooqmpHquCMemxsClSsiakrZZtFO9RBYD+T7y+iBgGIQgwS8wwWzVYIBBYUKoR8FXyKhDHTSWpF5jvdtXN6qTNkXrNYjmCYsyaVQZQ4Ahbe3wz4yGrsTfl7y3PFgWbZDOfbO7MviegokERtTjvgP7EIG5ggJZjk8IY7SmNiCaT2gCgtJC5H9jJPKKzLQMnLGVEVL7Yo4OewJseGFxWGsvtg7bHLOheeGOT6rdD4v8oBXKBG4MLIMYT3bTmZbJGpXBY8qaIv1IxTQpE7mWMtHAEH7Sm1VYvGLabCBaLBJYGnOC4dJyfayg9PH+8zWZ6mZy+3B9FkabQJBC2BwYrluG8HjYKkZF7NVh9Ajs2SN31Ar2XNkt8rzTsGcZ0kRuM/+qI7TpXU0FbWlIG8O1ArVfIW0ZdEPncEhr6Ayc15nbo0rzAkLaWuCdmgdsGtJanTHbVP2Jz0l9Wn3iYyTm2m7BEwzvUBLgAJWUt6zVMY1vxUAWbTFdaNN8a6RC3bbCeil1M27I+a4Yb+t01l2MfJjMCGJ9xsz3q7zednMjTwEdqdTcNtz2OlfgPSg1+1huS0pt1GxltZES1dsPldf3cEPi5B5FxZBAzaT82UY4oHNFiHbgmIxVlttLsA4BW2MrFAc/6DoKS+wV8Htz4xFXnPWAOEtNWHY5VTHuUAySgnNVMTgjjRxGLchBn7xSg4B/LOadhoa8DTuuZXaj1HQRTPkhSJLAL5vjMmOlBJuQGnCdnJDGVZ5ntxRY1cjmYLRl8oEHwy1BRq7OCHDauRFYeTk6w3F5hqYBWH94YKKKAKyt4EpNQv59Q9p98v/j/WR6bVvZPm+yAVFPt3Psp1qS7hrHyyfwm8E0MXkdQ3v1L3pJ4WGwLecFWAfhPr19jSKUsF3c0pBiV9rQ7Ur3iGGXSoBcwgFKZeUteSvjiMt4Qigzek1fzKVMcAlvD40187EZsk+axiqmSTmf99CrcgVMNjBlfD4wdRZpU3QXSVvQsbRXdRnpmMJppGNMTiscR0o1GFV2HoUerlAKCtfWAkHQ2MWDhI9PNXIT9uZdOWeLNe/S5VSMFERh7Au6J5Bf8ldKbzGEPq4t8k5b7CTLMu9YCi8gC541c+nXo8GuQ4Ne+tl+Vtp2KUtpol2Rvs7Gvr7s8u84KDtqeDWiG9WJrlpy5rhjyTmVkpsHRJGRFVwpwXL4TMk8sk55T5zM1JozKZLJGT238Ww8S5nmwx+y1emdJk9mWI+SZm61VSTrBZ3bXN1j6uSTT8ftYBk0ffMwasTZS7a5EgDCm5+ADOGNfvY17erVcUlNH7GovbbWNCOWPYRM9LIrkVe6pU5QRaVb2cPW1aQJ7vibpIMdTfRuZ1mRV0mMaWoePn+hnt5kE0zDAEbqRvc5bH3jRJUmSNdtJ3fHbW0esprVvzKQJyVj3j4Bab6jDKR5djpGk/zqKgepTcfY6pYkzTCSoHkI1lQhcftgBCSQ6/FinmzJpS1e1jEHGGQkvIKsI/6u2aG5jCpqIWtkHrObc7TEvfICczQrrKu6HH3WWVNXfV4CLivzzAsZ8lJPY+z1zq/u1FTa1J3LOJx/611S+s2WAKIU1DfNvznSQRmliqfj/Fv2+BaBJZTI2FIql2YXu6rj0mtKFV11KLwQdA1Hkvo5tbRrJO1UOjJMWypfrnpOp+XLqiffkko0BsNRSSNauYZ8I41Yh+0LwawtYdaWvZ/GmJWKoonj3JVGrGOrACvi1MCHfYLfV71XJQCP8IIanOLsrHpLK5zLDDNqcfQuqre0XzDsSsGaJe1ar1uFVHQeUpzuD4xU3Vq3K3wputVrSbfK3mZep/ZKulWt2ZjBp+1ySZYiiVTZ8V419LxgHdteUqhBZHusPrFPrL1t5TipvmanQbBxKep7fCy7JfVta9mtsZWd1eyo/vFDmvRJT8+nSZ8nmDKDnavX53x+hhNeB8/7tYORvnsYJGMNSNo4rq9fkZrDDefZ+JPtdV21/juLhUbSqRbFH258NEuaSCmnbCt+lx0Mr934XS9b1b902SsRqFA3wEggMeJUYQl1tcGi10FRbQvW1nIqfDQxZayrkDXbWNx6J1Zd3Nc7H27S4n+DTk6hjrdxlFsFvQkQVnvzdH5M3SpBx6qWnf7xAe56HbOjoJFWLb6ay3BcVs+6fZ6udqv1Nlw9P5OfyV7UyOuXyW4PFK4UM2nWtfeaJlutmL3PljCxvRQaubLsTa3ehJW+sotUYd4sQJj81MhpQdubkqbQFbboUNGZt685aVfnyHEpNkiFO45TytakB/dfKRWuOQpdtyYuxP2zRs7AUQ/Q53vJzmA0Fn7uab6hORwP3KNm7ji5Y7UeS1QfEnGUQyId7iyeBc3xRUHTlo2Z7Lo0ziRKJUi2PFF7YNP+hUFNYdl5WCs0nmlZJY3njU7UeJLMT8tYZ3xutoX9ZriSAlX31B1rWzrY5DbcsW4LVw02mE7FVbnKxnFP/Rtqx8KqeoPjrdBiynvFslvU+M+HyHmL1rRQj5dmC8OLomz7+v8=</diagram></mxfile>
\ No newline at end of file
diff --git a/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf b/ld_client/doc/sequence_diagram/ASWI_SequenceDiagram.drawio.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..5128acd1bf415de1716ada13e610c8526e0c55c3
GIT binary patch
literal 47537
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
DXrqKP

literal 0
HcmV?d00001

diff --git a/ld_client/doc/uml/ld_uml.pdf b/ld_client/doc/uml/ld_uml.pdf
new file mode 100644
index 0000000000000000000000000000000000000000..12dce252ae25008aabeceffc8606623a4275cc69
GIT binary patch
literal 37852
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
Ipwke413SdetN;K2

literal 0
HcmV?d00001

diff --git a/ld_client/doc/uml/ld_uml.txt b/ld_client/doc/uml/ld_uml.txt
new file mode 100644
index 0000000..39a6ec0
--- /dev/null
+++ b/ld_client/doc/uml/ld_uml.txt
@@ -0,0 +1,154 @@
+@startuml
+interface IProcessDection {
+  + void RunPeriodicDetection()
+}
+
+class ProcessDetection {
+   ____
+  + ProcessProcessDetection(string processName,
+                            uint detectionPeriodMs,
+                            InfoFetcher infoFetcher,
+                            IApiClient apiClient)
+                            
+  + async void RunPeriodicDetection()
+}
+
+interface IApiClient {
+  + Task SendPayloadAsync(Payload payload)
+  + void Run()
+}
+
+class ApiClient {
+  ____
+  + ApiClient(string url, uint port,
+              string path, uint retryPeriod,
+              uint maxEntries, uint maxRetries,
+              string cacheFilename)
+  
+  + async Task SendPayloadAsync(Payload payload)
+  + async void Run()
+}
+
+class InfoFetcher {
+  ____
+  + string HeadSerialNumber
+  + string BodySerialNumber
+  
+  + InfoFetcher(uint maxAttempts, uint waitPeriodMs,
+                string infoFilePath, string f32RemExecutable,
+                string[] f32RemArguments, int f32SuccessExitCode,
+                int f32WaitTimeoutMs)
+  
+  + async Task<bool> FetchDataAsync()
+}
+
+class DebuggerInfoParser {
+  + {static} static (string headSerialNumber,
+    {static} string bodySerialNumber) Parse(string dataTxt)
+}
+
+abstract class ALogger{
+  + ALogger Current
+
+  - LogVerbosity _verbosity
+  - LogFlow _logFlow
+
+  + void Info(string message)
+  + void Debug(string message)
+  + void Error(string message)
+  + void Error(Exception e)
+  
+  # ALogger()
+  
+  {abstract} # CreateLog(string message)
+}
+
+
+class FileLogger{
+  # CreateLog(string message)
+  - void Rotate(string filePat)
+  
+}
+
+class ConsoleLogger{
+ # CreateLog(string message)
+ 
+}
+
+enum LogVerbosity{
+  None
+  Exceptions
+  Full
+}
+
+enum LogFlow{
+  Console
+  File
+}
+
+
+class Payload{
+  + string UserName
+  + string HostName
+  + string TimeStamp
+  + DebuggerInfo HeadDevice
+  + DebuggerInfo BodyDevice
+  + ConnectionStatus Status
+}
+
+class DebuggerInfo{
+  + string SerialNumber
+}
+
+enum ConnectionStatus{
+  Connected
+  Disconnected
+}
+
+LogVerbosity -[hidden] ALogger
+ALogger -left[hidden] LogFlow
+
+ALogger ---left[hidden] ProcessDetection
+
+Payload -right[hidden] ApiClient
+
+ALogger <|.. FileLogger
+ALogger <|.. ConsoleLogger
+ALogger .. LogVerbosity
+ALogger .. LogFlow
+
+Payload o- DebuggerInfo
+Payload o- ConnectionStatus
+
+IProcessDection <|.. ProcessDetection : implements
+IApiClient <|.. ApiClient : implements
+DebuggerInfoParser <.. InfoFetcher : calls (uses)
+ProcessDetection o-- IApiClient : is held in
+note on link: Uses ApiClient to send\ndatato the server
+ProcessDetection o-- InfoFetcher : is held in
+note on link: Calls FetchDataAsync,\nreads the status\ncode (true/false)
+
+class DebuggerInfoParser
+note left: Parses the content of a .txt file \n(throws an ArgumentException)
+
+class InfoFetcher
+note left: Sends commands to the\ndebugger, periodically attempts\nto parse the .txt file 
+
+class ApiClient
+note left: Sends data (payload) to the server,\nmanages a file-based cache.
+
+class ProcessDetection
+note top: Detects a running\nprocess (t32mtc)
+
+note top of ALogger
+  Wraps up common logging functions.
+  Singleton design pattern
+end note
+
+note bottom of FileLogger
+  Transfers logs into file. Upon reaching
+  specified size starts logging into new file. 
+  Full block of files are zipped.
+end note
+
+@enduml
-- 
GitLab


From 015ea63649eb8219507b643f2c05a7ab71417d84 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Wed, 27 Apr 2022 18:45:14 +0200
Subject: [PATCH 42/67] re #9573 added ld coverage

---
 .../doc/coverage/2022-04-26 21_33_03.coverage  | Bin 0 -> 116240 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 ld_client/doc/coverage/2022-04-26 21_33_03.coverage

diff --git a/ld_client/doc/coverage/2022-04-26 21_33_03.coverage b/ld_client/doc/coverage/2022-04-26 21_33_03.coverage
new file mode 100644
index 0000000000000000000000000000000000000000..8c85839f595cac63ae4761a73585d6a4c27a0cc1
GIT binary patch
literal 116240
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

literal 0
HcmV?d00001

-- 
GitLab


From b78da0228175d682f1ab9a7e59f0c6fdb04228c5 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Wed, 27 Apr 2022 19:50:09 +0200
Subject: [PATCH 43/67] re #9573 Added generated html of code coverage

---
 .../doc/coverage/coveragereport/class.js      | 218 ++++++
 .../doc/coverage/coveragereport/icon_cube.svg |   2 +
 .../coveragereport/icon_cube_dark.svg         |   1 +
 .../coveragereport/icon_down-dir_active.svg   |   2 +
 .../icon_down-dir_active_dark.svg             |   1 +
 .../doc/coverage/coveragereport/icon_fork.svg |   2 +
 .../coveragereport/icon_fork_dark.svg         |   1 +
 .../coveragereport/icon_info-circled.svg      |   2 +
 .../coveragereport/icon_info-circled_dark.svg |   2 +
 .../coverage/coveragereport/icon_minus.svg    |   2 +
 .../coveragereport/icon_minus_dark.svg        |   1 +
 .../doc/coverage/coveragereport/icon_plus.svg |   2 +
 .../coveragereport/icon_plus_dark.svg         |   1 +
 .../coveragereport/icon_search-minus.svg      |   2 +
 .../coveragereport/icon_search-minus_dark.svg |   1 +
 .../coveragereport/icon_search-plus.svg       |   2 +
 .../coveragereport/icon_search-plus_dark.svg  |   1 +
 .../coverage/coveragereport/icon_sponsor.svg  |   2 +
 .../doc/coverage/coveragereport/icon_star.svg |   2 +
 .../coveragereport/icon_star_dark.svg         |   2 +
 .../coverage/coveragereport/icon_up-dir.svg   |   2 +
 .../coveragereport/icon_up-dir_active.svg     |   2 +
 .../coverage/coveragereport/icon_wrench.svg   |   2 +
 .../coveragereport/icon_wrench_dark.svg       |   1 +
 .../doc/coverage/coveragereport/index.htm     | 197 +++++
 .../doc/coverage/coveragereport/index.html    | 197 +++++
 .../coveragereport/ldclient.dll_ALogger.html  | 301 +++++++
 .../ldclient.dll_ApiClient.html               | 285 +++++++
 .../ldclient.dll_ConfigLoader.html            | 346 ++++++++
 .../ldclient.dll_ConsoleLogger.html           | 174 +++++
 .../ldclient.dll_DebuggerInfo.html            | 168 ++++
 .../ldclient.dll_DebuggerInfoParser.html      | 190 +++++
 .../ldclient.dll_FileLogger.html              | 272 +++++++
 .../ldclient.dll_FileUtils.html               | 180 +++++
 .../ldclient.dll_HttpClient.html              | 201 +++++
 .../ldclient.dll_InfoFetcher.html             | 263 +++++++
 .../coveragereport/ldclient.dll_Payload.html  | 232 ++++++
 .../ldclient.dll_ProcessDetection.html        | 268 +++++++
 .../ldclient.dll_ProcessUtils.html            | 209 +++++
 .../coveragereport/ldclient.dll_Program.html  | 240 ++++++
 .../ldclienttests.dll_ApiClientTests.html     | 344 ++++++++
 ...ienttests.dll_DebuggerInfoParserTests.html | 237 ++++++
 .../ldclienttests.dll_InfoFetcherTests.html   | 294 +++++++
 ...clienttests.dll_ProcessDetectionTests.html | 311 ++++++++
 ld_client/doc/coverage/coveragereport/main.js | 301 +++++++
 .../doc/coverage/coveragereport/report.css    | 736 ++++++++++++++++++
 46 files changed, 6202 insertions(+)
 create mode 100644 ld_client/doc/coverage/coveragereport/class.js
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_cube.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_cube_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_fork.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_fork_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_info-circled.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_minus.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_minus_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_plus.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_plus_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-minus.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-plus.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_sponsor.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_star.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_star_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_up-dir.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_wrench.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg
 create mode 100644 ld_client/doc/coverage/coveragereport/index.htm
 create mode 100644 ld_client/doc/coverage/coveragereport/index.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html
 create mode 100644 ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html
 create mode 100644 ld_client/doc/coverage/coveragereport/main.js
 create mode 100644 ld_client/doc/coverage/coveragereport/report.css

diff --git a/ld_client/doc/coverage/coveragereport/class.js b/ld_client/doc/coverage/coveragereport/class.js
new file mode 100644
index 0000000..b7a43b2
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/class.js
@@ -0,0 +1,218 @@
+/* Chartist.js 0.11.4
+ * Copyright © 2019 Gion Kunz
+ * Free to use under either the WTFPL license or the MIT license.
+ * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL
+ * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT
+ */
+
+!function (a, b) { "function" == typeof define && define.amd ? define("Chartist", [], function () { return a.Chartist = b() }) : "object" == typeof module && module.exports ? module.exports = b() : a.Chartist = b() }(this, function () {
+    var a = { version: "0.11.4" }; return function (a, b) { "use strict"; var c = a.window, d = a.document; b.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, b.noop = function (a) { return a }, b.alphaNumerate = function (a) { return String.fromCharCode(97 + a % 26) }, b.extend = function (a) { var c, d, e; for (a = a || {}, c = 1; c < arguments.length; c++) { d = arguments[c]; for (var f in d) e = d[f], "object" != typeof e || null === e || e instanceof Array ? a[f] = e : a[f] = b.extend(a[f], e) } return a }, b.replaceAll = function (a, b, c) { return a.replace(new RegExp(b, "g"), c) }, b.ensureUnit = function (a, b) { return "number" == typeof a && (a += b), a }, b.quantity = function (a) { if ("string" == typeof a) { var b = /^(\d+)\s*(.*)$/g.exec(a); return { value: +b[1], unit: b[2] || void 0 } } return { value: a } }, b.querySelector = function (a) { return a instanceof Node ? a : d.querySelector(a) }, b.times = function (a) { return Array.apply(null, new Array(a)) }, b.sum = function (a, b) { return a + (b ? b : 0) }, b.mapMultiply = function (a) { return function (b) { return b * a } }, b.mapAdd = function (a) { return function (b) { return b + a } }, b.serialMap = function (a, c) { var d = [], e = Math.max.apply(null, a.map(function (a) { return a.length })); return b.times(e).forEach(function (b, e) { var f = a.map(function (a) { return a[e] }); d[e] = c.apply(null, f) }), d }, b.roundWithPrecision = function (a, c) { var d = Math.pow(10, c || b.precision); return Math.round(a * d) / d }, b.precision = 8, b.escapingMap = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" }, b.serialize = function (a) { return null === a || void 0 === a ? a : ("number" == typeof a ? a = "" + a : "object" == typeof a && (a = JSON.stringify({ data: a })), Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, c, b.escapingMap[c]) }, a)) }, b.deserialize = function (a) { if ("string" != typeof a) return a; a = Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, b.escapingMap[c], c) }, a); try { a = JSON.parse(a), a = void 0 !== a.data ? a.data : a } catch (c) { } return a }, b.createSvg = function (a, c, d, e) { var f; return c = c || "100%", d = d || "100%", Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function (a) { return a.getAttributeNS(b.namespaces.xmlns, "ct") }).forEach(function (b) { a.removeChild(b) }), f = new b.Svg("svg").attr({ width: c, height: d }).addClass(e), f._node.style.width = c, f._node.style.height = d, a.appendChild(f._node), f }, b.normalizeData = function (a, c, d) { var e, f = { raw: a, normalized: {} }; return f.normalized.series = b.getDataArray({ series: a.series || [] }, c, d), e = f.normalized.series.every(function (a) { return a instanceof Array }) ? Math.max.apply(null, f.normalized.series.map(function (a) { return a.length })) : f.normalized.series.length, f.normalized.labels = (a.labels || []).slice(), Array.prototype.push.apply(f.normalized.labels, b.times(Math.max(0, e - f.normalized.labels.length)).map(function () { return "" })), c && b.reverseData(f.normalized), f }, b.safeHasProperty = function (a, b) { return null !== a && "object" == typeof a && a.hasOwnProperty(b) }, b.isDataHoleValue = function (a) { return null === a || void 0 === a || "number" == typeof a && isNaN(a) }, b.reverseData = function (a) { a.labels.reverse(), a.series.reverse(); for (var b = 0; b < a.series.length; b++)"object" == typeof a.series[b] && void 0 !== a.series[b].data ? a.series[b].data.reverse() : a.series[b] instanceof Array && a.series[b].reverse() }, b.getDataArray = function (a, c, d) { function e(a) { if (b.safeHasProperty(a, "value")) return e(a.value); if (b.safeHasProperty(a, "data")) return e(a.data); if (a instanceof Array) return a.map(e); if (!b.isDataHoleValue(a)) { if (d) { var c = {}; return "string" == typeof d ? c[d] = b.getNumberOrUndefined(a) : c.y = b.getNumberOrUndefined(a), c.x = a.hasOwnProperty("x") ? b.getNumberOrUndefined(a.x) : c.x, c.y = a.hasOwnProperty("y") ? b.getNumberOrUndefined(a.y) : c.y, c } return b.getNumberOrUndefined(a) } } return a.series.map(e) }, b.normalizePadding = function (a, b) { return b = b || 0, "number" == typeof a ? { top: a, right: a, bottom: a, left: a } : { top: "number" == typeof a.top ? a.top : b, right: "number" == typeof a.right ? a.right : b, bottom: "number" == typeof a.bottom ? a.bottom : b, left: "number" == typeof a.left ? a.left : b } }, b.getMetaData = function (a, b) { var c = a.data ? a.data[b] : a[b]; return c ? c.meta : void 0 }, b.orderOfMagnitude = function (a) { return Math.floor(Math.log(Math.abs(a)) / Math.LN10) }, b.projectLength = function (a, b, c) { return b / c.range * a }, b.getAvailableHeight = function (a, c) { return Math.max((b.quantity(c.height).value || a.height()) - (c.chartPadding.top + c.chartPadding.bottom) - c.axisX.offset, 0) }, b.getHighLow = function (a, c, d) { function e(a) { if (void 0 !== a) if (a instanceof Array) for (var b = 0; b < a.length; b++)e(a[b]); else { var c = d ? +a[d] : +a; g && c > f.high && (f.high = c), h && c < f.low && (f.low = c) } } c = b.extend({}, c, d ? c["axis" + d.toUpperCase()] : {}); var f = { high: void 0 === c.high ? -Number.MAX_VALUE : +c.high, low: void 0 === c.low ? Number.MAX_VALUE : +c.low }, g = void 0 === c.high, h = void 0 === c.low; return (g || h) && e(a), (c.referenceValue || 0 === c.referenceValue) && (f.high = Math.max(c.referenceValue, f.high), f.low = Math.min(c.referenceValue, f.low)), f.high <= f.low && (0 === f.low ? f.high = 1 : f.low < 0 ? f.high = 0 : f.high > 0 ? f.low = 0 : (f.high = 1, f.low = 0)), f }, b.isNumeric = function (a) { return null !== a && isFinite(a) }, b.isFalseyButZero = function (a) { return !a && 0 !== a }, b.getNumberOrUndefined = function (a) { return b.isNumeric(a) ? +a : void 0 }, b.isMultiValue = function (a) { return "object" == typeof a && ("x" in a || "y" in a) }, b.getMultiValue = function (a, c) { return b.isMultiValue(a) ? b.getNumberOrUndefined(a[c || "y"]) : b.getNumberOrUndefined(a) }, b.rho = function (a) { function b(a, c) { return a % c === 0 ? c : b(c, a % c) } function c(a) { return a * a + 1 } if (1 === a) return a; var d, e = 2, f = 2; if (a % 2 === 0) return 2; do e = c(e) % a, f = c(c(f)) % a, d = b(Math.abs(e - f), a); while (1 === d); return d }, b.getBounds = function (a, c, d, e) { function f(a, b) { return a === (a += b) && (a *= 1 + (b > 0 ? o : -o)), a } var g, h, i, j = 0, k = { high: c.high, low: c.low }; k.valueRange = k.high - k.low, k.oom = b.orderOfMagnitude(k.valueRange), k.step = Math.pow(10, k.oom), k.min = Math.floor(k.low / k.step) * k.step, k.max = Math.ceil(k.high / k.step) * k.step, k.range = k.max - k.min, k.numberOfSteps = Math.round(k.range / k.step); var l = b.projectLength(a, k.step, k), m = l < d, n = e ? b.rho(k.range) : 0; if (e && b.projectLength(a, 1, k) >= d) k.step = 1; else if (e && n < k.step && b.projectLength(a, n, k) >= d) k.step = n; else for (; ;) { if (m && b.projectLength(a, k.step, k) <= d) k.step *= 2; else { if (m || !(b.projectLength(a, k.step / 2, k) >= d)) break; if (k.step /= 2, e && k.step % 1 !== 0) { k.step *= 2; break } } if (j++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var o = 2.221e-16; for (k.step = Math.max(k.step, o), h = k.min, i = k.max; h + k.step <= k.low;)h = f(h, k.step); for (; i - k.step >= k.high;)i = f(i, -k.step); k.min = h, k.max = i, k.range = k.max - k.min; var p = []; for (g = k.min; g <= k.max; g = f(g, k.step)) { var q = b.roundWithPrecision(g); q !== p[p.length - 1] && p.push(q) } return k.values = p, k }, b.polarToCartesian = function (a, b, c, d) { var e = (d - 90) * Math.PI / 180; return { x: a + c * Math.cos(e), y: b + c * Math.sin(e) } }, b.createChartRect = function (a, c, d) { var e = !(!c.axisX && !c.axisY), f = e ? c.axisY.offset : 0, g = e ? c.axisX.offset : 0, h = a.width() || b.quantity(c.width).value || 0, i = a.height() || b.quantity(c.height).value || 0, j = b.normalizePadding(c.chartPadding, d); h = Math.max(h, f + j.left + j.right), i = Math.max(i, g + j.top + j.bottom); var k = { padding: j, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return e ? ("start" === c.axisX.position ? (k.y2 = j.top + g, k.y1 = Math.max(i - j.bottom, k.y2 + 1)) : (k.y2 = j.top, k.y1 = Math.max(i - j.bottom - g, k.y2 + 1)), "start" === c.axisY.position ? (k.x1 = j.left + f, k.x2 = Math.max(h - j.right, k.x1 + 1)) : (k.x1 = j.left, k.x2 = Math.max(h - j.right - f, k.x1 + 1))) : (k.x1 = j.left, k.x2 = Math.max(h - j.right, k.x1 + 1), k.y2 = j.top, k.y1 = Math.max(i - j.bottom, k.y2 + 1)), k }, b.createGrid = function (a, c, d, e, f, g, h, i) { var j = {}; j[d.units.pos + "1"] = a, j[d.units.pos + "2"] = a, j[d.counterUnits.pos + "1"] = e, j[d.counterUnits.pos + "2"] = e + f; var k = g.elem("line", j, h.join(" ")); i.emit("draw", b.extend({ type: "grid", axis: d, index: c, group: g, element: k }, j)) }, b.createGridBackground = function (a, b, c, d) { var e = a.elem("rect", { x: b.x1, y: b.y2, width: b.width(), height: b.height() }, c, !0); d.emit("draw", { type: "gridBackground", group: a, element: e }) }, b.createLabel = function (a, c, e, f, g, h, i, j, k, l, m) { var n, o = {}; if (o[g.units.pos] = a + i[g.units.pos], o[g.counterUnits.pos] = i[g.counterUnits.pos], o[g.units.len] = c, o[g.counterUnits.len] = Math.max(0, h - 10), l) { var p = d.createElement("span"); p.className = k.join(" "), p.setAttribute("xmlns", b.namespaces.xhtml), p.innerText = f[e], p.style[g.units.len] = Math.round(o[g.units.len]) + "px", p.style[g.counterUnits.len] = Math.round(o[g.counterUnits.len]) + "px", n = j.foreignObject(p, b.extend({ style: "overflow: visible;" }, o)) } else n = j.elem("text", o, k.join(" ")).text(f[e]); m.emit("draw", b.extend({ type: "label", axis: g, index: e, group: j, element: n, text: f[e] }, o)) }, b.getSeriesOption = function (a, b, c) { if (a.name && b.series && b.series[a.name]) { var d = b.series[a.name]; return d.hasOwnProperty(c) ? d[c] : b[c] } return b[c] }, b.optionsProvider = function (a, d, e) { function f(a) { var f = h; if (h = b.extend({}, j), d) for (i = 0; i < d.length; i++) { var g = c.matchMedia(d[i][0]); g.matches && (h = b.extend(h, d[i][1])) } e && a && e.emit("optionsChanged", { previousOptions: f, currentOptions: h }) } function g() { k.forEach(function (a) { a.removeListener(f) }) } var h, i, j = b.extend({}, a), k = []; if (!c.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (d) for (i = 0; i < d.length; i++) { var l = c.matchMedia(d[i][0]); l.addListener(f), k.push(l) } return f(), { removeMediaQueryListeners: g, getCurrentOptions: function () { return b.extend({}, h) } } }, b.splitIntoSegments = function (a, c, d) { var e = { increasingX: !1, fillHoles: !1 }; d = b.extend({}, e, d); for (var f = [], g = !0, h = 0; h < a.length; h += 2)void 0 === b.getMultiValue(c[h / 2].value) ? d.fillHoles || (g = !0) : (d.increasingX && h >= 2 && a[h] <= a[h - 2] && (g = !0), g && (f.push({ pathCoordinates: [], valueData: [] }), g = !1), f[f.length - 1].pathCoordinates.push(a[h], a[h + 1]), f[f.length - 1].valueData.push(c[h / 2])); return f } }(this || global, a), function (a, b) { "use strict"; b.Interpolation = {}, b.Interpolation.none = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e = new b.Svg.Path, f = !0, g = 0; g < c.length; g += 2) { var h = c[g], i = c[g + 1], j = d[g / 2]; void 0 !== b.getMultiValue(j.value) ? (f ? e.move(h, i, !1, j) : e.line(h, i, !1, j), f = !1) : a.fillHoles || (f = !0) } return e } }, b.Interpolation.simple = function (a) { var c = { divisor: 2, fillHoles: !1 }; a = b.extend({}, c, a); var d = 1 / Math.max(1, a.divisor); return function (c, e) { for (var f, g, h, i = new b.Svg.Path, j = 0; j < c.length; j += 2) { var k = c[j], l = c[j + 1], m = (k - f) * d, n = e[j / 2]; void 0 !== n.value ? (void 0 === h ? i.move(k, l, !1, n) : i.curve(f + m, g, k - m, l, k, l, !1, n), f = k, g = l, h = n) : a.fillHoles || (f = k = h = void 0) } return i } }, b.Interpolation.cardinal = function (a) { var c = { tension: 1, fillHoles: !1 }; a = b.extend({}, c, a); var d = Math.min(1, Math.max(0, a.tension)), e = 1 - d; return function f(c, g) { var h = b.splitIntoSegments(c, g, { fillHoles: a.fillHoles }); if (h.length) { if (h.length > 1) { var i = []; return h.forEach(function (a) { i.push(f(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(i) } if (c = h[0].pathCoordinates, g = h[0].valueData, c.length <= 4) return b.Interpolation.none()(c, g); for (var j, k = (new b.Svg.Path).move(c[0], c[1], !1, g[0]), l = 0, m = c.length; m - 2 * !j > l; l += 2) { var n = [{ x: +c[l - 2], y: +c[l - 1] }, { x: +c[l], y: +c[l + 1] }, { x: +c[l + 2], y: +c[l + 3] }, { x: +c[l + 4], y: +c[l + 5] }]; j ? l ? m - 4 === l ? n[3] = { x: +c[0], y: +c[1] } : m - 2 === l && (n[2] = { x: +c[0], y: +c[1] }, n[3] = { x: +c[2], y: +c[3] }) : n[0] = { x: +c[m - 2], y: +c[m - 1] } : m - 4 === l ? n[3] = n[2] : l || (n[0] = { x: +c[l], y: +c[l + 1] }), k.curve(d * (-n[0].x + 6 * n[1].x + n[2].x) / 6 + e * n[2].x, d * (-n[0].y + 6 * n[1].y + n[2].y) / 6 + e * n[2].y, d * (n[1].x + 6 * n[2].x - n[3].x) / 6 + e * n[2].x, d * (n[1].y + 6 * n[2].y - n[3].y) / 6 + e * n[2].y, n[2].x, n[2].y, !1, g[(l + 2) / 2]) } return k } return b.Interpolation.none()([]) } }, b.Interpolation.monotoneCubic = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function d(c, e) { var f = b.splitIntoSegments(c, e, { fillHoles: a.fillHoles, increasingX: !0 }); if (f.length) { if (f.length > 1) { var g = []; return f.forEach(function (a) { g.push(d(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(g) } if (c = f[0].pathCoordinates, e = f[0].valueData, c.length <= 4) return b.Interpolation.none()(c, e); var h, i, j = [], k = [], l = c.length / 2, m = [], n = [], o = [], p = []; for (h = 0; h < l; h++)j[h] = c[2 * h], k[h] = c[2 * h + 1]; for (h = 0; h < l - 1; h++)o[h] = k[h + 1] - k[h], p[h] = j[h + 1] - j[h], n[h] = o[h] / p[h]; for (m[0] = n[0], m[l - 1] = n[l - 2], h = 1; h < l - 1; h++)0 === n[h] || 0 === n[h - 1] || n[h - 1] > 0 != n[h] > 0 ? m[h] = 0 : (m[h] = 3 * (p[h - 1] + p[h]) / ((2 * p[h] + p[h - 1]) / n[h - 1] + (p[h] + 2 * p[h - 1]) / n[h]), isFinite(m[h]) || (m[h] = 0)); for (i = (new b.Svg.Path).move(j[0], k[0], !1, e[0]), h = 0; h < l - 1; h++)i.curve(j[h] + p[h] / 3, k[h] + m[h] * p[h] / 3, j[h + 1] - p[h] / 3, k[h + 1] - m[h + 1] * p[h] / 3, j[h + 1], k[h + 1], !1, e[h + 1]); return i } return b.Interpolation.none()([]) } }, b.Interpolation.step = function (a) { var c = { postpone: !0, fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e, f, g, h = new b.Svg.Path, i = 0; i < c.length; i += 2) { var j = c[i], k = c[i + 1], l = d[i / 2]; void 0 !== l.value ? (void 0 === g ? h.move(j, k, !1, l) : (a.postpone ? h.line(j, f, !1, g) : h.line(e, k, !1, l), h.line(j, k, !1, l)), e = j, f = k, g = l) : a.fillHoles || (e = f = g = void 0) } return h } } }(this || global, a), function (a, b) { "use strict"; b.EventEmitter = function () { function a(a, b) { d[a] = d[a] || [], d[a].push(b) } function b(a, b) { d[a] && (b ? (d[a].splice(d[a].indexOf(b), 1), 0 === d[a].length && delete d[a]) : delete d[a]) } function c(a, b) { d[a] && d[a].forEach(function (a) { a(b) }), d["*"] && d["*"].forEach(function (c) { c(a, b) }) } var d = []; return { addEventHandler: a, removeEventHandler: b, emit: c } } }(this || global, a), function (a, b) { "use strict"; function c(a) { var b = []; if (a.length) for (var c = 0; c < a.length; c++)b.push(a[c]); return b } function d(a, c) { var d = c || this.prototype || b.Class, e = Object.create(d); b.Class.cloneDefinitions(e, a); var f = function () { var a, c = e.constructor || function () { }; return a = this === b ? Object.create(e) : this, c.apply(a, Array.prototype.slice.call(arguments, 0)), a }; return f.prototype = e, f["super"] = d, f.extend = this.extend, f } function e() { var a = c(arguments), b = a[0]; return a.splice(1, a.length - 1).forEach(function (a) { Object.getOwnPropertyNames(a).forEach(function (c) { delete b[c], Object.defineProperty(b, c, Object.getOwnPropertyDescriptor(a, c)) }) }), b } b.Class = { extend: d, cloneDefinitions: e } }(this || global, a), function (a, b) { "use strict"; function c(a, c, d) { return a && (this.data = a || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), c && (this.options = b.extend({}, d ? this.options : this.defaultOptions, c), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this } function d() { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this } function e(a, b) { return this.eventEmitter.addEventHandler(a, b), this } function f(a, b) { return this.eventEmitter.removeEventHandler(a, b), this } function g() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (a) { a instanceof Array ? a[0](this, a[1]) : a(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } function h(a, c, d, e, f) { this.container = b.querySelector(a), this.data = c || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = d, this.options = e, this.responsiveOptions = f, this.eventEmitter = b.EventEmitter(), this.supportsForeignObject = b.Svg.isSupported("Extensibility"), this.supportsAnimations = b.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(g.bind(this), 0) } var i = a.window; b.Base = b.Class.extend({ constructor: h, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: c, detach: d, on: e, off: f, version: b.version, supportsForeignObject: !1 }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f) { a instanceof Element ? this._node = a : (this._node = y.createElementNS(b.namespaces.svg, a), "svg" === a && this.attr({ "xmlns:ct": b.namespaces.ct })), c && this.attr(c), d && this.addClass(d), e && (f && e._node.firstChild ? e._node.insertBefore(this._node, e._node.firstChild) : e._node.appendChild(this._node)) } function d(a, c) { return "string" == typeof a ? c ? this._node.getAttributeNS(c, a) : this._node.getAttribute(a) : (Object.keys(a).forEach(function (c) { if (void 0 !== a[c]) if (c.indexOf(":") !== -1) { var d = c.split(":"); this._node.setAttributeNS(b.namespaces[d[0]], c, a[c]) } else this._node.setAttribute(c, a[c]) }.bind(this)), this) } function e(a, c, d, e) { return new b.Svg(a, c, d, this, e) } function f() { return this._node.parentNode instanceof SVGElement ? new b.Svg(this._node.parentNode) : null } function g() { for (var a = this._node; "svg" !== a.nodeName;)a = a.parentNode; return new b.Svg(a) } function h(a) { var c = this._node.querySelector(a); return c ? new b.Svg(c) : null } function i(a) { var c = this._node.querySelectorAll(a); return c.length ? new b.Svg.List(c) : null } function j() { return this._node } function k(a, c, d, e) { if ("string" == typeof a) { var f = y.createElement("div"); f.innerHTML = a, a = f.firstChild } a.setAttribute("xmlns", b.namespaces.xmlns); var g = this.elem("foreignObject", c, d, e); return g._node.appendChild(a), g } function l(a) { return this._node.appendChild(y.createTextNode(a)), this } function m() { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this } function n() { return this._node.parentNode.removeChild(this._node), this.parent() } function o(a) { return this._node.parentNode.replaceChild(a._node, this._node), a } function p(a, b) { return b && this._node.firstChild ? this._node.insertBefore(a._node, this._node.firstChild) : this._node.appendChild(a._node), this } function q() { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] } function r(a) { return this._node.setAttribute("class", this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function (a, b, c) { return c.indexOf(a) === b }).join(" ")), this } function s(a) { var b = a.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter(function (a) { return b.indexOf(a) === -1 }).join(" ")), this } function t() { return this._node.setAttribute("class", ""), this } function u() { return this._node.getBoundingClientRect().height } function v() { return this._node.getBoundingClientRect().width } function w(a, c, d) { return void 0 === c && (c = !0), Object.keys(a).forEach(function (e) { function f(a, c) { var f, g, h, i = {}; a.easing && (h = a.easing instanceof Array ? a.easing : b.Svg.Easing[a.easing], delete a.easing), a.begin = b.ensureUnit(a.begin, "ms"), a.dur = b.ensureUnit(a.dur, "ms"), h && (a.calcMode = "spline", a.keySplines = h.join(" "), a.keyTimes = "0;1"), c && (a.fill = "freeze", i[e] = a.from, this.attr(i), g = b.quantity(a.begin || 0).value, a.begin = "indefinite"), f = this.elem("animate", b.extend({ attributeName: e }, a)), c && setTimeout(function () { try { f._node.beginElement() } catch (b) { i[e] = a.to, this.attr(i), f.remove() } }.bind(this), g), d && f._node.addEventListener("beginEvent", function () { d.emit("animationBegin", { element: this, animate: f._node, params: a }) }.bind(this)), f._node.addEventListener("endEvent", function () { d && d.emit("animationEnd", { element: this, animate: f._node, params: a }), c && (i[e] = a.to, this.attr(i), f.remove()) }.bind(this)) } a[e] instanceof Array ? a[e].forEach(function (a) { f.bind(this)(a, !1) }.bind(this)) : f.bind(this)(a[e], c) }.bind(this)), this } function x(a) { var c = this; this.svgElements = []; for (var d = 0; d < a.length; d++)this.svgElements.push(new b.Svg(a[d])); Object.keys(b.Svg.prototype).filter(function (a) { return ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(a) === -1 }).forEach(function (a) { c[a] = function () { var d = Array.prototype.slice.call(arguments, 0); return c.svgElements.forEach(function (c) { b.Svg.prototype[a].apply(c, d) }), c } }) } var y = a.document; b.Svg = b.Class.extend({ constructor: c, attr: d, elem: e, parent: f, root: g, querySelector: h, querySelectorAll: i, getNode: j, foreignObject: k, text: l, empty: m, remove: n, replace: o, append: p, classes: q, addClass: r, removeClass: s, removeAllClasses: t, height: u, width: v, animate: w }), b.Svg.isSupported = function (a) { return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + a, "1.1") }; var z = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }; b.Svg.Easing = z, b.Svg.List = b.Class.extend({ constructor: x }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f, g) { var h = b.extend({ command: f ? a.toLowerCase() : a.toUpperCase() }, c, g ? { data: g } : {}); d.splice(e, 0, h) } function d(a, b) { a.forEach(function (c, d) { t[c.command.toLowerCase()].forEach(function (e, f) { b(c, e, d, f, a) }) }) } function e(a, c) { this.pathElements = [], this.pos = 0, this.close = a, this.options = b.extend({}, u, c) } function f(a) { return void 0 !== a ? (this.pos = Math.max(0, Math.min(this.pathElements.length, a)), this) : this.pos } function g(a) { return this.pathElements.splice(this.pos, a), this } function h(a, b, d, e) { return c("M", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function i(a, b, d, e) { return c("L", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function j(a, b, d, e, f, g, h, i) { return c("C", { x1: +a, y1: +b, x2: +d, y2: +e, x: +f, y: +g }, this.pathElements, this.pos++, h, i), this } function k(a, b, d, e, f, g, h, i, j) { return c("A", { rx: +a, ry: +b, xAr: +d, lAf: +e, sf: +f, x: +g, y: +h }, this.pathElements, this.pos++, i, j), this } function l(a) { var c = a.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce(function (a, b) { return b.match(/[A-Za-z]/) && a.push([]), a[a.length - 1].push(b), a }, []); "Z" === c[c.length - 1][0].toUpperCase() && c.pop(); var d = c.map(function (a) { var c = a.shift(), d = t[c.toLowerCase()]; return b.extend({ command: c }, d.reduce(function (b, c, d) { return b[c] = +a[d], b }, {})) }), e = [this.pos, 0]; return Array.prototype.push.apply(e, d), Array.prototype.splice.apply(this.pathElements, e), this.pos += d.length, this } function m() { var a = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (b, c) { var d = t[c.command.toLowerCase()].map(function (b) { return this.options.accuracy ? Math.round(c[b] * a) / a : c[b] }.bind(this)); return b + c.command + d.join(",") }.bind(this), "") + (this.close ? "Z" : "") } function n(a, b) { return d(this.pathElements, function (c, d) { c[d] *= "x" === d[0] ? a : b }), this } function o(a, b) { return d(this.pathElements, function (c, d) { c[d] += "x" === d[0] ? a : b }), this } function p(a) { return d(this.pathElements, function (b, c, d, e, f) { var g = a(b, c, d, e, f); (g || 0 === g) && (b[c] = g) }), this } function q(a) { var c = new b.Svg.Path(a || this.close); return c.pos = this.pos, c.pathElements = this.pathElements.slice().map(function (a) { return b.extend({}, a) }), c.options = b.extend({}, this.options), c } function r(a) { var c = [new b.Svg.Path]; return this.pathElements.forEach(function (d) { d.command === a.toUpperCase() && 0 !== c[c.length - 1].pathElements.length && c.push(new b.Svg.Path), c[c.length - 1].pathElements.push(d) }), c } function s(a, c, d) { for (var e = new b.Svg.Path(c, d), f = 0; f < a.length; f++)for (var g = a[f], h = 0; h < g.pathElements.length; h++)e.pathElements.push(g.pathElements[h]); return e } var t = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, u = { accuracy: 3 }; b.Svg.Path = b.Class.extend({ constructor: e, position: f, remove: g, move: h, line: i, curve: j, arc: k, scale: n, translate: o, transform: p, parse: l, stringify: m, clone: q, splitByCommand: r }), b.Svg.Path.elementDescriptions = t, b.Svg.Path.join = s }(this || global, a), function (a, b) { "use strict"; function c(a, b, c, d) { this.units = a, this.counterUnits = a === e.x ? e.y : e.x, this.chartRect = b, this.axisLength = b[a.rectEnd] - b[a.rectStart], this.gridOffset = b[a.rectOffset], this.ticks = c, this.options = d } function d(a, c, d, e, f) { var g = e["axis" + this.units.pos.toUpperCase()], h = this.ticks.map(this.projectValue.bind(this)), i = this.ticks.map(g.labelInterpolationFnc); h.forEach(function (j, k) { var l, m = { x: 0, y: 0 }; l = h[k + 1] ? h[k + 1] - j : Math.max(this.axisLength - j, 30), b.isFalseyButZero(i[k]) && "" !== i[k] || ("x" === this.units.pos ? (j = this.chartRect.x1 + j, m.x = e.axisX.labelOffset.x, "start" === e.axisX.position ? m.y = this.chartRect.padding.top + e.axisX.labelOffset.y + (d ? 5 : 20) : m.y = this.chartRect.y1 + e.axisX.labelOffset.y + (d ? 5 : 20)) : (j = this.chartRect.y1 - j, m.y = e.axisY.labelOffset.y - (d ? l : 0), "start" === e.axisY.position ? m.x = d ? this.chartRect.padding.left + e.axisY.labelOffset.x : this.chartRect.x1 - 10 : m.x = this.chartRect.x2 + e.axisY.labelOffset.x + 10), g.showGrid && b.createGrid(j, k, this, this.gridOffset, this.chartRect[this.counterUnits.len](), a, [e.classNames.grid, e.classNames[this.units.dir]], f), g.showLabel && b.createLabel(j, l, k, i, this, g.offset, m, c, [e.classNames.label, e.classNames[this.units.dir], "start" === g.position ? e.classNames[g.position] : e.classNames.end], d, f)) }.bind(this)) } var e = (a.window, a.document, { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }); b.Axis = b.Class.extend({ constructor: c, createGridAndLabels: d, projectValue: function (a, b, c) { throw new Error("Base axis can't be instantiated!") } }), b.Axis.units = e }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.bounds = b.getBounds(d[a.rectEnd] - d[a.rectStart], f, e.scaleMinSpace || 20, e.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, b.AutoScaleAxis["super"].constructor.call(this, a, d, this.bounds.values, e) } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.bounds.min) / this.bounds.range } a.window, a.document; b.AutoScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.divisor = e.divisor || 1, this.ticks = e.ticks || b.times(this.divisor).map(function (a, b) { return f.low + (f.high - f.low) / this.divisor * b }.bind(this)), this.ticks.sort(function (a, b) { return a - b }), this.range = { min: f.low, max: f.high }, b.FixedScaleAxis["super"].constructor.call(this, a, d, this.ticks, e), this.stepLength = this.axisLength / this.divisor } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } a.window, a.document; b.FixedScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { b.StepAxis["super"].constructor.call(this, a, d, e.ticks, e); var f = Math.max(1, e.ticks.length - (e.stretch ? 1 : 0)); this.stepLength = this.axisLength / f } function d(a, b) { return this.stepLength * b } a.window, a.document; b.StepAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a) { var c = b.normalizeData(this.data, a.reverseData, !0); this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart); var d, f, g = this.svg.elem("g").addClass(a.classNames.gridGroup), h = this.svg.elem("g"), i = this.svg.elem("g").addClass(a.classNames.labelGroup), j = b.createChartRect(this.svg, a, e.padding); d = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, j, b.extend({}, a.axisX, { ticks: c.normalized.labels, stretch: a.fullWidth })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, j, a.axisX), f = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, j, b.extend({}, a.axisY, { high: b.isNumeric(a.high) ? a.high : a.axisY.high, low: b.isNumeric(a.low) ? a.low : a.axisY.low })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, j, a.axisY), d.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), f.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(g, j, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (e, g) { var i = h.elem("g"); i.attr({ "ct:series-name": e.name, "ct:meta": b.serialize(e.meta) }), i.addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(g)].join(" ")); var k = [], l = []; c.normalized.series[g].forEach(function (a, h) { var i = { x: j.x1 + d.projectValue(a, h, c.normalized.series[g]), y: j.y1 - f.projectValue(a, h, c.normalized.series[g]) }; k.push(i.x, i.y), l.push({ value: a, valueIndex: h, meta: b.getMetaData(e, h) }) }.bind(this)); var m = { lineSmooth: b.getSeriesOption(e, a, "lineSmooth"), showPoint: b.getSeriesOption(e, a, "showPoint"), showLine: b.getSeriesOption(e, a, "showLine"), showArea: b.getSeriesOption(e, a, "showArea"), areaBase: b.getSeriesOption(e, a, "areaBase") }, n = "function" == typeof m.lineSmooth ? m.lineSmooth : m.lineSmooth ? b.Interpolation.monotoneCubic() : b.Interpolation.none(), o = n(k, l); if (m.showPoint && o.pathElements.forEach(function (c) { var h = i.elem("line", { x1: c.x, y1: c.y, x2: c.x + .01, y2: c.y }, a.classNames.point).attr({ "ct:value": [c.data.value.x, c.data.value.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(c.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: c.data.value, index: c.data.valueIndex, meta: c.data.meta, series: e, seriesIndex: g, axisX: d, axisY: f, group: i, element: h, x: c.x, y: c.y }) }.bind(this)), m.showLine) { var p = i.elem("path", { d: o.stringify() }, a.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: c.normalized.series[g], path: o.clone(), chartRect: j, index: g, series: e, seriesIndex: g, seriesMeta: e.meta, axisX: d, axisY: f, group: i, element: p }) } if (m.showArea && f.range) { var q = Math.max(Math.min(m.areaBase, f.range.max), f.range.min), r = j.y1 - f.projectValue(q); o.splitByCommand("M").filter(function (a) { return a.pathElements.length > 1 }).map(function (a) { var b = a.pathElements[0], c = a.pathElements[a.pathElements.length - 1]; return a.clone(!0).position(0).remove(1).move(b.x, r).line(b.x, b.y).position(a.pathElements.length + 1).line(c.x, r) }).forEach(function (b) { var h = i.elem("path", { d: b.stringify() }, a.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: c.normalized.series[g], path: b.clone(), series: e, seriesIndex: g, axisX: d, axisY: f, chartRect: j, index: g, group: i, element: h }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: f.bounds, chartRect: j, axisX: d, axisY: f, svg: this.svg, options: a }) } function d(a, c, d, f) { b.Line["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Line = b.Base.extend({ constructor: d, createChart: c }) }(this || global, a), function (a, b) {
+        "use strict"; function c(a) {
+            var c, d; a.distributeSeries ? (c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), c.normalized.series = c.normalized.series.map(function (a) { return [a] })) : c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart + (a.horizontalBars ? " " + a.classNames.horizontalBars : "")); var f = this.svg.elem("g").addClass(a.classNames.gridGroup), g = this.svg.elem("g"), h = this.svg.elem("g").addClass(a.classNames.labelGroup);
+            if (a.stackBars && 0 !== c.normalized.series.length) { var i = b.serialMap(c.normalized.series, function () { return Array.prototype.slice.call(arguments).map(function (a) { return a }).reduce(function (a, b) { return { x: a.x + (b && b.x) || 0, y: a.y + (b && b.y) || 0 } }, { x: 0, y: 0 }) }); d = b.getHighLow([i], a, a.horizontalBars ? "x" : "y") } else d = b.getHighLow(c.normalized.series, a, a.horizontalBars ? "x" : "y"); d.high = +a.high || (0 === a.high ? 0 : d.high), d.low = +a.low || (0 === a.low ? 0 : d.low); var j, k, l, m, n, o = b.createChartRect(this.svg, a, e.padding); k = a.distributeSeries && a.stackBars ? c.normalized.labels.slice(0, 1) : c.normalized.labels, a.horizontalBars ? (j = m = void 0 === a.axisX.type ? new b.AutoScaleAxis(b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })), l = n = void 0 === a.axisY.type ? new b.StepAxis(b.Axis.units.y, c.normalized.series, o, { ticks: k }) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, a.axisY)) : (l = m = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, o, { ticks: k }) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, a.axisX), j = n = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 }))); var p = a.horizontalBars ? o.x1 + j.projectValue(0) : o.y1 - j.projectValue(0), q = []; l.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), j.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(f, o, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (d, e) { var f, h, i = e - (c.raw.series.length - 1) / 2; f = a.distributeSeries && !a.stackBars ? l.axisLength / c.normalized.series.length / 2 : a.distributeSeries && a.stackBars ? l.axisLength / 2 : l.axisLength / c.normalized.series[e].length / 2, h = g.elem("g"), h.attr({ "ct:series-name": d.name, "ct:meta": b.serialize(d.meta) }), h.addClass([a.classNames.series, d.className || a.classNames.series + "-" + b.alphaNumerate(e)].join(" ")), c.normalized.series[e].forEach(function (g, k) { var r, s, t, u; if (u = a.distributeSeries && !a.stackBars ? e : a.distributeSeries && a.stackBars ? 0 : k, r = a.horizontalBars ? { x: o.x1 + j.projectValue(g && g.x ? g.x : 0, k, c.normalized.series[e]), y: o.y1 - l.projectValue(g && g.y ? g.y : 0, u, c.normalized.series[e]) } : { x: o.x1 + l.projectValue(g && g.x ? g.x : 0, u, c.normalized.series[e]), y: o.y1 - j.projectValue(g && g.y ? g.y : 0, k, c.normalized.series[e]) }, l instanceof b.StepAxis && (l.options.stretch || (r[l.units.pos] += f * (a.horizontalBars ? -1 : 1)), r[l.units.pos] += a.stackBars || a.distributeSeries ? 0 : i * a.seriesBarDistance * (a.horizontalBars ? -1 : 1)), t = q[k] || p, q[k] = t - (p - r[l.counterUnits.pos]), void 0 !== g) { var v = {}; v[l.units.pos + "1"] = r[l.units.pos], v[l.units.pos + "2"] = r[l.units.pos], !a.stackBars || "accumulate" !== a.stackMode && a.stackMode ? (v[l.counterUnits.pos + "1"] = p, v[l.counterUnits.pos + "2"] = r[l.counterUnits.pos]) : (v[l.counterUnits.pos + "1"] = t, v[l.counterUnits.pos + "2"] = q[k]), v.x1 = Math.min(Math.max(v.x1, o.x1), o.x2), v.x2 = Math.min(Math.max(v.x2, o.x1), o.x2), v.y1 = Math.min(Math.max(v.y1, o.y2), o.y1), v.y2 = Math.min(Math.max(v.y2, o.y2), o.y1); var w = b.getMetaData(d, k); s = h.elem("line", v, a.classNames.bar).attr({ "ct:value": [g.x, g.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(w) }), this.eventEmitter.emit("draw", b.extend({ type: "bar", value: g, index: k, meta: w, series: d, seriesIndex: e, axisX: m, axisY: n, chartRect: o, group: h, element: s }, v)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: j.bounds, chartRect: o, axisX: m, axisY: n, svg: this.svg, options: a })
+        } function d(a, c, d, f) { b.Bar["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Bar = b.Base.extend({ constructor: d, createChart: c })
+    }(this || global, a), function (a, b) { "use strict"; function c(a, b, c) { var d = b.x > a.x; return d && "explode" === c || !d && "implode" === c ? "start" : d && "implode" === c || !d && "explode" === c ? "end" : "middle" } function d(a) { var d, e, g, h, i, j = b.normalizeData(this.data), k = [], l = a.startAngle; this.svg = b.createSvg(this.container, a.width, a.height, a.donut ? a.classNames.chartDonut : a.classNames.chartPie), e = b.createChartRect(this.svg, a, f.padding), g = Math.min(e.width() / 2, e.height() / 2), i = a.total || j.normalized.series.reduce(function (a, b) { return a + b }, 0); var m = b.quantity(a.donutWidth); "%" === m.unit && (m.value *= g / 100), g -= a.donut && !a.donutSolid ? m.value / 2 : 0, h = "outside" === a.labelPosition || a.donut && !a.donutSolid ? g : "center" === a.labelPosition ? 0 : a.donutSolid ? g - m.value / 2 : g / 2, h += a.labelOffset; var n = { x: e.x1 + e.width() / 2, y: e.y2 + e.height() / 2 }, o = 1 === j.raw.series.filter(function (a) { return a.hasOwnProperty("value") ? 0 !== a.value : 0 !== a }).length; j.raw.series.forEach(function (a, b) { k[b] = this.svg.elem("g", null, null) }.bind(this)), a.showLabel && (d = this.svg.elem("g", null, null)), j.raw.series.forEach(function (e, f) { if (0 !== j.normalized.series[f] || !a.ignoreEmptyValues) { k[f].attr({ "ct:series-name": e.name }), k[f].addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(f)].join(" ")); var p = i > 0 ? l + j.normalized.series[f] / i * 360 : 0, q = Math.max(0, l - (0 === f || o ? 0 : .2)); p - q >= 359.99 && (p = q + 359.99); var r, s, t, u = b.polarToCartesian(n.x, n.y, g, q), v = b.polarToCartesian(n.x, n.y, g, p), w = new b.Svg.Path(!a.donut || a.donutSolid).move(v.x, v.y).arc(g, g, 0, p - l > 180, 0, u.x, u.y); a.donut ? a.donutSolid && (t = g - m.value, r = b.polarToCartesian(n.x, n.y, t, l - (0 === f || o ? 0 : .2)), s = b.polarToCartesian(n.x, n.y, t, p), w.line(r.x, r.y), w.arc(t, t, 0, p - l > 180, 1, s.x, s.y)) : w.line(n.x, n.y); var x = a.classNames.slicePie; a.donut && (x = a.classNames.sliceDonut, a.donutSolid && (x = a.classNames.sliceDonutSolid)); var y = k[f].elem("path", { d: w.stringify() }, x); if (y.attr({ "ct:value": j.normalized.series[f], "ct:meta": b.serialize(e.meta) }), a.donut && !a.donutSolid && (y._node.style.strokeWidth = m.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: j.normalized.series[f], totalDataSum: i, index: f, meta: e.meta, series: e, group: k[f], element: y, path: w.clone(), center: n, radius: g, startAngle: l, endAngle: p }), a.showLabel) { var z; z = 1 === j.raw.series.length ? { x: n.x, y: n.y } : b.polarToCartesian(n.x, n.y, h, l + (p - l) / 2); var A; A = j.normalized.labels && !b.isFalseyButZero(j.normalized.labels[f]) ? j.normalized.labels[f] : j.normalized.series[f]; var B = a.labelInterpolationFnc(A, f); if (B || 0 === B) { var C = d.elem("text", { dx: z.x, dy: z.y, "text-anchor": c(n, z, a.labelDirection) }, a.classNames.label).text("" + B); this.eventEmitter.emit("draw", { type: "label", index: f, group: d, element: C, text: "" + B, x: z.x, y: z.y }) } } l = p } }.bind(this)), this.eventEmitter.emit("created", { chartRect: e, svg: this.svg, options: a }) } function e(a, c, d, e) { b.Pie["super"].constructor.call(this, a, c, f, b.extend({}, f, d), e) } var f = (a.window, a.document, { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: b.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }); b.Pie = b.Base.extend({ constructor: e, createChart: d, determineAnchorPosition: c }) }(this || global, a), a
+});
+//# sourceMappingURL=chartist.min.js.map
+
+var i, l, selectedLine = null;
+
+/* Navigate to hash without browser history entry */
+var navigateToHash = function () {
+    if (window.history !== undefined && window.history.replaceState !== undefined) {
+        window.history.replaceState(undefined, undefined, this.getAttribute("href"));
+    }
+};
+
+var hashLinks = document.getElementsByClassName('navigatetohash');
+for (i = 0, l = hashLinks.length; i < l; i++) {
+    hashLinks[i].addEventListener('click', navigateToHash);
+}
+
+/* Switch test method */
+var switchTestMethod = function () {
+    var method = this.getAttribute("value");
+    console.log("Selected test method: " + method);
+
+    var lines, i, l, coverageData, lineAnalysis, cells;
+
+    lines = document.querySelectorAll('.lineAnalysis tr');
+
+    for (i = 1, l = lines.length; i < l; i++) {
+        coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"'));
+        lineAnalysis = coverageData[method];
+        cells = lines[i].querySelectorAll('td');
+        if (lineAnalysis === undefined) {
+            lineAnalysis = coverageData.AllTestMethods;
+            if (lineAnalysis.LVS !== 'gray') {
+                cells[0].setAttribute('class', 'red');
+                cells[1].innerText = cells[1].textContent = '0';
+                cells[4].setAttribute('class', 'lightred');
+            }
+        } else {
+            cells[0].setAttribute('class', lineAnalysis.LVS);
+            cells[1].innerText = cells[1].textContent = lineAnalysis.VC;
+            cells[4].setAttribute('class', 'light' + lineAnalysis.LVS);
+        }
+    }
+};
+
+var testMethods = document.getElementsByClassName('switchtestmethod');
+for (i = 0, l = testMethods.length; i < l; i++) {
+    testMethods[i].addEventListener('change', switchTestMethod);
+}
+
+/* Highlight test method by line */
+var toggleLine = function () {
+    if (selectedLine === this) {
+        selectedLine = null;
+    } else {
+        selectedLine = null;
+        unhighlightTestMethods();
+        highlightTestMethods.call(this);
+        selectedLine = this;
+    }
+    
+};
+var highlightTestMethods = function () {
+    if (selectedLine !== null) {
+        return;
+    }
+
+    var lineAnalysis;
+    var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"'));
+    var testMethods = document.getElementsByClassName('testmethod');
+
+    for (i = 0, l = testMethods.length; i < l; i++) {
+        lineAnalysis = coverageData[testMethods[i].id];
+        if (lineAnalysis === undefined) {
+            testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, "");
+        } else {
+            testMethods[i].className += ' light' + lineAnalysis.LVS;
+        }
+    }
+};
+var unhighlightTestMethods = function () {
+    if (selectedLine !== null) {
+        return;
+    }
+
+    var testMethods = document.getElementsByClassName('testmethod');
+    for (i = 0, l = testMethods.length; i < l; i++) {
+        testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, "");
+    }
+};
+var coverableLines = document.getElementsByClassName('coverableline');
+for (i = 0, l = coverableLines.length; i < l; i++) {
+    coverableLines[i].addEventListener('click', toggleLine);
+    coverableLines[i].addEventListener('mouseenter', highlightTestMethods);
+    coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods);
+}
+
+/* History charts */
+var renderChart = function (chart) {
+    // Remove current children (e.g. PNG placeholder)
+    while (chart.firstChild) {
+        chart.firstChild.remove();
+    }
+
+    var chartData = window[chart.getAttribute('data-data')];
+    var options = {
+        axisY: {
+            type: undefined,
+            onlyInteger: true
+        },
+        lineSmooth: false,
+        low: 0,
+        high: 100,
+        scaleMinSpace: 20,
+        onlyInteger: true,
+        fullWidth: true
+    };
+    var lineChart = new Chartist.Line(chart, {
+        labels: [],
+        series: chartData.series
+    }, options);
+
+    /* Zoom */
+    var zoomButtonDiv = document.createElement("div");
+    zoomButtonDiv.className = "toggleZoom";
+    var zoomButtonLink = document.createElement("a");
+    zoomButtonLink.setAttribute("href", "");
+    var zoomButtonText = document.createElement("i");
+    zoomButtonText.className = "icon-search-plus";
+
+    zoomButtonLink.appendChild(zoomButtonText);
+    zoomButtonDiv.appendChild(zoomButtonLink);
+
+    chart.appendChild(zoomButtonDiv);
+
+    zoomButtonDiv.addEventListener('click', function (event) {
+        event.preventDefault();
+
+        if (options.axisY.type === undefined) {
+            options.axisY.type = Chartist.AutoScaleAxis;
+            zoomButtonText.className = "icon-search-minus";
+        } else {
+            options.axisY.type = undefined;
+            zoomButtonText.className = "icon-search-plus";
+        }
+
+        lineChart.update(null, options);
+    });
+
+    var tooltip = document.createElement("div");
+    tooltip.className = "tooltip";
+
+    chart.appendChild(tooltip);
+
+    /* Tooltips */
+    var showToolTip = function () {
+        var index = this.getAttribute('ct:meta');
+
+        tooltip.innerHTML = chartData.tooltips[index];
+        tooltip.style.display = 'block';
+    };
+
+    var moveToolTip = function (event) {
+        var box = chart.getBoundingClientRect();
+        var left = event.pageX - box.left - window.pageXOffset;
+        var top = event.pageY - box.top - window.pageYOffset;
+
+        left = left + 20;
+        top = top - tooltip.offsetHeight / 2;
+
+        if (left + tooltip.offsetWidth > box.width) {
+            left -= tooltip.offsetWidth + 40;
+        }
+
+        if (top < 0) {
+            top = 0;
+        }
+
+        if (top + tooltip.offsetHeight > box.height) {
+            top = box.height - tooltip.offsetHeight;
+        }
+
+        tooltip.style.left = left + 'px';
+        tooltip.style.top = top + 'px';
+    };
+
+    var hideToolTip = function () {
+        tooltip.style.display = 'none';
+    };
+    chart.addEventListener('mousemove', moveToolTip);
+
+    lineChart.on('created', function () {
+        var chartPoints = chart.getElementsByClassName('ct-point');
+        for (i = 0, l = chartPoints.length; i < l; i++) {
+            chartPoints[i].addEventListener('mousemove', showToolTip);
+            chartPoints[i].addEventListener('mouseout', hideToolTip);
+        }
+    });
+};
+
+var charts = document.getElementsByClassName('historychart');
+for (i = 0, l = charts.length; i < l; i++) {
+    renderChart(charts[i]);
+}
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_cube.svg b/ld_client/doc/coverage/coveragereport/icon_cube.svg
new file mode 100644
index 0000000..3302443
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_cube.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M896 1629l640-349v-636l-640 233v752zm-64-865l698-254-698-254-698 254zm832-252v768q0 35-18 65t-49 47l-704 384q-28 16-61 16t-61-16l-704-384q-31-17-49-47t-18-65v-768q0-40 23-73t61-47l704-256q22-8 44-8t44 8l704 256q38 14 61 47t23 73z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg b/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg
new file mode 100644
index 0000000..3e7f0fa
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_cube_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M896 1629l640-349v-636l-640 233v752zm-64-865l698-254-698-254-698 254zm832-252v768q0 35-18 65t-49 47l-704 384q-28 16-61 16t-61-16l-704-384q-31-17-49-47t-18-65v-768q0-40 23-73t61-47l704-256q22-8 44-8t44 8l704 256q38 14 61 47t23 73z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg b/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg
new file mode 100644
index 0000000..d11cf04
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_down-dir_active.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg b/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg
new file mode 100644
index 0000000..fa34aeb
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_down-dir_active_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_fork.svg b/ld_client/doc/coverage/coveragereport/icon_fork.svg
new file mode 100644
index 0000000..f0148b3
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_fork.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><rect width="1792" height="1792" style="fill:#fff" /><path d="M672 1472q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm0-1152q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm640 128q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm96 0q0 52-26 96.5t-70 69.5q-2 287-226 414-67 38-203 81-128 40-169.5 71t-41.5 100v26q44 25 70 69.5t26 96.5q0 80-56 136t-136 56-136-56-56-136q0-52 26-96.5t70-69.5v-820q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136q0 52-26 96.5t-70 69.5v497q54-26 154-57 55-17 87.5-29.5t70.5-31 59-39.5 40.5-51 28-69.5 8.5-91.5q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg b/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg
new file mode 100644
index 0000000..11930c9
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_fork_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M672 1472q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm0-1152q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm640 128q0-40-28-68t-68-28-68 28-28 68 28 68 68 28 68-28 28-68zm96 0q0 52-26 96.5t-70 69.5q-2 287-226 414-67 38-203 81-128 40-169.5 71t-41.5 100v26q44 25 70 69.5t26 96.5q0 80-56 136t-136 56-136-56-56-136q0-52 26-96.5t70-69.5v-820q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136q0 52-26 96.5t-70 69.5v497q54-26 154-57 55-17 87.5-29.5t70.5-31 59-39.5 40.5-51 28-69.5 8.5-91.5q-44-25-70-69.5t-26-96.5q0-80 56-136t136-56 136 56 56 136z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_info-circled.svg b/ld_client/doc/coverage/coveragereport/icon_info-circled.svg
new file mode 100644
index 0000000..252166b
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_info-circled.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><circle cx="896" cy="896" r="750" fill="#fff" /><path fill="#28A5FF" d="M1152 1376v-160q0-14-9-23t-23-9h-96v-512q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23zm-128-896v-160q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23zm640 416q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg b/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg
new file mode 100644
index 0000000..252166b
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_info-circled_dark.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><circle cx="896" cy="896" r="750" fill="#fff" /><path fill="#28A5FF" d="M1152 1376v-160q0-14-9-23t-23-9h-96v-512q0-14-9-23t-23-9h-320q-14 0-23 9t-9 23v160q0 14 9 23t23 9h96v320h-96q-14 0-23 9t-9 23v160q0 14 9 23t23 9h448q14 0 23-9t9-23zm-128-896v-160q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v160q0 14 9 23t23 9h192q14 0 23-9t9-23zm640 416q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_minus.svg b/ld_client/doc/coverage/coveragereport/icon_minus.svg
new file mode 100644
index 0000000..3c30c36
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_minus.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1600 736v192q0 40-28 68t-68 28h-1216q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h1216q40 0 68 28t28 68z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg
new file mode 100644
index 0000000..2516b6f
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_minus_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1600 736v192q0 40-28 68t-68 28h-1216q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h1216q40 0 68 28t28 68z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_plus.svg b/ld_client/doc/coverage/coveragereport/icon_plus.svg
new file mode 100644
index 0000000..7932723
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_plus.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg
new file mode 100644
index 0000000..6ed4edd
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_plus_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_search-minus.svg b/ld_client/doc/coverage/coveragereport/icon_search-minus.svg
new file mode 100644
index 0000000..c174eb5
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_search-minus.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#6f6f6f" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-576q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h576q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg
new file mode 100644
index 0000000..9caaffb
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_search-minus_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-576q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h576q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_search-plus.svg b/ld_client/doc/coverage/coveragereport/icon_search-plus.svg
new file mode 100644
index 0000000..04b24ec
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_search-plus.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#6f6f6f" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-224v224q0 13-9.5 22.5t-22.5 9.5h-64q-13 0-22.5-9.5t-9.5-22.5v-224h-224q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h224v-224q0-13 9.5-22.5t22.5-9.5h64q13 0 22.5 9.5t9.5 22.5v224h224q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg b/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg
new file mode 100644
index 0000000..5324194
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_search-plus_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BFBFC0" d="M1088 800v64q0 13-9.5 22.5t-22.5 9.5h-224v224q0 13-9.5 22.5t-22.5 9.5h-64q-13 0-22.5-9.5t-9.5-22.5v-224h-224q-13 0-22.5-9.5t-9.5-22.5v-64q0-13 9.5-22.5t22.5-9.5h224v-224q0-13 9.5-22.5t22.5-9.5h64q13 0 22.5 9.5t9.5 22.5v224h224q13 0 22.5 9.5t9.5 22.5zm128 32q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 53-37.5 90.5t-90.5 37.5q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_sponsor.svg b/ld_client/doc/coverage/coveragereport/icon_sponsor.svg
new file mode 100644
index 0000000..bf6d959
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_sponsor.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M896 1664q-26 0-44-18l-624-602q-10-8-27.5-26t-55.5-65.5-68-97.5-53.5-121-23.5-138q0-220 127-344t351-124q62 0 126.5 21.5t120 58 95.5 68.5 76 68q36-36 76-68t95.5-68.5 120-58 126.5-21.5q224 0 351 124t127 344q0 221-229 450l-623 600q-18 18-44 18z" fill="#ea4aaa"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_star.svg b/ld_client/doc/coverage/coveragereport/icon_star.svg
new file mode 100644
index 0000000..b23c54e
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_star.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#000"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_star_dark.svg b/ld_client/doc/coverage/coveragereport/icon_star_dark.svg
new file mode 100644
index 0000000..49c0d03
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_star_dark.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M1728 647q0 22-26 48l-363 354 86 500q1 7 1 20 0 21-10.5 35.5t-30.5 14.5q-19 0-40-12l-449-236-449 236q-22 12-40 12-21 0-31.5-14.5t-10.5-35.5q0-6 2-20l86-500-364-354q-25-27-25-48 0-37 56-46l502-73 225-455q19-41 49-41t49 41l225 455 502 73q56 9 56 46z" fill="#fff"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_up-dir.svg b/ld_client/doc/coverage/coveragereport/icon_up-dir.svg
new file mode 100644
index 0000000..567c11f
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_up-dir.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg b/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg
new file mode 100644
index 0000000..bb22554
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_up-dir_active.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#c00" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_wrench.svg b/ld_client/doc/coverage/coveragereport/icon_wrench.svg
new file mode 100644
index 0000000..b6aa318
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_wrench.svg
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8"?>
+<svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path d="M448 1472q0-26-19-45t-45-19-45 19-19 45 19 45 45 19 45-19 19-45zm644-420l-682 682q-37 37-90 37-52 0-91-37l-106-108q-38-36-38-90 0-53 38-91l681-681q39 98 114.5 173.5t173.5 114.5zm634-435q0 39-23 106-47 134-164.5 217.5t-258.5 83.5q-185 0-316.5-131.5t-131.5-316.5 131.5-316.5 316.5-131.5q58 0 121.5 16.5t107.5 46.5q16 11 16 28t-16 28l-293 169v224l193 107q5-3 79-48.5t135.5-81 70.5-35.5q15 0 23.5 10t8.5 25z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg b/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg
new file mode 100644
index 0000000..5c77a9c
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/icon_wrench_dark.svg
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="utf-8"?><svg width="1792" height="1792" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"><path fill="#BDBDBF" d="M448 1472q0-26-19-45t-45-19-45 19-19 45 19 45 45 19 45-19 19-45zm644-420l-682 682q-37 37-90 37-52 0-91-37l-106-108q-38-36-38-90 0-53 38-91l681-681q39 98 114.5 173.5t173.5 114.5zm634-435q0 39-23 106-47 134-164.5 217.5t-258.5 83.5q-185 0-316.5-131.5t-131.5-316.5 131.5-316.5 316.5-131.5q58 0 121.5 16.5t107.5 46.5q16 11 16 28t-16 28l-293 169v224l193 107q5-3 79-48.5t135.5-81 70.5-35.5q15 0 23.5 10t8.5 25z"/></svg>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/index.htm b/ld_client/doc/coverage/coveragereport/index.htm
new file mode 100644
index 0000000..96bf9a8
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/index.htm
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>Summary - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1>Summary<a class="button" href="https://github.com/danielpalme/ReportGenerator" title="Star on GitHub"><i class="icon-star"></i>Star</a><a class="button" href="https://github.com/sponsors/danielpalme" title="Become a sponsor"><i class="icon-sponsor"></i>Sponsor</a></h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Parser:</th>
+<td class="limit-width " title="VisualStudio">VisualStudio</td>
+</tr>
+<tr>
+<th>Assemblies:</th>
+<td class="limit-width right" title="2">2</td>
+</tr>
+<tr>
+<th>Classes:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+<tr>
+<th>Files:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar20">79%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="583">583</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="150">150</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="733">733</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="1336">1336</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="583 of 733">79.5%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="Total">Total</td><td>1308</td><td>275</td></tr>
+</tbody>
+</table>
+</div>
+<risk-hotspots>
+</risk-hotspots>
+<h1>Coverage</h1>
+<coverage-info>
+<div class="table-responsive">
+<table class="overview table-fixed stripped">
+<colgroup>
+<col class="column-min-200" />
+<col class="column90" />
+<col class="column105" />
+<col class="column100" />
+<col class="column70" />
+<col class="column60" />
+<col class="column112" />
+</colgroup>
+<thead>
+<tr class="header"><th></th><th colspan="6" class="center">Line coverage</th></tr>
+<tr><th>Name</th><th class="right">Covered</th><th class="right">Uncovered</th><th class="right">Coverable</th><th class="right">Total</th><th class="center" colspan="2">Percentage</th></tr></thead>
+<tbody>
+<tr><th>ldclient.dll</th><th class="right">364</th><th class="right">150</th><th class="right">514</th><th class="right">854</th><th title="LineCoverage: 364/514" class="right">70.8%</th><th><table class="coverage"><tr><td class="green covered71">&nbsp;</td><td class="red covered29">&nbsp;</td></tr></table></th></tr>
+<tr><td><a href="ldclient.dll_DebuggerInfoParser.html">LDClient.detection.DebuggerInfoParser</a></td><td class="right">7</td><td class="right">0</td><td class="right">7</td><td class="right">21</td><td title="LineCoverage: 7/7" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_InfoFetcher.html">LDClient.detection.InfoFetcher</a></td><td class="right">52</td><td class="right">0</td><td class="right">52</td><td class="right">86</td><td title="LineCoverage: 52/52" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ProcessDetection.html">LDClient.detection.ProcessDetection</a></td><td class="right">62</td><td class="right">0</td><td class="right">62</td><td class="right">91</td><td title="LineCoverage: 62/62" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ProcessUtils.html">LDClient.detection.ProcessUtils</a></td><td class="right">0</td><td class="right">20</td><td class="right">20</td><td class="right">40</td><td title="LineCoverage: 0/20" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ApiClient.html">LDClient.network.ApiClient</a></td><td class="right">75</td><td class="right">0</td><td class="right">75</td><td class="right">108</td><td title="LineCoverage: 75/75" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_DebuggerInfo.html">LDClient.network.data.DebuggerInfo</a></td><td class="right">1</td><td class="right">0</td><td class="right">1</td><td class="right">9</td><td title="LineCoverage: 1/1" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_Payload.html">LDClient.network.data.Payload</a></td><td class="right">17</td><td class="right">3</td><td class="right">20</td><td class="right">49</td><td title="LineCoverage: 17/20" class="right">85%</td><td><table class="coverage"><tr><td class="green covered85">&nbsp;</td><td class="red covered15">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_HttpClient.html">LDClient.network.HttpClient</a></td><td class="right">4</td><td class="right">7</td><td class="right">11</td><td class="right">32</td><td title="LineCoverage: 4/11" class="right">36.3%</td><td><table class="coverage"><tr><td class="green covered36">&nbsp;</td><td class="red covered64">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_Program.html">LDClient.Program</a></td><td class="right">11</td><td class="right">32</td><td class="right">43</td><td class="right">67</td><td title="LineCoverage: 11/43" class="right">25.5%</td><td><table class="coverage"><tr><td class="green covered26">&nbsp;</td><td class="red covered74">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ConfigLoader.html">LDClient.utils.ConfigLoader</a></td><td class="right">74</td><td class="right">12</td><td class="right">86</td><td class="right">127</td><td title="LineCoverage: 74/86" class="right">86%</td><td><table class="coverage"><tr><td class="green covered86">&nbsp;</td><td class="red covered14">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_FileUtils.html">LDClient.utils.FileUtils</a></td><td class="right">0</td><td class="right">3</td><td class="right">3</td><td class="right">13</td><td title="LineCoverage: 0/3" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ALogger.html">LDClient.utils.loggers.ALogger</a></td><td class="right">58</td><td class="right">14</td><td class="right">72</td><td class="right">109</td><td title="LineCoverage: 58/72" class="right">80.5%</td><td><table class="coverage"><tr><td class="green covered80">&nbsp;</td><td class="red covered20">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ConsoleLogger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="right">3</td><td class="right">0</td><td class="right">3</td><td class="right">7</td><td title="LineCoverage: 3/3" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_FileLogger.html">LDClient.utils.loggers.FileLogger</a></td><td class="right">0</td><td class="right">59</td><td class="right">59</td><td class="right">95</td><td title="LineCoverage: 0/59" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><th>ldclienttests.dll</th><th class="right">219</th><th class="right">0</th><th class="right">219</th><th class="right">482</th><th title="LineCoverage: 219/219" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></th></tr>
+<tr><td><a href="ldclienttests.dll_DebuggerInfoParserTests.html">LDClientTests.detection.DebuggerInfoParserTests</a></td><td class="right">18</td><td class="right">0</td><td class="right">18</td><td class="right">66</td><td title="LineCoverage: 18/18" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_InfoFetcherTests.html">LDClientTests.detection.InfoFetcherTests</a></td><td class="right">59</td><td class="right">0</td><td class="right">59</td><td class="right">117</td><td title="LineCoverage: 59/59" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_ProcessDetectionTests.html">LDClientTests.detection.ProcessDetectionTests</a></td><td class="right">61</td><td class="right">0</td><td class="right">61</td><td class="right">132</td><td title="LineCoverage: 61/61" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_ApiClientTests.html">LDClientTests.network.ApiClientTests</a></td><td class="right">81</td><td class="right">0</td><td class="right">81</td><td class="right">167</td><td title="LineCoverage: 81/81" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+</tbody>
+</table>
+</div>
+</coverage-info>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'main.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/index.html b/ld_client/doc/coverage/coveragereport/index.html
new file mode 100644
index 0000000..96bf9a8
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/index.html
@@ -0,0 +1,197 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>Summary - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1>Summary<a class="button" href="https://github.com/danielpalme/ReportGenerator" title="Star on GitHub"><i class="icon-star"></i>Star</a><a class="button" href="https://github.com/sponsors/danielpalme" title="Become a sponsor"><i class="icon-sponsor"></i>Sponsor</a></h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Parser:</th>
+<td class="limit-width " title="VisualStudio">VisualStudio</td>
+</tr>
+<tr>
+<th>Assemblies:</th>
+<td class="limit-width right" title="2">2</td>
+</tr>
+<tr>
+<th>Classes:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+<tr>
+<th>Files:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar20">79%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="583">583</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="150">150</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="733">733</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="1336">1336</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="583 of 733">79.5%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="Total">Total</td><td>1308</td><td>275</td></tr>
+</tbody>
+</table>
+</div>
+<risk-hotspots>
+</risk-hotspots>
+<h1>Coverage</h1>
+<coverage-info>
+<div class="table-responsive">
+<table class="overview table-fixed stripped">
+<colgroup>
+<col class="column-min-200" />
+<col class="column90" />
+<col class="column105" />
+<col class="column100" />
+<col class="column70" />
+<col class="column60" />
+<col class="column112" />
+</colgroup>
+<thead>
+<tr class="header"><th></th><th colspan="6" class="center">Line coverage</th></tr>
+<tr><th>Name</th><th class="right">Covered</th><th class="right">Uncovered</th><th class="right">Coverable</th><th class="right">Total</th><th class="center" colspan="2">Percentage</th></tr></thead>
+<tbody>
+<tr><th>ldclient.dll</th><th class="right">364</th><th class="right">150</th><th class="right">514</th><th class="right">854</th><th title="LineCoverage: 364/514" class="right">70.8%</th><th><table class="coverage"><tr><td class="green covered71">&nbsp;</td><td class="red covered29">&nbsp;</td></tr></table></th></tr>
+<tr><td><a href="ldclient.dll_DebuggerInfoParser.html">LDClient.detection.DebuggerInfoParser</a></td><td class="right">7</td><td class="right">0</td><td class="right">7</td><td class="right">21</td><td title="LineCoverage: 7/7" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_InfoFetcher.html">LDClient.detection.InfoFetcher</a></td><td class="right">52</td><td class="right">0</td><td class="right">52</td><td class="right">86</td><td title="LineCoverage: 52/52" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ProcessDetection.html">LDClient.detection.ProcessDetection</a></td><td class="right">62</td><td class="right">0</td><td class="right">62</td><td class="right">91</td><td title="LineCoverage: 62/62" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ProcessUtils.html">LDClient.detection.ProcessUtils</a></td><td class="right">0</td><td class="right">20</td><td class="right">20</td><td class="right">40</td><td title="LineCoverage: 0/20" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ApiClient.html">LDClient.network.ApiClient</a></td><td class="right">75</td><td class="right">0</td><td class="right">75</td><td class="right">108</td><td title="LineCoverage: 75/75" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_DebuggerInfo.html">LDClient.network.data.DebuggerInfo</a></td><td class="right">1</td><td class="right">0</td><td class="right">1</td><td class="right">9</td><td title="LineCoverage: 1/1" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_Payload.html">LDClient.network.data.Payload</a></td><td class="right">17</td><td class="right">3</td><td class="right">20</td><td class="right">49</td><td title="LineCoverage: 17/20" class="right">85%</td><td><table class="coverage"><tr><td class="green covered85">&nbsp;</td><td class="red covered15">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_HttpClient.html">LDClient.network.HttpClient</a></td><td class="right">4</td><td class="right">7</td><td class="right">11</td><td class="right">32</td><td title="LineCoverage: 4/11" class="right">36.3%</td><td><table class="coverage"><tr><td class="green covered36">&nbsp;</td><td class="red covered64">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_Program.html">LDClient.Program</a></td><td class="right">11</td><td class="right">32</td><td class="right">43</td><td class="right">67</td><td title="LineCoverage: 11/43" class="right">25.5%</td><td><table class="coverage"><tr><td class="green covered26">&nbsp;</td><td class="red covered74">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ConfigLoader.html">LDClient.utils.ConfigLoader</a></td><td class="right">74</td><td class="right">12</td><td class="right">86</td><td class="right">127</td><td title="LineCoverage: 74/86" class="right">86%</td><td><table class="coverage"><tr><td class="green covered86">&nbsp;</td><td class="red covered14">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_FileUtils.html">LDClient.utils.FileUtils</a></td><td class="right">0</td><td class="right">3</td><td class="right">3</td><td class="right">13</td><td title="LineCoverage: 0/3" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ALogger.html">LDClient.utils.loggers.ALogger</a></td><td class="right">58</td><td class="right">14</td><td class="right">72</td><td class="right">109</td><td title="LineCoverage: 58/72" class="right">80.5%</td><td><table class="coverage"><tr><td class="green covered80">&nbsp;</td><td class="red covered20">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_ConsoleLogger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="right">3</td><td class="right">0</td><td class="right">3</td><td class="right">7</td><td title="LineCoverage: 3/3" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclient.dll_FileLogger.html">LDClient.utils.loggers.FileLogger</a></td><td class="right">0</td><td class="right">59</td><td class="right">59</td><td class="right">95</td><td title="LineCoverage: 0/59" class="right">0%</td><td><table class="coverage"><tr><td class="red covered100">&nbsp;</td></tr></table></td></tr>
+<tr><th>ldclienttests.dll</th><th class="right">219</th><th class="right">0</th><th class="right">219</th><th class="right">482</th><th title="LineCoverage: 219/219" class="right">100%</th><th><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></th></tr>
+<tr><td><a href="ldclienttests.dll_DebuggerInfoParserTests.html">LDClientTests.detection.DebuggerInfoParserTests</a></td><td class="right">18</td><td class="right">0</td><td class="right">18</td><td class="right">66</td><td title="LineCoverage: 18/18" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_InfoFetcherTests.html">LDClientTests.detection.InfoFetcherTests</a></td><td class="right">59</td><td class="right">0</td><td class="right">59</td><td class="right">117</td><td title="LineCoverage: 59/59" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_ProcessDetectionTests.html">LDClientTests.detection.ProcessDetectionTests</a></td><td class="right">61</td><td class="right">0</td><td class="right">61</td><td class="right">132</td><td title="LineCoverage: 61/61" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+<tr><td><a href="ldclienttests.dll_ApiClientTests.html">LDClientTests.network.ApiClientTests</a></td><td class="right">81</td><td class="right">0</td><td class="right">81</td><td class="right">167</td><td title="LineCoverage: 81/81" class="right">100%</td><td><table class="coverage"><tr><td class="green covered100">&nbsp;</td></tr></table></td></tr>
+</tbody>
+</table>
+</div>
+</coverage-info>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'main.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html
new file mode 100644
index 0000000..433ba04
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ALogger.html
@@ -0,0 +1,301 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.utils.loggers.ALogger - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.utils.loggers.ALogger">LDClient.utils.loggers.ALogger</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersALoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ALogger.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar20">80%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="58">58</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="14">14</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="72">72</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="109">109</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="58 of 72">80.5%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ALogger()"><a href="#file0_line10" class="navigatetohash">ALogger()</a></td><td>14</td><td>0</td></tr>
+<tr><td title="ALogger()"><a href="#file0_line16" class="navigatetohash">ALogger()</a></td><td>3</td><td>0</td></tr>
+<tr><td title="Info(string)"><a href="#file0_line38" class="navigatetohash">Info(...)</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Debug(string)"><a href="#file0_line42" class="navigatetohash">Debug(...)</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Error(string)"><a href="#file0_line46" class="navigatetohash">Error(...)</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Error(System.Exception)"><a href="#file0_line50" class="navigatetohash">Error(...)</a></td><td>0</td><td>5</td></tr>
+<tr><td title="ToString()"><a href="#file0_line56" class="navigatetohash">ToString()</a></td><td>0</td><td>10</td></tr>
+<tr><td title="Flush()"><a href="#file0_line60" class="navigatetohash">Flush()</a></td><td>0</td><td>2</td></tr>
+<tr><td title="Dispose()"><a href="#file0_line62" class="navigatetohash">Dispose()</a></td><td>0</td><td>3</td></tr>
+<tr><td title="ComposeLogRow(string, LDClient.utils.loggers.LogType)"><a href="#file0_line68" class="navigatetohash">ComposeLogRow(...)</a></td><td>12</td><td>0</td></tr>
+<tr><td title="UnwrapExceptionMessages(System.Exception)"><a href="#file0_line71" class="navigatetohash">UnwrapExceptionMessages(...)</a></td><td>0</td><td>12</td></tr>
+<tr><td title="ProcessQueue()"><a href="#file0_line74" class="navigatetohash">ProcessQueue()</a></td><td>21</td><td>2</td></tr>
+<tr><td title="Log(string, LDClient.utils.loggers.LogType)"><a href="#file0_line94" class="navigatetohash">Log(...)</a></td><td>13</td><td>1</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersALoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ALogger.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Globalization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.utils.loggers&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;abstract&nbsp;class&nbsp;ALogger&nbsp;:&nbsp;IDisposable&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;LogVerbosity&nbsp;_verbosity;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;LogFlow&nbsp;_logFlow;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;Queue&lt;Action&gt;&nbsp;_queue&nbsp;=&nbsp;new();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;ManualResetEvent&nbsp;_hasNewItems&nbsp;=&nbsp;new(false);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;ManualResetEvent&nbsp;_terminate&nbsp;=&nbsp;new(false);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;ManualResetEvent&nbsp;_waiting&nbsp;=&nbsp;new(false);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;Thread&nbsp;_loggingThread;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;readonly&nbsp;Lazy&lt;ALogger&gt;&nbsp;LazyLog&nbsp;=&nbsp;new(()</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=&gt;&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;switch&nbsp;(Program.Config.LogFlowType)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;LogFlow.File:</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;FileLogger();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;case&nbsp;LogFlow.Console:</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;default:</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;new&nbsp;ConsoleLogger();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;ALogger&nbsp;Current&nbsp;=&gt;&nbsp;LazyLog.Value;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;ALogger()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_verbosity&nbsp;=&nbsp;Program.Config.LogVerbosityType;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_logFlow&nbsp;=&nbsp;Program.Config.LogFlowType;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_loggingThread&nbsp;=&nbsp;new&nbsp;Thread(ProcessQueue)&nbsp;{&nbsp;IsBackground&nbsp;=&nbsp;true&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_loggingThread.Start();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Info(string&nbsp;message)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log(message,&nbsp;LogType.Info);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Debug(string&nbsp;message)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log(message,&nbsp;LogType.Debug);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Error(string&nbsp;message)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log(message,&nbsp;LogType.Error);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Error(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(_verbosity&nbsp;!=&nbsp;LogVerbosity.None)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Log(UnwrapExceptionMessages(e),&nbsp;LogType.Error);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;string&nbsp;ToString()&nbsp;=&gt;&nbsp;$&quot;Logger&nbsp;settings:&nbsp;[Type:&nbsp;{this.GetType().Name},&nbsp;Verbosity:&nbsp;{_verbosity},&nbsp;&quot;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;abstract&nbsp;void&nbsp;CreateLog(string&nbsp;message);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Flush()&nbsp;=&gt;&nbsp;_waiting.WaitOne();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Dispose()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_terminate.Set();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_loggingThread.Join();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;virtual&nbsp;string&nbsp;ComposeLogRow(string&nbsp;message,&nbsp;LogType&nbsp;logType)&nbsp;=&gt;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$&quot;[{DateTime.Now.ToString(&quot;yyyy-MM-dd&nbsp;HH:mm:ss,fff&quot;,&nbsp;CultureInfo.InvariantCulture)}&nbsp;-&nbsp;{logType}]&nbsp;-&nbsp;{message}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;virtual&nbsp;string&nbsp;UnwrapExceptionMessages(Exception?&nbsp;ex)&nbsp;=&gt;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ex&nbsp;==&nbsp;null&nbsp;?&nbsp;string.Empty&nbsp;:&nbsp;$&quot;{ex},&nbsp;Inner&nbsp;exception:&nbsp;{UnwrapExceptionMessages(ex.InnerException)}&nbsp;&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;ProcessQueue()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(true)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_waiting.Set();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;i&nbsp;=&nbsp;WaitHandle.WaitAny(new&nbsp;WaitHandle[]&nbsp;{&nbsp;_hasNewItems,&nbsp;_terminate&nbsp;});</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(i&nbsp;==&nbsp;1)&nbsp;return;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_hasNewItems.Reset();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_waiting.Reset();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queue&lt;Action&gt;&nbsp;queueCopy;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock&nbsp;(_queue)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;queueCopy&nbsp;=&nbsp;new&nbsp;Queue&lt;Action&gt;(_queue);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_queue.Clear();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;log&nbsp;in&nbsp;queueCopy)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;log();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;Log(string&nbsp;message,&nbsp;LogType&nbsp;logType)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(string.IsNullOrEmpty(message))</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;logRow&nbsp;=&nbsp;ComposeLogRow(message,&nbsp;logType);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Diagnostics.Debug.WriteLine(logRow);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(_verbosity&nbsp;==&nbsp;LogVerbosity.Full)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;lock&nbsp;(_queue)</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_queue.Enqueue(()&nbsp;=&gt;&nbsp;CreateLog(logRow));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_hasNewItems.Set();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line10" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ALogger()"><i class="icon-cube"></i>ALogger()</a><br />
+<a href="#file0_line16" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ALogger()"><i class="icon-cube"></i>ALogger()</a><br />
+<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Current()"><i class="icon-wrench"></i>Current()</a><br />
+<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Info(string)"><i class="icon-cube"></i>Info(string)</a><br />
+<a href="#file0_line42" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Debug(string)"><i class="icon-cube"></i>Debug(string)</a><br />
+<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Error(string)"><i class="icon-cube"></i>Error(string)</a><br />
+<a href="#file0_line50" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Error(System.Exception)"><i class="icon-cube"></i>Error(System.Exception)</a><br />
+<a href="#file0_line56" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ToString()"><i class="icon-cube"></i>ToString()</a><br />
+<a href="#file0_line60" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Flush()"><i class="icon-cube"></i>Flush()</a><br />
+<a href="#file0_line62" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Dispose()"><i class="icon-cube"></i>Dispose()</a><br />
+<a href="#file0_line68" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ComposeLogRow(string, LDClient.utils.loggers.LogType)"><i class="icon-cube"></i>ComposeLogRow(string, LDClient.utils.loggers.LogType)</a><br />
+<a href="#file0_line71" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - UnwrapExceptionMessages(System.Exception)"><i class="icon-cube"></i>UnwrapExceptionMessages(System.Exception)</a><br />
+<a href="#file0_line74" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 93.7% - ProcessQueue()"><i class="icon-cube"></i>ProcessQueue()</a><br />
+<a href="#file0_line94" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 90.9% - Log(string, LDClient.utils.loggers.LogType)"><i class="icon-cube"></i>Log(string, LDClient.utils.loggers.LogType)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html
new file mode 100644
index 0000000..31cd516
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ApiClient.html
@@ -0,0 +1,285 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.network.ApiClient - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.network.ApiClient">LDClient.network.ApiClient</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkApiClientcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\ApiClient.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="75">75</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="75">75</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="108">108</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="75 of 75">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)"><a href="#file0_line22" class="navigatetohash">ApiClient(...)</a></td><td>9</td><td>0</td></tr>
+<tr><td title="SendPayloadAsync()"><a href="#file0_line32" class="navigatetohash">SendPayloadAsync()</a></td><td>23</td><td>0</td></tr>
+<tr><td title="CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)"><a href="#file0_line48" class="navigatetohash">CreateRequestLog(...)</a></td><td>18</td><td>0</td></tr>
+<tr><td title="ResendPayloadsAsync()"><a href="#file0_line61" class="navigatetohash">ResendPayloadsAsync()</a></td><td>50</td><td>0</td></tr>
+<tr><td title="CachePayload(LDClient.network.data.Payload)"><a href="#file0_line87" class="navigatetohash">CachePayload(...)</a></td><td>20</td><td>0</td></tr>
+<tr><td title="Run()"><a href="#file0_line99" class="navigatetohash">Run()</a></td><td>10</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkApiClientcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\ApiClient.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Diagnostics;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Net.Http.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json.Serialization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;DiskQueue;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network.data;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.network&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;sealed&nbsp;class&nbsp;ApiClient&nbsp;:&nbsp;IApiClient&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;IHttpClient&nbsp;_client;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;bool&nbsp;ClientRunning;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_retryPeriod;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_maxEntries;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_maxRetries;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;IPersistentQueue&nbsp;_cache;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ApiClient(string&nbsp;url,&nbsp;uint&nbsp;port,&nbsp;string&nbsp;path,&nbsp;uint&nbsp;retryPeriod,&nbsp;uint&nbsp;maxEntries,&nbsp;uint&nbsp;maxRetries,&nbsp;IPersis</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;uri&nbsp;=&nbsp;$&quot;{url}:{port}{path}&quot;;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_retryPeriod&nbsp;=&nbsp;retryPeriod;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_maxEntries&nbsp;=&nbsp;maxEntries;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_maxRetries&nbsp;=&nbsp;maxRetries;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_client&nbsp;=&nbsp;new&nbsp;HttpClient(uri);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cache&nbsp;=&nbsp;cache;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;SendPayloadAsync(Payload&nbsp;payload)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stopwatch&nbsp;stopWatch&nbsp;=&nbsp;new();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopWatch.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;response&nbsp;=&nbsp;await&nbsp;_client.PostAsJsonAsync(payload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;stopWatch.Stop();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CreateRequestLog(payload,&nbsp;response,&nbsp;stopWatch.ElapsedMilliseconds);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;response.EnsureSuccessStatusCode();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Failed&nbsp;to&nbsp;send&nbsp;{payload}&nbsp;to&nbsp;the&nbsp;server.&nbsp;Due&nbsp;to:&nbsp;{e.Message}&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CachePayload(payload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;void&nbsp;CreateRequestLog(Payload&nbsp;payload,&nbsp;HttpResponseMessage&nbsp;response,&nbsp;long&nbsp;durationMs)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;responseToLog&nbsp;=&nbsp;new&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;statusCode&nbsp;=&nbsp;response.StatusCode,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;content&nbsp;=&nbsp;response.Content,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;headers&nbsp;=&nbsp;response.Headers,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;errorMessage&nbsp;=&nbsp;response.RequestMessage,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Request&nbsp;completed&nbsp;in&nbsp;{durationMs}&nbsp;ms,\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$&quot;Request&nbsp;body:&nbsp;{payload},\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$&quot;Response:&nbsp;{responseToLog}&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;async&nbsp;Task&nbsp;ResendPayloadsAsync()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;numberOfPayloadsToResend&nbsp;=&nbsp;Math.Min(_maxRetries,&nbsp;_cache.EstimatedCountOfItemsInQueue);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;payloads&nbsp;=&nbsp;new&nbsp;List&lt;Payload&gt;();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(numberOfPayloadsToResend&nbsp;&gt;&nbsp;0)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;var&nbsp;session&nbsp;=&nbsp;_cache.OpenSession();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;numberOfPayloadsToResend;&nbsp;i++)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;rawBytes&nbsp;=&nbsp;session.Dequeue();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;payload&nbsp;=&nbsp;JsonSerializer.Deserialize&lt;Payload&gt;(rawBytes);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(payload&nbsp;is&nbsp;not&nbsp;null)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;payloads.Add(payload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.Flush();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(payloads.Count&nbsp;&gt;&nbsp;0)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Debug($&quot;ResendPayloadAsync&nbsp;-&gt;&nbsp;{payloads.Count}&nbsp;unsent&nbsp;payloads&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;tasks&nbsp;=&nbsp;new&nbsp;List&lt;Task&gt;();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;payload&nbsp;in&nbsp;payloads)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Resending&nbsp;{payload}.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;tasks.Add(SendPayloadAsync(payload));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;Task.WhenAll(tasks);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;CachePayload(Payload&nbsp;payload)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Storing&nbsp;{payload}&nbsp;into&nbsp;the&nbsp;cache.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;numberOfCachedPayloads&nbsp;=&nbsp;_cache.EstimatedCountOfItemsInQueue;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;var&nbsp;session&nbsp;=&nbsp;_cache.OpenSession();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(numberOfCachedPayloads&nbsp;&gt;=&nbsp;_maxEntries)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.Dequeue();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;payloadJson&nbsp;=&nbsp;JsonSerializer.Serialize(payload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.Enqueue(Encoding.UTF8.GetBytes(payloadJson));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;session.Flush();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;void&nbsp;Run()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info(&quot;Api&nbsp;Client&nbsp;thread&nbsp;has&nbsp;started&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ClientRunning&nbsp;=&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(ClientRunning)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;ResendPayloadsAsync();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep((int)&nbsp;_retryPeriod);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)"><i class="icon-cube"></i>ApiClient(string, uint, string, uint, uint, uint, DiskQueue.IPersistentQueue)</a><br />
+<a href="#file0_line32" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync()"><i class="icon-cube"></i>SendPayloadAsync()</a><br />
+<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)"><i class="icon-cube"></i>CreateRequestLog(LDClient.network.data.Payload, System.Net.Http.HttpResponseMessage, long)</a><br />
+<a href="#file0_line61" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ResendPayloadsAsync()"><i class="icon-cube"></i>ResendPayloadsAsync()</a><br />
+<a href="#file0_line87" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CachePayload(LDClient.network.data.Payload)"><i class="icon-cube"></i>CachePayload(LDClient.network.data.Payload)</a><br />
+<a href="#file0_line99" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run()"><i class="icon-cube"></i>Run()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html
new file mode 100644
index 0000000..e7713f7
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConfigLoader.html
@@ -0,0 +1,346 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.utils.ConfigLoader - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.utils.ConfigLoader">LDClient.utils.ConfigLoader</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsConfigLoadercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\ConfigLoader.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar14">86%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="74">74</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="12">12</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="86">86</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="127">127</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="74 of 86">86%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ConfigLoader()"><a href="#file0_line21" class="navigatetohash">ConfigLoader()</a></td><td>10</td><td>0</td></tr>
+<tr><td title="ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line69" class="navigatetohash">ReadLoggerSection(...)</a></td><td>22</td><td>4</td></tr>
+<tr><td title="ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line84" class="navigatetohash">ReadApiSection(...)</a></td><td>11</td><td>4</td></tr>
+<tr><td title="ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line96" class="navigatetohash">ReadCacheSection(...)</a></td><td>15</td><td>4</td></tr>
+<tr><td title="ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><a href="#file0_line109" class="navigatetohash">ReadDebuggerSection(...)</a></td><td>33</td><td>3</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsConfigLoadercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\ConfigLoader.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils.loggers;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;Microsoft.Extensions.Configuration;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.utils&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;internal&nbsp;class&nbsp;ConfigLoader&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;int&nbsp;ErrorExitCode&nbsp;=&nbsp;1;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;ConfigFile&nbsp;=&nbsp;&quot;appsettings.json&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;LoggingSection&nbsp;=&nbsp;&quot;Logging&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;NetworkSection&nbsp;=&nbsp;&quot;Network&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;CacheSection&nbsp;=&nbsp;&quot;Cache&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;DdSection&nbsp;=&nbsp;&quot;DebuggerDetection&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Logger</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;LogChunkSize&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;LogChunkMaxCount&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;LogArchiveMaxCount&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;LogCleanupPeriod&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;LogVerbosity&nbsp;LogVerbosityType&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;LogVerbosity.Full;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;LogFlow&nbsp;LogFlowType&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;LogFlow.Console;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Api</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;ApiBaseAddress&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;ApiUsbEndPoint&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;ApiPort&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Cache</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;CacheFileName&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;MaxRetries&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;MaxEntries&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;RetryPeriod&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#region&nbsp;Detection</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;T32ProcessName&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;DetectionPeriod&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;T32InfoLocation&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;F32RemExecutable&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;FetchInfoMaxAttempts&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;uint&nbsp;FetchInfoAttemptPeriod&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string[]&nbsp;F32RemArguments&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}&nbsp;=&nbsp;null!;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;T32RemSuccessExitCode&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;int&nbsp;T32RemWaitTimeoutMs&nbsp;{&nbsp;get;&nbsp;private&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#endregion</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ConfigLoader()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;configuration&nbsp;=&nbsp;new&nbsp;ConfigurationBuilder()</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.AddJsonFile(ConfigFile)</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Build();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadLoggerSection(configuration);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadApiSection(configuration);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadCacheSection(configuration);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ReadDebuggerSection(configuration);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(&quot;Configuration&nbsp;successfully&nbsp;loaded!&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;ReadLoggerSection(IConfiguration&nbsp;configuration)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;logging&nbsp;=&nbsp;configuration.GetSection(LoggingSection);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogChunkSize&nbsp;=&nbsp;int.Parse(logging[&quot;LogChunkSize&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogChunkMaxCount&nbsp;=&nbsp;int.Parse(logging[&quot;LogChunkMaxCount&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogArchiveMaxCount&nbsp;=&nbsp;int.Parse(logging[&quot;LogArchiveMaxCount&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogCleanupPeriod&nbsp;=&nbsp;int.Parse(logging[&quot;LogCleanupPeriod&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogFlowType&nbsp;=&nbsp;(LogFlow)int.Parse(logging[&quot;LogFlowType&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LogVerbosityType&nbsp;=&nbsp;(LogVerbosity)int.Parse(logging[&quot;LogVerbosityType&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(e.Message);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Environment.Exit(ErrorExitCode);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;ReadApiSection(IConfiguration&nbsp;configuration)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;network&nbsp;=&nbsp;configuration.GetSection(NetworkSection);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApiBaseAddress&nbsp;=&nbsp;network[&quot;ApiBaseAddress&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApiUsbEndPoint&nbsp;=&nbsp;network[&quot;ApiLDEndPoint&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApiPort&nbsp;=&nbsp;uint.Parse(network[&quot;ApiPort&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(e.Message);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Environment.Exit(ErrorExitCode);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;ReadCacheSection(IConfiguration&nbsp;configuration)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;cache&nbsp;=&nbsp;configuration.GetSection(CacheSection);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;RetryPeriod&nbsp;=&nbsp;uint.Parse(cache[&quot;RetryPeriod&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxEntries&nbsp;=&nbsp;uint.Parse(cache[&quot;MaxEntries&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MaxRetries&nbsp;=&nbsp;uint.Parse(cache[&quot;MaxRetries&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CacheFileName&nbsp;=&nbsp;cache[&quot;CacheFileName&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(e.Message);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Environment.Exit(ErrorExitCode);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;ReadDebuggerSection(IConfiguration&nbsp;configuration)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;debugger&nbsp;=&nbsp;configuration.GetSection(DdSection);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T32ProcessName&nbsp;=&nbsp;debugger[&quot;T32ProcessName&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T32InfoLocation&nbsp;=&nbsp;debugger[&quot;T32InfoLocation&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DetectionPeriod&nbsp;=&nbsp;uint.Parse(debugger[&quot;DetectionPeriod&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F32RemExecutable&nbsp;=&nbsp;debugger[&quot;F32RemExecutable&quot;];</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FetchInfoMaxAttempts&nbsp;=&nbsp;uint.Parse(debugger[&quot;FetchInfoMaxAttempts&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FetchInfoAttemptPeriod&nbsp;=&nbsp;uint.Parse(debugger[&quot;FetchInfoAttemptPeriod&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T32RemSuccessExitCode&nbsp;=&nbsp;int.Parse(debugger[&quot;T32RemSuccessExitCode&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;T32RemWaitTimeoutMs&nbsp;=&nbsp;int.Parse(debugger[&quot;T32RemWaitTimeoutMs&quot;]);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;F32RemArguments&nbsp;=&nbsp;configuration.GetSection($&quot;{DdSection}:F32RemArguments&quot;).GetChildren().Select(key&nbsp;=&gt;&nbsp;k</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;e)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(e);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Environment.Exit(ErrorExitCode);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkSize()"><i class="icon-wrench"></i>LogChunkSize()</a><br />
+<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkSize(int)"><i class="icon-wrench"></i>LogChunkSize(int)</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkMaxCount()"><i class="icon-wrench"></i>LogChunkMaxCount()</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogChunkMaxCount(int)"><i class="icon-wrench"></i>LogChunkMaxCount(int)</a><br />
+<a href="#file0_line19" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogArchiveMaxCount()"><i class="icon-wrench"></i>LogArchiveMaxCount()</a><br />
+<a href="#file0_line19" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogArchiveMaxCount(int)"><i class="icon-wrench"></i>LogArchiveMaxCount(int)</a><br />
+<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogCleanupPeriod()"><i class="icon-wrench"></i>LogCleanupPeriod()</a><br />
+<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogCleanupPeriod(int)"><i class="icon-wrench"></i>LogCleanupPeriod(int)</a><br />
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogVerbosityType()"><i class="icon-wrench"></i>LogVerbosityType()</a><br />
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogVerbosityType(LDClient.utils.loggers.LogVerbosity)"><i class="icon-wrench"></i>LogVerbosityType(LDClient.utils.loggers.LogVerbosity)</a><br />
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ConfigLoader()"><i class="icon-cube"></i>ConfigLoader()</a><br />
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogFlowType()"><i class="icon-wrench"></i>LogFlowType()</a><br />
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - LogFlowType(LDClient.utils.loggers.LogFlow)"><i class="icon-wrench"></i>LogFlowType(LDClient.utils.loggers.LogFlow)</a><br />
+<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiBaseAddress()"><i class="icon-wrench"></i>ApiBaseAddress()</a><br />
+<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiBaseAddress(string)"><i class="icon-wrench"></i>ApiBaseAddress(string)</a><br />
+<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiUsbEndPoint()"><i class="icon-wrench"></i>ApiUsbEndPoint()</a><br />
+<a href="#file0_line29" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiUsbEndPoint(string)"><i class="icon-wrench"></i>ApiUsbEndPoint(string)</a><br />
+<a href="#file0_line30" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiPort()"><i class="icon-wrench"></i>ApiPort()</a><br />
+<a href="#file0_line30" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiPort(uint)"><i class="icon-wrench"></i>ApiPort(uint)</a><br />
+<a href="#file0_line36" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CacheFileName()"><i class="icon-wrench"></i>CacheFileName()</a><br />
+<a href="#file0_line36" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CacheFileName(string)"><i class="icon-wrench"></i>CacheFileName(string)</a><br />
+<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxRetries()"><i class="icon-wrench"></i>MaxRetries()</a><br />
+<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxRetries(uint)"><i class="icon-wrench"></i>MaxRetries(uint)</a><br />
+<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxEntries()"><i class="icon-wrench"></i>MaxEntries()</a><br />
+<a href="#file0_line38" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - MaxEntries(uint)"><i class="icon-wrench"></i>MaxEntries(uint)</a><br />
+<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetryPeriod()"><i class="icon-wrench"></i>RetryPeriod()</a><br />
+<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetryPeriod(uint)"><i class="icon-wrench"></i>RetryPeriod(uint)</a><br />
+<a href="#file0_line44" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32ProcessName()"><i class="icon-wrench"></i>T32ProcessName()</a><br />
+<a href="#file0_line44" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32ProcessName(string)"><i class="icon-wrench"></i>T32ProcessName(string)</a><br />
+<a href="#file0_line45" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectionPeriod()"><i class="icon-wrench"></i>DetectionPeriod()</a><br />
+<a href="#file0_line45" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectionPeriod(uint)"><i class="icon-wrench"></i>DetectionPeriod(uint)</a><br />
+<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32InfoLocation()"><i class="icon-wrench"></i>T32InfoLocation()</a><br />
+<a href="#file0_line46" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32InfoLocation(string)"><i class="icon-wrench"></i>T32InfoLocation(string)</a><br />
+<a href="#file0_line47" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemExecutable()"><i class="icon-wrench"></i>F32RemExecutable()</a><br />
+<a href="#file0_line47" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemExecutable(string)"><i class="icon-wrench"></i>F32RemExecutable(string)</a><br />
+<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoMaxAttempts()"><i class="icon-wrench"></i>FetchInfoMaxAttempts()</a><br />
+<a href="#file0_line48" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoMaxAttempts(uint)"><i class="icon-wrench"></i>FetchInfoMaxAttempts(uint)</a><br />
+<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoAttemptPeriod()"><i class="icon-wrench"></i>FetchInfoAttemptPeriod()</a><br />
+<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchInfoAttemptPeriod(uint)"><i class="icon-wrench"></i>FetchInfoAttemptPeriod(uint)</a><br />
+<a href="#file0_line50" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemArguments()"><i class="icon-wrench"></i>F32RemArguments()</a><br />
+<a href="#file0_line50" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - F32RemArguments(string[])"><i class="icon-wrench"></i>F32RemArguments(string[])</a><br />
+<a href="#file0_line51" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemSuccessExitCode()"><i class="icon-wrench"></i>T32RemSuccessExitCode()</a><br />
+<a href="#file0_line51" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemSuccessExitCode(int)"><i class="icon-wrench"></i>T32RemSuccessExitCode(int)</a><br />
+<a href="#file0_line52" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemWaitTimeoutMs()"><i class="icon-wrench"></i>T32RemWaitTimeoutMs()</a><br />
+<a href="#file0_line52" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - T32RemWaitTimeoutMs(int)"><i class="icon-wrench"></i>T32RemWaitTimeoutMs(int)</a><br />
+<a href="#file0_line69" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 78.5% - ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadLoggerSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br />
+<a href="#file0_line84" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 72.7% - ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadApiSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br />
+<a href="#file0_line96" class="navigatetohash percentagebar percentagebar70" title="Line coverage: 75% - ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadCacheSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br />
+<a href="#file0_line109" class="navigatetohash percentagebar percentagebar80" title="Line coverage: 82.3% - ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)"><i class="icon-cube"></i>ReadDebuggerSection(Microsoft.Extensions.Configuration.IConfiguration)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html
new file mode 100644
index 0000000..c41aaa5
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ConsoleLogger.html
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.utils.loggers.ConsoleLogger - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.utils.loggers.ConsoleLogger">LDClient.utils.loggers.ConsoleLogger</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersConsoleLoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ConsoleLogger.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="3">3</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="3">3</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="7">7</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="3 of 3">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="CreateLog(string)"><a href="#file0_line3" class="navigatetohash">CreateLog(...)</a></td><td>2</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersConsoleLoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\ConsoleLogger.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.utils.loggers&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;ConsoleLogger&nbsp;:&nbsp;ALogger&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;override&nbsp;void&nbsp;CreateLog(string&nbsp;message)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.WriteLine(message);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line3" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - CreateLog(string)"><i class="icon-cube"></i>CreateLog(string)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html
new file mode 100644
index 0000000..63eece6
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfo.html
@@ -0,0 +1,168 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.network.data.DebuggerInfo - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.network.data.DebuggerInfo">LDClient.network.data.DebuggerInfo</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataDebuggerInfocs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\DebuggerInfo.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="1">1</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="1">1</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="9">9</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="1 of 1">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataDebuggerInfocs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\DebuggerInfo.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json.Serialization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.network.data&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;DebuggerInfo&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;serial_number&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string?&nbsp;SerialNumber&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line7" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SerialNumber()"><i class="icon-wrench"></i>SerialNumber()</a><br />
+<a href="#file0_line7" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SerialNumber(string)"><i class="icon-wrench"></i>SerialNumber(string)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html
new file mode 100644
index 0000000..f4fd26d
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_DebuggerInfoParser.html
@@ -0,0 +1,190 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.detection.DebuggerInfoParser - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.detection.DebuggerInfoParser">LDClient.detection.DebuggerInfoParser</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionDebuggerInfoParsercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\DebuggerInfoParser.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="7">7</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="7">7</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="21">21</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="7 of 7">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="DebuggerInfoParser()"><a href="#file0_line9" class="navigatetohash">DebuggerInfoParser()</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Parse(string)"><a href="#file0_line11" class="navigatetohash">Parse(...)</a></td><td>22</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionDebuggerInfoParsercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\DebuggerInfoParser.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.RegularExpressions;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.detection&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;class&nbsp;DebuggerInfoParser&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;int&nbsp;ExpectedNumberOfMatches&nbsp;=&nbsp;2;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;readonly&nbsp;Regex&nbsp;SerialNumberRegex&nbsp;=&nbsp;new(&quot;(?&lt;=Serial&nbsp;Number:&nbsp;)(.*)&quot;);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;(string&nbsp;headSerialNumber,&nbsp;string&nbsp;bodySerialNumber)&nbsp;Parse(string&nbsp;dataTxt)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;matches&nbsp;=&nbsp;SerialNumberRegex.Matches(dataTxt);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(matches.Count&nbsp;!=&nbsp;ExpectedNumberOfMatches)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throw&nbsp;new&nbsp;ArgumentException($&quot;Expected&nbsp;{ExpectedNumberOfMatches}&nbsp;matches&nbsp;to&nbsp;be&nbsp;found&nbsp;in&nbsp;the&nbsp;text&nbsp;(actual</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;(matches[1].ToString().Trim(),&nbsp;matches[0].ToString().Trim());</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line9" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerInfoParser()"><i class="icon-cube"></i>DebuggerInfoParser()</a><br />
+<a href="#file0_line11" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse(string)"><i class="icon-cube"></i>Parse(string)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html
new file mode 100644
index 0000000..ba2bc04
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileLogger.html
@@ -0,0 +1,272 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.utils.loggers.FileLogger - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.utils.loggers.FileLogger">LDClient.utils.loggers.FileLogger</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersFileLoggercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\FileLogger.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar100">0%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="59">59</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="59">59</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="95">95</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="0 of 59">0%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="FileLogger()"><a href="#file0_line9" class="navigatetohash">FileLogger()</a></td><td>0</td><td>10</td></tr>
+<tr><td title="CreateLog(string)"><a href="#file0_line18" class="navigatetohash">CreateLog(...)</a></td><td>0</td><td>13</td></tr>
+<tr><td title="Rotate(string)"><a href="#file0_line36" class="navigatetohash">Rotate(...)</a></td><td>0</td><td>28</td></tr>
+<tr><td title="Archive(System.Collections.Generic.IEnumerable&lt;System.IO.FileSystemInfo&gt;, string, string, string)"><a href="#file0_line63" class="navigatetohash">Archive(...)</a></td><td>0</td><td>27</td></tr>
+<tr><td title="DeleteOldArchives(System.IO.FileSystemInfo[])"><a href="#file0_line76" class="navigatetohash">DeleteOldArchives(...)</a></td><td>0</td><td>26</td></tr>
+<tr><td title="ToString()"><a href="#file0_line94" class="navigatetohash">ToString()</a></td><td>0</td><td>14</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsloggersFileLoggercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\loggers\FileLogger.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.IO.Compression;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.utils.loggers;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>public&nbsp;class&nbsp;FileLogger&nbsp;:&nbsp;ALogger&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;LogFolderName&nbsp;=&nbsp;&quot;logs&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;LogFileName&nbsp;=&nbsp;&quot;app_info.log&quot;;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_logChunkSize&nbsp;=&nbsp;Program.Config.LogChunkSize;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_logChunkMaxCount&nbsp;=&nbsp;Program.Config.LogChunkMaxCount;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_logArchiveMaxCount&nbsp;=&nbsp;Program.Config.LogArchiveMaxCount;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_logCleanupPeriod&nbsp;=&nbsp;Program.Config.LogCleanupPeriod;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;LogFolderPath&nbsp;=&nbsp;$&quot;ldClient\\{LogFolderName}&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;bool&nbsp;_logDirExists;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;protected&nbsp;override&nbsp;void&nbsp;CreateLog(string&nbsp;message)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!_logDirExists)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_logDirExists&nbsp;=&nbsp;Directory.Exists(LogFolderPath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!_logDirExists)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Directory.CreateDirectory(LogFolderPath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_logDirExists&nbsp;=&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;logFilePath&nbsp;=&nbsp;Path.Combine(LogFolderPath,&nbsp;LogFileName);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Rotate(logFilePath);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using&nbsp;var&nbsp;sw&nbsp;=&nbsp;File.AppendText(logFilePath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sw.WriteLine(message);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;Rotate(string&nbsp;filePath)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!File.Exists(filePath))&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;fileInfo&nbsp;=&nbsp;new&nbsp;FileInfo(filePath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(fileInfo.Length&nbsp;&lt;&nbsp;_logChunkSize)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;fileTime&nbsp;=&nbsp;DateTime.Now.ToString(&quot;dd-MM-yyyy,hh-mm-ss,fff&quot;);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;rotatedPath&nbsp;=&nbsp;filePath.Replace(&quot;.log&quot;,&nbsp;$&quot;.{fileTime}&quot;);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.Move(filePath,&nbsp;rotatedPath);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;folderPath&nbsp;=&nbsp;Path.GetDirectoryName(rotatedPath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;logFolderContent&nbsp;=&nbsp;new&nbsp;DirectoryInfo(folderPath&nbsp;??&nbsp;string.Empty).GetFileSystemInfos();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;chunks&nbsp;=&nbsp;logFolderContent.Where(x&nbsp;=&gt;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;!x.Extension.Equals(&quot;.zip&quot;,&nbsp;StringComparison.OrdinalIgnoreCase));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(chunks.Count()&nbsp;&lt;=&nbsp;_logChunkMaxCount)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Archive(chunks,&nbsp;rotatedPath,&nbsp;fileTime,&nbsp;folderPath);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DeleteOldArchives(logFolderContent);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;Archive(IEnumerable&lt;FileSystemInfo&gt;&nbsp;chunks,&nbsp;string&nbsp;rotatedPath,&nbsp;string&nbsp;fileTime,&nbsp;string?&nbsp;folderPath)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;archiveFolderInfo&nbsp;=&nbsp;Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath)&nbsp;??&nbsp;LogFolderPa</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;chunk&nbsp;in&nbsp;chunks)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;destination&nbsp;=&nbsp;Path.Combine(archiveFolderInfo.FullName,&nbsp;chunk.Name);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Directory.Move(chunk.FullName,&nbsp;destination);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ZipFile.CreateFromDirectory(archiveFolderInfo.FullName,&nbsp;Path.Combine(folderPath&nbsp;??&nbsp;LogFolderPath,&nbsp;$&quot;{LogFolderNa</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Directory.Delete(archiveFolderInfo.FullName,&nbsp;true);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;DeleteOldArchives(FileSystemInfo[]&nbsp;logFolderContent)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;archives&nbsp;=&nbsp;logFolderContent.Where(x&nbsp;=&gt;&nbsp;x.Extension.Equals(&quot;.zip&quot;,&nbsp;StringComparison.OrdinalIgnoreCase)).ToArr</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(archives.Length&nbsp;&lt;=&nbsp;_logArchiveMaxCount)</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;oldestArchive&nbsp;=&nbsp;archives.OrderBy(x&nbsp;=&gt;&nbsp;x.CreationTime).First();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;cleanupDate&nbsp;=&nbsp;oldestArchive.CreationTime.AddDays(_logCleanupPeriod);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(DateTime.Compare(cleanupDate,&nbsp;DateTime.Now)&nbsp;&lt;=&nbsp;0)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;file&nbsp;in&nbsp;logFolderContent)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Delete();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.Delete(oldestArchive.FullName);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;string&nbsp;ToString()&nbsp;=&gt;&nbsp;$&quot;{base.ToString()},&nbsp;Chunk&nbsp;Size:&nbsp;{_logChunkSize},&nbsp;Max&nbsp;chunk&nbsp;count:&nbsp;{_logChunkMa</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line9" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - FileLogger()"><i class="icon-cube"></i>FileLogger()</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - CreateLog(string)"><i class="icon-cube"></i>CreateLog(string)</a><br />
+<a href="#file0_line36" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Rotate(string)"><i class="icon-cube"></i>Rotate(string)</a><br />
+<a href="#file0_line63" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Archive(System.Collections.Generic.IEnumerable&lt;System.IO.FileSystemInfo&gt;, string, string, string)"><i class="icon-cube"></i>Archive(System.Collections.Generic.IEnumerable&lt;System.IO.FileSystemInfo&gt;, string, string, string)</a><br />
+<a href="#file0_line76" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DeleteOldArchives(System.IO.FileSystemInfo[])"><i class="icon-cube"></i>DeleteOldArchives(System.IO.FileSystemInfo[])</a><br />
+<a href="#file0_line94" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ToString()"><i class="icon-cube"></i>ToString()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html
new file mode 100644
index 0000000..9eb1fd6
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_FileUtils.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFwklEQVR4AcWXA3Qk2RrH/7e6qtPbaQ6TdKyXsbm2bdv22N7R2raRs9JYyhszk0FvOkYnzfJLnTc3p3rv9GY9X+m7hfv/fagGwRG2PwywdetWUl5e7hNF0QeAv/LKK1f+4wDffPONIXiZqqpntG3DdV13tW3gOC5wt3XM22ElfAZHLPWEkD084cu62br+XH7WBv9fBvjhhx9KAExRFOXCNkHeEDWMHtsEA9fhvkWtaujaQxdgXCEgusAJ63gL/8Jgb//3F4/8SvxDAP6TT7ZEN268d2mfPjf7Hn20t9PphCF6OIAL5BsXRfXYtYa0Yf8/tI/AE/6gXbA/0nxSxSe/C8BfUJAmNzV9pEnSsQqAj08+GaeMGgVBEBgAAIEz41ctCpHItdBNsqZs0GOKJeWDDFvarRVDN4STAlTl5haoweAiXVGyqUjYYsFXV16Jc++914j41xCB4yMXLgpxiQDUp0N6RSDCJq/Vc2rNwO0NDEBDfn53tbl5bZt4DqU2RAy/ymbD2ocfxllXXcUADGk9c1HIEr42QYxymIDomCf8xiyb7/iKknWhdoDI8cdz8vbtP2qSdBIVNZ4xg2x3OlHzxBM49qSTzP0Q+E/o2G9UXrn1kAYT/eF6w8pZ34+X+K9qB4j5fDdp4fCremLkCdEa3pLu3eF86SX06t0bhmmaFsiLDiuFgDv0X9c+UZQph52znxfOqygl2qmnCurGjXtp3ak4BaHiFOjjkhIMfP11+Hw+YxzIjA0qhRV3UA26MyUhAYL6PCzbBtn69SV6Xt4FCAY/Z1JPN4CBevmYY3Deyy/D5XIF0uX+pbpA7oBxlRjX2VfRDGT23ZzzJKKnp78GUbzReLJ9A6jPQBnHOMfhpYsuwnULFwayLUNLZat6R3Ihtjmpn0KszxA9LW0bJKmXWZSFYM81CgLeuvHGwPgZX5cqNpXpAVaU9QXwZUYGQpBlBytqHrPXNKMU2Wl1j+4Q/ApRBptFk/sMQJDo2dkqJInrQJAZr4tGMeGVNKy5zmFMx4owIxaABy8TPSenCarq7TBy07ajTXzh/S58OTPNmMo8eQcwTAZaiF5UtB6yPDi5YCKYPxbDq6dY8MZHBdA4nU7MHH8T5tBcAoSNRO/ZcwEk6QFDoCOIBlHE+7lxvLCkN0Q7Z4qewaB7BolObfhWCM8SedCgY/lIZBkrmAgTliR8ITTj2VUD0JpupbLmErBHamZE084ZTz2L7L7lFi571aqDNiAzGYSkqvi+pQbP/zwQNf0drDiT7OQZaAdo1RqK1mRmEGO8s6BgZondPupw0WuahmWBSrz6Xm/sPbebWZwFoHu2+kwDSj+Hntl16rp7DQB8k5ubUczz5QUOhx2altAD6ysr8e6EHGx6sBB68sUsxpaDzkdgGCJlLQr5WOy5Y/Z/ywnl+iQzc9xwp3Oqz2ZrB9hVU4OPz3di+QuDaKx/MAPsWdEfQ8PzlQv8s3Y/lPCDpHTECEvzgQOLjvV6j8u12/FLYyO+KBTx4zcnQ+Vh2G9Ez+4B1osfjKD6hQNb236QjFg5aVGE+Un2Tu/enVrq6xf3stn6HrA047uyCyB6BCbNGjTzGbNHfaYIwbUNqPnA/4uDSz125/xNB5P+KH2lTx9vpLb2U9Uled6b2X+A7+RcpHhTOqp/UgSxPo7AJ/sR2tKyw53qOnvbvLIDHf4sf/+ii3hJCx41e3DwFSkqXdapZxd0G5YBZ4EHIDq0DtKv6zpC5S1oWFGNpg31Gk8sr3V1d3tw7cxl4T/8z2jgpBEnhVvDk6WIdIzVZYW7uBMcOU7YutphcfDgBA6arEEKiYjXxxD2h9C6qwlySNZ5C/+DwPOTdj29Zc1f/m846JERfSOxyGWqpp2qaWp/TdetSDAdhHAxjuM2coR87zzK+UHZvNV7/tY/p9Tue+UhoWzvxtyIGO0ajUcET6pbsQop1T2zSvwv3fWcgj9gBEfY/gcDB4tklLmGUgAAAABJRU5ErkJggg==" rel="icon" type="image/x-icon" />
+<title>LDClient.utils.FileUtils - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.utils.FileUtils">LDClient.utils.FileUtils</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsFileUtilscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\FileUtils.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar100">0%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="3">3</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="3">3</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="13">13</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="0 of 3">0%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ReadFileAllLines(string)"><a href="#file0_line9" class="navigatetohash">ReadFileAllLines(...)</a></td><td>0</td><td>3</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientutilsFileUtilscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\utils\FileUtils.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Collections.Generic;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Linq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.utils&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;FileUtils&nbsp;:&nbsp;IFileUtils&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string[]&nbsp;ReadFileAllLines(string&nbsp;file)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;File.ReadAllLines(file);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line9" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ReadFileAllLines(string)"><i class="icon-cube"></i>ReadFileAllLines(string)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html
new file mode 100644
index 0000000..d975c30
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_HttpClient.html
@@ -0,0 +1,201 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.network.HttpClient - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.network.HttpClient">LDClient.network.HttpClient</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkHttpClientcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\HttpClient.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar64">36%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="4">4</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="7">7</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="11">11</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="32">32</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="4 of 11">36.3%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="HttpClient(string)"><a href="#file0_line17" class="navigatetohash">HttpClient(...)</a></td><td>3</td><td>0</td></tr>
+<tr><td title="PostAsJsonAsync(LDClient.network.data.Payload)"><a href="#file0_line23" class="navigatetohash">PostAsJsonAsync(...)</a></td><td>0</td><td>8</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkHttpClientcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\HttpClient.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Collections.Generic;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Linq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Net.Http.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json.Serialization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network.data;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.network&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;HttpClient&nbsp;:&nbsp;IHttpClient{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;System.Net.Http.HttpClient&nbsp;_httpClient;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string&nbsp;_uri;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;HttpClient(string&nbsp;uri)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClient&nbsp;=&nbsp;new&nbsp;System.Net.Http.HttpClient();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_uri&nbsp;=&nbsp;uri;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;Task&lt;HttpResponseMessage&gt;&nbsp;PostAsJsonAsync(Payload&nbsp;payload)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;_httpClient.PostAsJsonAsync(_uri,&nbsp;payload,&nbsp;new&nbsp;JsonSerializerOptions&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Converters&nbsp;=&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;JsonStringEnumConverter(&nbsp;JsonNamingPolicy.CamelCase)</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HttpClient(string)"><i class="icon-cube"></i>HttpClient(string)</a><br />
+<a href="#file0_line23" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - PostAsJsonAsync(LDClient.network.data.Payload)"><i class="icon-cube"></i>PostAsJsonAsync(LDClient.network.data.Payload)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html
new file mode 100644
index 0000000..77c4c2a
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_InfoFetcher.html
@@ -0,0 +1,263 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAFwklEQVR4AcWXA3Qk2RrH/7e6qtPbaQ6TdKyXsbm2bdv22N7R2raRs9JYyhszk0FvOkYnzfJLnTc3p3rv9GY9X+m7hfv/fagGwRG2PwywdetWUl5e7hNF0QeAv/LKK1f+4wDffPONIXiZqqpntG3DdV13tW3gOC5wt3XM22ElfAZHLPWEkD084cu62br+XH7WBv9fBvjhhx9KAExRFOXCNkHeEDWMHtsEA9fhvkWtaujaQxdgXCEgusAJ63gL/8Jgb//3F4/8SvxDAP6TT7ZEN268d2mfPjf7Hn20t9PphCF6OIAL5BsXRfXYtYa0Yf8/tI/AE/6gXbA/0nxSxSe/C8BfUJAmNzV9pEnSsQqAj08+GaeMGgVBEBgAAIEz41ctCpHItdBNsqZs0GOKJeWDDFvarRVDN4STAlTl5haoweAiXVGyqUjYYsFXV16Jc++914j41xCB4yMXLgpxiQDUp0N6RSDCJq/Vc2rNwO0NDEBDfn53tbl5bZt4DqU2RAy/ymbD2ocfxllXXcUADGk9c1HIEr42QYxymIDomCf8xiyb7/iKknWhdoDI8cdz8vbtP2qSdBIVNZ4xg2x3OlHzxBM49qSTzP0Q+E/o2G9UXrn1kAYT/eF6w8pZ34+X+K9qB4j5fDdp4fCremLkCdEa3pLu3eF86SX06t0bhmmaFsiLDiuFgDv0X9c+UZQph52znxfOqygl2qmnCurGjXtp3ak4BaHiFOjjkhIMfP11+Hw+YxzIjA0qhRV3UA26MyUhAYL6PCzbBtn69SV6Xt4FCAY/Z1JPN4CBevmYY3Deyy/D5XIF0uX+pbpA7oBxlRjX2VfRDGT23ZzzJKKnp78GUbzReLJ9A6jPQBnHOMfhpYsuwnULFwayLUNLZat6R3Ihtjmpn0KszxA9LW0bJKmXWZSFYM81CgLeuvHGwPgZX5cqNpXpAVaU9QXwZUYGQpBlBytqHrPXNKMU2Wl1j+4Q/ApRBptFk/sMQJDo2dkqJInrQJAZr4tGMeGVNKy5zmFMx4owIxaABy8TPSenCarq7TBy07ajTXzh/S58OTPNmMo8eQcwTAZaiF5UtB6yPDi5YCKYPxbDq6dY8MZHBdA4nU7MHH8T5tBcAoSNRO/ZcwEk6QFDoCOIBlHE+7lxvLCkN0Q7Z4qewaB7BolObfhWCM8SedCgY/lIZBkrmAgTliR8ITTj2VUD0JpupbLmErBHamZE084ZTz2L7L7lFi571aqDNiAzGYSkqvi+pQbP/zwQNf0drDiT7OQZaAdo1RqK1mRmEGO8s6BgZondPupw0WuahmWBSrz6Xm/sPbebWZwFoHu2+kwDSj+Hntl16rp7DQB8k5ubUczz5QUOhx2altAD6ysr8e6EHGx6sBB68sUsxpaDzkdgGCJlLQr5WOy5Y/Z/ywnl+iQzc9xwp3Oqz2ZrB9hVU4OPz3di+QuDaKx/MAPsWdEfQ8PzlQv8s3Y/lPCDpHTECEvzgQOLjvV6j8u12/FLYyO+KBTx4zcnQ+Vh2G9Ez+4B1osfjKD6hQNb236QjFg5aVGE+Un2Tu/enVrq6xf3stn6HrA047uyCyB6BCbNGjTzGbNHfaYIwbUNqPnA/4uDSz125/xNB5P+KH2lTx9vpLb2U9Uled6b2X+A7+RcpHhTOqp/UgSxPo7AJ/sR2tKyw53qOnvbvLIDHf4sf/+ii3hJCx41e3DwFSkqXdapZxd0G5YBZ4EHIDq0DtKv6zpC5S1oWFGNpg31Gk8sr3V1d3tw7cxl4T/8z2jgpBEnhVvDk6WIdIzVZYW7uBMcOU7YutphcfDgBA6arEEKiYjXxxD2h9C6qwlySNZ5C/+DwPOTdj29Zc1f/m846JERfSOxyGWqpp2qaWp/TdetSDAdhHAxjuM2coR87zzK+UHZvNV7/tY/p9Tue+UhoWzvxtyIGO0ajUcET6pbsQop1T2zSvwv3fWcgj9gBEfY/gcDB4tklLmGUgAAAABJRU5ErkJggg==" rel="icon" type="image/x-icon" />
+<title>LDClient.detection.InfoFetcher - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.detection.InfoFetcher">LDClient.detection.InfoFetcher</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionInfoFetchercs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\InfoFetcher.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="52">52</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="52">52</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="86">86</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="52 of 52">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="InfoFetcher(uint, uint, string, string, string[], int, int)"><a href="#file0_line22" class="navigatetohash">InfoFetcher(...)</a></td><td>4</td><td>0</td></tr>
+<tr><td title="FetchDataAsync()"><a href="#file0_line40" class="navigatetohash">FetchDataAsync()</a></td><td>28</td><td>0</td></tr>
+<tr><td title="RetrieveDebuggerInfo(string)"><a href="#file0_line59" class="navigatetohash">RetrieveDebuggerInfo(...)</a></td><td>18</td><td>0</td></tr>
+<tr><td title="SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList&lt;string&gt;, int, int)"><a href="#file0_line73" class="navigatetohash">SendRetrieveInfoCommands(...)</a></td><td>17</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionInfoFetchercs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\InfoFetcher.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Diagnostics;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils.loggers;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.detection&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;InfoFetcher&nbsp;:&nbsp;IInfoFetcher&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;UndefinedSerialNumber&nbsp;=&nbsp;&quot;number&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string&nbsp;_f32RemExecutable;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string[]&nbsp;_f32RemArguments;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_f32SuccessExitCode;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;int&nbsp;_f32WaitTimeoutMs;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_maxAttempts;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_waitPeriodMs;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string&nbsp;_infoFilePath;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;IProcessUtils&nbsp;ProcessUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;IFileUtils&nbsp;FileUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;HeadSerialNumber&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}&nbsp;=&nbsp;UndefinedSerialNumber;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;BodySerialNumber&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}&nbsp;=&nbsp;UndefinedSerialNumber;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;InfoFetcher(uint&nbsp;maxAttempts,&nbsp;uint&nbsp;waitPeriodMs,&nbsp;string&nbsp;infoFilePath,&nbsp;string&nbsp;f32RemExecutable,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string[]&nbsp;f32RemArguments,&nbsp;int&nbsp;f32SuccessExitCode,&nbsp;int&nbsp;f32WaitTimeoutMs)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_maxAttempts&nbsp;=&nbsp;maxAttempts;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_waitPeriodMs&nbsp;=&nbsp;waitPeriodMs;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_infoFilePath&nbsp;=&nbsp;infoFilePath;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_f32RemExecutable&nbsp;=&nbsp;f32RemExecutable;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_f32RemArguments&nbsp;=&nbsp;f32RemArguments;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_f32SuccessExitCode&nbsp;=&nbsp;f32SuccessExitCode;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_f32WaitTimeoutMs&nbsp;=&nbsp;f32WaitTimeoutMs;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessUtils&nbsp;=&nbsp;new&nbsp;ProcessUtils();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileUtils&nbsp;=&nbsp;new&nbsp;FileUtils();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&lt;bool&gt;&nbsp;FetchDataAsync()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info(&quot;Fetching&nbsp;data&nbsp;from&nbsp;the&nbsp;debugger.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;success&nbsp;=&nbsp;SendRetrieveInfoCommands(_f32RemExecutable,&nbsp;_f32RemArguments,&nbsp;_f32SuccessExitCode,&nbsp;_f32WaitTim</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!success)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error(&quot;Failed&nbsp;to&nbsp;fetch&nbsp;data&nbsp;from&nbsp;the&nbsp;debugger.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for&nbsp;(var&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;_maxAttempts;&nbsp;i++)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;{i}.&nbsp;attempt&nbsp;to&nbsp;parse&nbsp;the&nbsp;info&nbsp;file.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(RetrieveDebuggerInfo(_infoFilePath))&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Info&nbsp;file&nbsp;has&nbsp;been&nbsp;parsed&nbsp;successfully.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;Task.Delay((int)_waitPeriodMs);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error(&quot;Failed&nbsp;to&nbsp;parse&nbsp;the&nbsp;into&nbsp;file.&nbsp;It&nbsp;may&nbsp;have&nbsp;not&nbsp;been&nbsp;created.&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;bool&nbsp;RetrieveDebuggerInfo(string&nbsp;filePath)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;fileContent&nbsp;=&nbsp;FileUtils.ReadFileAllLines(filePath).Aggregate(&quot;&quot;,&nbsp;(current,&nbsp;line)&nbsp;=&gt;&nbsp;$&quot;{current}{line</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;(headSerialNumber,&nbsp;bodySerialNumber)&nbsp;=&nbsp;DebuggerInfoParser.Parse(fileContent);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HeadSerialNumber&nbsp;=&nbsp;headSerialNumber;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BodySerialNumber&nbsp;=&nbsp;bodySerialNumber;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;File.Delete(filePath);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;exception)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Failed&nbsp;to&nbsp;retrieve&nbsp;debugger&nbsp;info.&nbsp;File&nbsp;{filePath}&nbsp;may&nbsp;not&nbsp;exist&nbsp;or&nbsp;it&nbsp;does</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;bool&nbsp;SendRetrieveInfoCommands(string&nbsp;executableFile,&nbsp;IReadOnlyList&lt;string&gt;?&nbsp;arguments,&nbsp;int&nbsp;desiredExitCo</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(arguments&nbsp;==&nbsp;null)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Failed&nbsp;to&nbsp;run&nbsp;{executableFile}&nbsp;-&nbsp;no&nbsp;parameters&nbsp;were&nbsp;given&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach&nbsp;(var&nbsp;argument&nbsp;in&nbsp;arguments)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!ProcessUtils.ExecuteNewProcess(executableFile,&nbsp;argument,&nbsp;waitTimeoutMs,&nbsp;desiredExitCode))&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadSerialNumber()"><i class="icon-wrench"></i>HeadSerialNumber()</a><br />
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadSerialNumber(string)"><i class="icon-wrench"></i>HeadSerialNumber(string)</a><br />
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - InfoFetcher(uint, uint, string, string, string[], int, int)"><i class="icon-cube"></i>InfoFetcher(uint, uint, string, string, string[], int, int)</a><br />
+<a href="#file0_line23" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodySerialNumber()"><i class="icon-wrench"></i>BodySerialNumber()</a><br />
+<a href="#file0_line23" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodySerialNumber(string)"><i class="icon-wrench"></i>BodySerialNumber(string)</a><br />
+<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync()"><i class="icon-cube"></i>FetchDataAsync()</a><br />
+<a href="#file0_line59" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetrieveDebuggerInfo(string)"><i class="icon-cube"></i>RetrieveDebuggerInfo(string)</a><br />
+<a href="#file0_line73" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList&lt;string&gt;, int, int)"><i class="icon-cube"></i>SendRetrieveInfoCommands(string, System.Collections.Generic.IReadOnlyList&lt;string&gt;, int, int)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html
new file mode 100644
index 0000000..9c252eb
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_Payload.html
@@ -0,0 +1,232 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.network.data.Payload - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.network.data.Payload">LDClient.network.data.Payload</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataPayloadcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\Payload.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar15">85%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="17">17</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="3">3</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="20">20</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="49">49</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="17 of 20">85%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ToString()"><a href="#file0_line31" class="navigatetohash">ToString()</a></td><td>3</td><td>0</td></tr>
+<tr><td title="ParseToJson()"><a href="#file0_line35" class="navigatetohash">ParseToJson()</a></td><td>0</td><td>3</td></tr>
+<tr><td title="ParseToJson(LDClient.network.data.Payload)"><a href="#file0_line39" class="navigatetohash">ParseToJson(...)</a></td><td>8</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientnetworkdataPayloadcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\network\data\Payload.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json.Serialization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;Newtonsoft.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;JsonSerializer&nbsp;=&nbsp;System.Text.Json.JsonSerializer;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.network.data&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[JsonObject(MemberSerialization.OptIn)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;Payload&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;username&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string?&nbsp;UserName&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;hostname&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string?&nbsp;HostName&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;timestamp&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string?&nbsp;TimeStamp&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;head_device&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;DebuggerInfo?&nbsp;HeadDevice&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;body_device&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;DebuggerInfo?&nbsp;&nbsp;BodyDevice&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[JsonPropertyName(&quot;status&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ConnectionStatus&nbsp;Status&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;override&nbsp;string&nbsp;ToString()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ParseToJson(this);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;string&nbsp;ParseToJson()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Payload.ParseToJson(this);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;string&nbsp;ParseToJson(Payload&nbsp;payload)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;options&nbsp;=&nbsp;new&nbsp;JsonSerializerOptions&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Converters&nbsp;=&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;JsonStringEnumConverter(JsonNamingPolicy.CamelCase)</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;JsonSerializer.Serialize(payload,&nbsp;options);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line12" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - UserName()"><i class="icon-wrench"></i>UserName()</a><br />
+<a href="#file0_line12" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - UserName(string)"><i class="icon-wrench"></i>UserName(string)</a><br />
+<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HostName()"><i class="icon-wrench"></i>HostName()</a><br />
+<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HostName(string)"><i class="icon-wrench"></i>HostName(string)</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - TimeStamp()"><i class="icon-wrench"></i>TimeStamp()</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - TimeStamp(string)"><i class="icon-wrench"></i>TimeStamp(string)</a><br />
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadDevice()"><i class="icon-wrench"></i>HeadDevice()</a><br />
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - HeadDevice(LDClient.network.data.DebuggerInfo)"><i class="icon-wrench"></i>HeadDevice(LDClient.network.data.DebuggerInfo)</a><br />
+<a href="#file0_line25" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodyDevice()"><i class="icon-wrench"></i>BodyDevice()</a><br />
+<a href="#file0_line25" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - BodyDevice(LDClient.network.data.DebuggerInfo)"><i class="icon-wrench"></i>BodyDevice(LDClient.network.data.DebuggerInfo)</a><br />
+<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Status()"><i class="icon-wrench"></i>Status()</a><br />
+<a href="#file0_line28" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Status(LDClient.network.data.ConnectionStatus)"><i class="icon-wrench"></i>Status(LDClient.network.data.ConnectionStatus)</a><br />
+<a href="#file0_line31" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ToString()"><i class="icon-cube"></i>ToString()</a><br />
+<a href="#file0_line35" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ParseToJson()"><i class="icon-cube"></i>ParseToJson()</a><br />
+<a href="#file0_line39" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ParseToJson(LDClient.network.data.Payload)"><i class="icon-cube"></i>ParseToJson(LDClient.network.data.Payload)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html
new file mode 100644
index 0000000..367b986
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessDetection.html
@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.detection.ProcessDetection - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.detection.ProcessDetection">LDClient.detection.ProcessDetection</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessDetectioncs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessDetection.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="62">62</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="62">62</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="91">91</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="62 of 62">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)"><a href="#file0_line21" class="navigatetohash">ProcessDetection(...)</a></td><td>2</td><td>0</td></tr>
+<tr><td title="RetrieveDataFromDebugger()"><a href="#file0_line32" class="navigatetohash">RetrieveDataFromDebugger()</a></td><td>12</td><td>0</td></tr>
+<tr><td title="DebuggerDisconnected()"><a href="#file0_line40" class="navigatetohash">DebuggerDisconnected()</a></td><td>10</td><td>0</td></tr>
+<tr><td title="DetectProcessAsync()"><a href="#file0_line49" class="navigatetohash">DetectProcessAsync()</a></td><td>27</td><td>0</td></tr>
+<tr><td title="SendDataToServerAsync()"><a href="#file0_line65" class="navigatetohash">SendDataToServerAsync()</a></td><td>20</td><td>0</td></tr>
+<tr><td title="RunPeriodicDetection()"><a href="#file0_line82" class="navigatetohash">RunPeriodicDetection()</a></td><td>10</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessDetectioncs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessDetection.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Diagnostics;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network.data;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.detection&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;public&nbsp;sealed&nbsp;class&nbsp;ProcessDetection&nbsp;:&nbsp;IProcessDetection&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;string&nbsp;DatetimeFormat&nbsp;=&nbsp;&quot;yyyy-MM-dd&nbsp;hh:mm:ss&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string&nbsp;_processName;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;uint&nbsp;_detectionPeriodMs;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;IInfoFetcher&nbsp;_infoFetcher;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;IApiClient&nbsp;_apiClient;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;IProcessUtils&nbsp;_processUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;bool&nbsp;_processIsActive;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;bool&nbsp;_failedToRetrieveData;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Payload?&nbsp;_lastConnectedPayload;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;bool&nbsp;DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;ProcessDetection(string&nbsp;processName,&nbsp;uint&nbsp;detectionPeriodMs,&nbsp;IInfoFetcher&nbsp;infoFetcher,&nbsp;IApiClient&nbsp;apiClie</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processName&nbsp;=&nbsp;processName;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_detectionPeriodMs&nbsp;=&nbsp;detectionPeriodMs;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_infoFetcher&nbsp;=&nbsp;infoFetcher;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_apiClient&nbsp;=&nbsp;apiClient;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_failedToRetrieveData&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processUtils&nbsp;=&nbsp;processUtils;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;async&nbsp;Task&lt;bool&gt;&nbsp;RetrieveDataFromDebugger()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;success&nbsp;=&nbsp;await&nbsp;_infoFetcher.FetchDataAsync();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(success)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_lastConnectedPayload&nbsp;=&nbsp;await&nbsp;SendDataToServerAsync(_infoFetcher.HeadSerialNumber,&nbsp;_infoFetcher.BodySeri</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;success;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;async&nbsp;Task&nbsp;DebuggerDisconnected()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(_lastConnectedPayload&nbsp;is&nbsp;not&nbsp;null)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_lastConnectedPayload.Status&nbsp;=&nbsp;ConnectionStatus.Disconnected;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_lastConnectedPayload.TimeStamp&nbsp;=&nbsp;DateTime.Now.ToString(DatetimeFormat);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;_apiClient.SendPayloadAsync(_lastConnectedPayload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_lastConnectedPayload&nbsp;=&nbsp;null;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;async&nbsp;Task&nbsp;DetectProcessAsync()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;processExists&nbsp;=&nbsp;_processUtils.IsProcessRunning(_processName);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(processExists&nbsp;&amp;&amp;&nbsp;!_processIsActive)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Process&nbsp;started:&nbsp;{_processName}&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!_failedToRetrieveData)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_failedToRetrieveData&nbsp;=&nbsp;!await&nbsp;RetrieveDataFromDebugger();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;if&nbsp;(!processExists&nbsp;&amp;&amp;&nbsp;_processIsActive)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info($&quot;Process&nbsp;stopped:&nbsp;{_processName}&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_failedToRetrieveData&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;DebuggerDisconnected();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processIsActive&nbsp;=&nbsp;processExists;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;async&nbsp;Task&lt;Payload&gt;&nbsp;SendDataToServerAsync(string&nbsp;headSerialNumber,&nbsp;string&nbsp;bodySerialNumber,&nbsp;string&nbsp;datet</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Payload&nbsp;payload&nbsp;=&nbsp;new()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserName&nbsp;=&nbsp;Environment.UserName,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HostName&nbsp;=&nbsp;Environment.MachineName,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeStamp&nbsp;=&nbsp;DateTime.Now.ToString(datetimeFormat),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HeadDevice&nbsp;=&nbsp;new&nbsp;DebuggerInfo&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SerialNumber&nbsp;=&nbsp;headSerialNumber</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BodyDevice&nbsp;=&nbsp;new&nbsp;DebuggerInfo&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SerialNumber&nbsp;=&nbsp;bodySerialNumber</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status&nbsp;=&nbsp;ConnectionStatus.Connected</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;_apiClient.SendPayloadAsync(payload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;payload;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;void&nbsp;RunPeriodicDetection()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Info(&quot;Process&nbsp;periodic&nbsp;detector&nbsp;has&nbsp;started&quot;);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DetectionRunning&nbsp;=&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(DetectionRunning)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;DetectProcessAsync();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep((int)_detectionPeriodMs);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line21" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)"><i class="icon-cube"></i>ProcessDetection(string, uint, LDClient.detection.IInfoFetcher, LDClient.network.IApiClient, LDClient.detection.IProcessUtils)</a><br />
+<a href="#file0_line32" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RetrieveDataFromDebugger()"><i class="icon-cube"></i>RetrieveDataFromDebugger()</a><br />
+<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerDisconnected()"><i class="icon-cube"></i>DebuggerDisconnected()</a><br />
+<a href="#file0_line49" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DetectProcessAsync()"><i class="icon-cube"></i>DetectProcessAsync()</a><br />
+<a href="#file0_line65" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendDataToServerAsync()"><i class="icon-cube"></i>SendDataToServerAsync()</a><br />
+<a href="#file0_line82" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection()"><i class="icon-cube"></i>RunPeriodicDetection()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html
new file mode 100644
index 0000000..d90cd9e
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_ProcessUtils.html
@@ -0,0 +1,209 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.detection.ProcessUtils - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.detection.ProcessUtils">LDClient.detection.ProcessUtils</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessUtilscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessUtils.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar100">0%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="20">20</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="20">20</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="40">40</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="0 of 20">0%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="IsProcessRunning(string)"><a href="#file0_line11" class="navigatetohash">IsProcessRunning(...)</a></td><td>0</td><td>3</td></tr>
+<tr><td title="ExecuteNewProcess(string, string, int, int)"><a href="#file0_line16" class="navigatetohash">ExecuteNewProcess(...)</a></td><td>0</td><td>42</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientdetectionProcessUtilscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\detection\ProcessUtils.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Collections.Generic;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Diagnostics;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Linq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient.detection&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;class&nbsp;ProcessUtils&nbsp;:&nbsp;IProcessUtils{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;bool&nbsp;IsProcessRunning(string&nbsp;name)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;Process.GetProcessesByName(name).Length&nbsp;&gt;&nbsp;0;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;bool&nbsp;ExecuteNewProcess(string&nbsp;fileName,&nbsp;string&nbsp;argument,&nbsp;int&nbsp;timeout,&nbsp;int&nbsp;desiredExitCode)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;t32RemProcess&nbsp;=&nbsp;new&nbsp;Process();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t32RemProcess.StartInfo.FileName&nbsp;=&nbsp;fileName;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t32RemProcess.StartInfo.Arguments&nbsp;=&nbsp;argument;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;t32RemProcess.Start();</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(!t32RemProcess.WaitForExit(timeout))&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Execution&nbsp;has&nbsp;not&nbsp;terminated&nbsp;within&nbsp;a&nbsp;predefined&nbsp;timeout&nbsp;of&nbsp;{timeout}&nbsp;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(t32RemProcess.ExitCode&nbsp;!=&nbsp;desiredExitCode)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Execution&nbsp;terminated&nbsp;with&nbsp;an&nbsp;error&nbsp;code&nbsp;of&nbsp;{t32RemProcess.ExitCode}&quot;);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;catch&nbsp;(Exception&nbsp;exception)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Program.DefaultLogger.Error($&quot;Failed&nbsp;to&nbsp;run&nbsp;{fileName}&nbsp;{argument}.&nbsp;{exception.Message}&quot;);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;true;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line11" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - IsProcessRunning(string)"><i class="icon-cube"></i>IsProcessRunning(string)</a><br />
+<a href="#file0_line16" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - ExecuteNewProcess(string, string, int, int)"><i class="icon-cube"></i>ExecuteNewProcess(string, string, int, int)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html b/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html
new file mode 100644
index 0000000..96ce423
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclient.dll_Program.html
@@ -0,0 +1,240 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClient.Program - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClient.Program">LDClient.Program</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclient.dll">ldclient.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientProgramcs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\Program.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar74">25%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="11">11</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="32">32</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="43">43</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="67">67</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="11 of 43">25.5%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="Program()"><a href="#file0_line16" class="navigatetohash">Program()</a></td><td>18</td><td>0</td></tr>
+<tr><td title="Main()"><a href="#file0_line30" class="navigatetohash">Main()</a></td><td>0</td><td>48</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientProgramcs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClient\Program.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;DiskQueue;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils.loggers;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using&nbsp;static&nbsp;System.Diagnostics.Process;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using&nbsp;static&nbsp;System.Reflection.Assembly;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClient;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>internal&nbsp;static&nbsp;class&nbsp;Program&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;int&nbsp;MainLoopDelayMs&nbsp;=&nbsp;30000;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;ConfigLoader&nbsp;Config&nbsp;{&nbsp;get;&nbsp;}&nbsp;=&nbsp;new();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;ALogger&nbsp;DefaultLogger&nbsp;{&nbsp;get;&nbsp;}&nbsp;=&nbsp;ALogger.Current;</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;IApiClient?&nbsp;DefaultApiClient&nbsp;{&nbsp;get;&nbsp;set;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;static&nbsp;readonly&nbsp;InfoFetcher&nbsp;InfoFetcher&nbsp;=&nbsp;new(</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.FetchInfoMaxAttempts,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.FetchInfoAttemptPeriod,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.T32InfoLocation,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.F32RemExecutable,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.F32RemArguments,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.T32RemSuccessExitCode,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.T32RemWaitTimeoutMs</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;int&nbsp;Main()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length&nbsp;&gt;&nbsp;1)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultLogger.Error(&quot;Another&nbsp;instance&nbsp;of&nbsp;the&nbsp;application&nbsp;is&nbsp;already&nbsp;running&quot;);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;1;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultApiClient&nbsp;=&nbsp;new&nbsp;ApiClient(</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.ApiBaseAddress,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.ApiPort,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.ApiUsbEndPoint,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.RetryPeriod,&nbsp;Config.MaxEntries,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.MaxRetries,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;PersistentQueue(Config.CacheFileName)</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IProcessDetection&nbsp;processProcessDetection&nbsp;=&nbsp;new&nbsp;ProcessDetection(</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.T32ProcessName,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Config.DetectionPeriod,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InfoFetcher,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DefaultApiClient,</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new&nbsp;ProcessUtils()</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;apiClientThread&nbsp;=&nbsp;new&nbsp;Thread(DefaultApiClient.Run)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsBackground&nbsp;=&nbsp;true</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;apiClientThread.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;processThread&nbsp;=&nbsp;new&nbsp;Thread(processProcessDetection.RunPeriodicDetection)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IsBackground&nbsp;=&nbsp;true</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;processThread.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while&nbsp;(true)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(MainLoopDelayMs);</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="coverableline" title="Not covered (0 visits)" data-coverage="{'AllTestMethods': {'VC': '0', 'LVS': 'red'}}"><td class="red">&nbsp;</td><td class="leftmargin rightmargin right">0</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightred"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line16" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Config()"><i class="icon-wrench"></i>Config()</a><br />
+<a href="#file0_line16" class="navigatetohash percentagebar percentagebar90" title="Line coverage: 91.6% - Program()"><i class="icon-cube"></i>Program()</a><br />
+<a href="#file0_line17" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DefaultLogger()"><i class="icon-wrench"></i>DefaultLogger()</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DefaultApiClient()"><i class="icon-wrench"></i>DefaultApiClient()</a><br />
+<a href="#file0_line18" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - DefaultApiClient(LDClient.network.IApiClient)"><i class="icon-wrench"></i>DefaultApiClient(LDClient.network.IApiClient)</a><br />
+<a href="#file0_line30" class="navigatetohash percentagebar percentagebar0" title="Line coverage: 0% - Main()"><i class="icon-cube"></i>Main()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html
new file mode 100644
index 0000000..be4d31b
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ApiClientTests.html
@@ -0,0 +1,344 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClientTests.network.ApiClientTests - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClientTests.network.ApiClientTests">LDClientTests.network.ApiClientTests</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsnetworkApiClientTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\network\ApiClientTests.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="81">81</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="81">81</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="167">167</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="81 of 81">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ApiClientTests()"><a href="#file0_line31" class="navigatetohash">ApiClientTests()</a></td><td>12</td><td>0</td></tr>
+<tr><td title="Setup()"><a href="#file0_line53" class="navigatetohash">Setup()</a></td><td>60</td><td>0</td></tr>
+<tr><td title="SendPayloadAsync_SendingSuccess_PayloadSent()"><a href="#file0_line73" class="navigatetohash">SendPayloadAsync_SendingSuccess_PayloadSent()</a></td><td>27</td><td>0</td></tr>
+<tr><td title="SendPayloadAsync_SendingFailure_PayloadSaved2Cache()"><a href="#file0_line86" class="navigatetohash">SendPayloadAsync_SendingFailure_PayloadSaved2Cache()</a></td><td>63</td><td>0</td></tr>
+<tr><td title="Run_EmptyCache_NothingSent()"><a href="#file0_line104" class="navigatetohash">Run_EmptyCache_NothingSent()</a></td><td>60</td><td>0</td></tr>
+<tr><td title="Run_CacheContainX_SentX(int, int, int)"><a href="#file0_line138" class="navigatetohash">Run_CacheContainX_SentX(...)</a></td><td>70</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsnetworkApiClientTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\network\ApiClientTests.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Collections.Generic;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Linq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Net.Http;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Net.Http.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Runtime.CompilerServices;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Text.Json;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>using&nbsp;DiskQueue;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network.data;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code>using&nbsp;Moq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code>using&nbsp;Newtonsoft.Json.Serialization;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>using&nbsp;NUnit.Framework;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>using&nbsp;NUnit.Framework.Internal;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClientTests.network&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;internal&nbsp;class&nbsp;ApiClientTests&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ApiClient&nbsp;_client;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IHttpClient&gt;&nbsp;_httpClientMock;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IPersistentQueue&gt;&nbsp;_cacheMock;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IPersistentQueueSession&gt;&nbsp;_cacheSessionMock;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;Payload&nbsp;ExamplePayload&nbsp;=&nbsp;new()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserName&nbsp;=&nbsp;&quot;honikCz&quot;,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HostName&nbsp;=&nbsp;&quot;Bramborak&quot;,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TimeStamp&nbsp;=&nbsp;&quot;2022-03-21&nbsp;18:05:00&quot;,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HeadDevice&nbsp;=&nbsp;new&nbsp;DebuggerInfo&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SerialNumber&nbsp;=&nbsp;&quot;C12345678912&quot;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BodyDevice&nbsp;=&nbsp;new&nbsp;DebuggerInfo&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SerialNumber&nbsp;=&nbsp;&quot;C98765432198&quot;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Status&nbsp;=&nbsp;ConnectionStatus.Connected</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;string&nbsp;ApiUrl&nbsp;=&nbsp;&quot;http://127.0.0.1&quot;;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;string&nbsp;ApiEndPoint&nbsp;=&nbsp;&quot;/lauterbach-debugger-logs/&quot;;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;uint&nbsp;ApiPort&nbsp;=&nbsp;8000;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;uint&nbsp;ApiRetryPeriod&nbsp;=&nbsp;50;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;uint&nbsp;ApiMaxEntries&nbsp;=&nbsp;10;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;uint&nbsp;ApiMaxRetries&nbsp;=&nbsp;5;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[SetUp]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Setup()&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock&nbsp;=&nbsp;new&nbsp;Mock&lt;IHttpClient&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock&nbsp;=&nbsp;new&nbsp;Mock&lt;IPersistentQueue&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock&nbsp;=&nbsp;new&nbsp;Mock&lt;IPersistentQueueSession&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Setup(x&nbsp;=&gt;&nbsp;x.Dequeue()).Returns(JsonSerializer.SerializeToUtf8Bytes(ExamplePayload));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Setup(x&nbsp;=&gt;&nbsp;x.Dispose()).Callback(()&nbsp;=&gt;&nbsp;{&nbsp;});</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Setup(p&nbsp;=&gt;&nbsp;p.Enqueue(It.IsAny&lt;byte[]&gt;())).Callback(()&nbsp;=&gt;&nbsp;{&nbsp;});</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Setup(p&nbsp;=&gt;&nbsp;p.Flush()).Callback(()&nbsp;=&gt;&nbsp;{&nbsp;});</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Setup(p&nbsp;=&gt;&nbsp;p.OpenSession()).Returns(_cacheSessionMock.Object);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_client&nbsp;=&nbsp;new&nbsp;ApiClient(ApiUrl,&nbsp;ApiPort,&nbsp;ApiEndPoint,&nbsp;ApiRetryPeriod,&nbsp;ApiMaxEntries,&nbsp;ApiMaxRetries,&nbsp;_cacheMo</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_client&nbsp;=&nbsp;_httpClientMock.Object</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;SendPayloadAsync_SendingSuccess_PayloadSent()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Setup(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()))</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Returns(Task.FromResult(new&nbsp;HttpResponseMessage(System.Net.HttpStatusCode.OK)));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;_client.SendPayloadAsync(ExamplePayload);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Verify(x&nbsp;=&gt;&nbsp;x.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(15,&nbsp;true)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(0,&nbsp;false)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;SendPayloadAsync_SendingFailure_PayloadSaved2Cache(int&nbsp;itemsInQueueCount,&nbsp;bool&nbsp;isDequeueHappen</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Setup(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()))</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Returns(Task.FromResult(new&nbsp;HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Setup(p&nbsp;=&gt;&nbsp;p.EstimatedCountOfItemsInQueue).Returns(itemsInQueueCount);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;await&nbsp;_client.SendPayloadAsync(ExamplePayload);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(p&nbsp;=&gt;&nbsp;p.Enqueue(It.IsAny&lt;byte[]&gt;()),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Verify(x&nbsp;=&gt;&nbsp;x.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(x&nbsp;=&gt;&nbsp;x.Flush(),&nbsp;Times.Once);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(x&nbsp;=&gt;&nbsp;x.Dequeue(),&nbsp;isDequeueHappening&nbsp;?&nbsp;Times.Once&nbsp;:&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(1000)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Run_EmptyCache_NothingSent()&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//nothing&nbsp;in&nbsp;cache</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Setup(p&nbsp;=&gt;&nbsp;p.EstimatedCountOfItemsInQueue).Returns(0);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Setup(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()))</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Returns(Task.FromResult(new&nbsp;HttpResponseMessage(System.Net.HttpStatusCode.UnprocessableEntity)));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;clientThread&nbsp;=&nbsp;new&nbsp;Thread(_client.Run);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clientThread.Start();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(400);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_client.ClientRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//_processDetection.DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clientThread.Join();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Verify(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(p&nbsp;=&gt;&nbsp;p.Enqueue(It.IsAny&lt;byte[]&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(p&nbsp;=&gt;&nbsp;p.Flush(),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Verify(p&nbsp;=&gt;&nbsp;p.EstimatedCountOfItemsInQueue,&nbsp;Times.AtLeastOnce);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;summary&gt;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;Some&nbsp;tests&nbsp;here&nbsp;can&nbsp;fail&nbsp;due&nbsp;to&nbsp;not&nbsp;long&nbsp;enough&nbsp;sleep&nbsp;period.</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line128"></a><code>128</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;/summary&gt;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line129"></a><code>129</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name=&quot;itemsInQueueCount&quot;&gt;&lt;/param&gt;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line130"></a><code>130</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name=&quot;flushedHappened&quot;&gt;&lt;/param&gt;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line131"></a><code>131</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&lt;param&nbsp;name=&quot;testSleep&quot;&gt;&lt;/param&gt;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line132"></a><code>132</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line133"></a><code>133</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(5000)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line134"></a><code>134</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(100,&nbsp;20,&nbsp;2000)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line135"></a><code>135</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(15,&nbsp;3,&nbsp;600)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line136"></a><code>136</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(1,&nbsp;1,&nbsp;200)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line137"></a><code>137</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(6,&nbsp;2,&nbsp;400)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line138"></a><code>138</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Run_CacheContainX_SentX(int&nbsp;itemsInQueueCount,&nbsp;int&nbsp;flushedHappened,&nbsp;int&nbsp;testSleep)&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line139"></a><code>139</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line140"></a><code>140</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;cacheItemCount&nbsp;=&nbsp;itemsInQueueCount;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line141"></a><code>141</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//nothing&nbsp;in&nbsp;cache</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line142"></a><code>142</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Setup(p&nbsp;=&gt;&nbsp;p.EstimatedCountOfItemsInQueue).Returns(()&nbsp;=&gt;&nbsp;{&nbsp;return&nbsp;cacheItemCount;&nbsp;});</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line143"></a><code>143</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Setup(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()))</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line144"></a><code>144</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Returns(Task.FromResult(new&nbsp;HttpResponseMessage(System.Net.HttpStatusCode.OK)));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line145"></a><code>145</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Setup(x&nbsp;=&gt;&nbsp;x.Dequeue())</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line146"></a><code>146</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;.Returns(()&nbsp;=&gt;&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line147"></a><code>147</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;--cacheItemCount;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line148"></a><code>148</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;JsonSerializer.SerializeToUtf8Bytes(ExamplePayload);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line149"></a><code>149</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;});</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line150"></a><code>150</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line151"></a><code>151</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;clientThread&nbsp;=&nbsp;new&nbsp;Thread(_client.Run);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line152"></a><code>152</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line153"></a><code>153</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clientThread.Start();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line154"></a><code>154</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(testSleep);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line155"></a><code>155</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_client.ClientRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line156"></a><code>156</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//_processDetection.DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line157"></a><code>157</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;clientThread.Join();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line158"></a><code>158</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line159"></a><code>159</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_httpClientMock.Verify(p&nbsp;=&gt;&nbsp;p.PostAsJsonAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Exactly(itemsInQueueCount));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line160"></a><code>160</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(p&nbsp;=&gt;&nbsp;p.Enqueue(It.IsAny&lt;byte[]&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line161"></a><code>161</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheSessionMock.Verify(p&nbsp;=&gt;&nbsp;p.Flush(),&nbsp;Times.Exactly(flushedHappened));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line162"></a><code>162</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_cacheMock.Verify(p&nbsp;=&gt;&nbsp;p.EstimatedCountOfItemsInQueue,&nbsp;Times.AtLeastOnce);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line163"></a><code>163</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line164"></a><code>164</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line165"></a><code>165</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line166"></a><code>166</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line167"></a><code>167</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line31" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ApiClientTests()"><i class="icon-cube"></i>ApiClientTests()</a><br />
+<a href="#file0_line53" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br />
+<a href="#file0_line73" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync_SendingSuccess_PayloadSent()"><i class="icon-cube"></i>SendPayloadAsync_SendingSuccess_PayloadSent()</a><br />
+<a href="#file0_line86" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - SendPayloadAsync_SendingFailure_PayloadSaved2Cache()"><i class="icon-cube"></i>SendPayloadAsync_SendingFailure_PayloadSaved2Cache()</a><br />
+<a href="#file0_line104" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run_EmptyCache_NothingSent()"><i class="icon-cube"></i>Run_EmptyCache_NothingSent()</a><br />
+<a href="#file0_line138" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Run_CacheContainX_SentX(int, int, int)"><i class="icon-cube"></i>Run_CacheContainX_SentX(int, int, int)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html
new file mode 100644
index 0000000..3830ab5
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_DebuggerInfoParserTests.html
@@ -0,0 +1,237 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClientTests.detection.DebuggerInfoParserTests - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClientTests.detection.DebuggerInfoParserTests">LDClientTests.detection.DebuggerInfoParserTests</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionDebuggerInfoParserTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\DebuggerInfoParserTests.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="18">18</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="66">66</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="18 of 18">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="DebuggerInfoParserTests()"><a href="#file0_line9" class="navigatetohash">DebuggerInfoParserTests()</a></td><td>1</td><td>0</td></tr>
+<tr><td title="Parse_CorrectValues_ReturnSerials(string, string, string)"><a href="#file0_line37" class="navigatetohash">Parse_CorrectValues_ReturnSerials(...)</a></td><td>4</td><td>0</td></tr>
+<tr><td title="Parse_IncorrectValues_ThrowException(string)"><a href="#file0_line61" class="navigatetohash">Parse_IncorrectValues_ThrowException(...)</a></td><td>3</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionDebuggerInfoParserTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\DebuggerInfoParserTests.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;NUnit.Framework;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClientTests.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>public&nbsp;class&nbsp;DebuggerInfoParserTests&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;string&nbsp;CorrectFileContent&nbsp;=</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;B::version.hardware&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;PowerDebug&nbsp;USB&nbsp;3.0&nbsp;via&nbsp;USB&nbsp;3.0&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Firmware&nbsp;R.2021.02&nbsp;(136263)&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Instance:&nbsp;1.&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Automotive&nbsp;Debug&nbsp;Cable&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C98765432198&nbsp;&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;string&nbsp;HeadSerialNumber&nbsp;=&nbsp;&quot;C98765432198&quot;;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;readonly&nbsp;string&nbsp;BodySerialNumber&nbsp;=&nbsp;&quot;C12345678912&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(&quot;B::version.hardware&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;PowerDebug&nbsp;USB&nbsp;3.0&nbsp;via&nbsp;USB&nbsp;3.0&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Firmware&nbsp;R.2021.02&nbsp;(136263)&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Instance:&nbsp;1.&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Automotive&nbsp;Debug&nbsp;Cable&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;&quot;,&nbsp;&quot;C12345678912&quot;,&nbsp;&quot;C12345678912&quot;)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(&quot;B::version.hardware&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;PowerDebug&nbsp;USB&nbsp;3.0&nbsp;via&nbsp;USB&nbsp;3.0&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C1awfaw484&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Firmware&nbsp;R.2021.02&nbsp;(136263)&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Instance:&nbsp;1.&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Automotive&nbsp;Debug&nbsp;Cable&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C16468551&quot;,&nbsp;&quot;C16468551&quot;,&nbsp;&quot;C1awfaw484&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Parse_CorrectValues_ReturnSerials(string&nbsp;file,&nbsp;string&nbsp;expectedHead,&nbsp;string&nbsp;expectedBody)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;(headResult,&nbsp;bodyResult)&nbsp;=&nbsp;DebuggerInfoParser.Parse(file);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(expectedHead,&nbsp;headResult);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(expectedBody,&nbsp;bodyResult);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(&quot;B::version.hardware&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;PowerDebug&nbsp;USB&nbsp;3.0&nbsp;via&nbsp;USB&nbsp;3.0&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Firmware&nbsp;R.2021.02&nbsp;(136263)&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Instance:&nbsp;1.&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Automotive&nbsp;Debug&nbsp;Cable&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C12345678912&nbsp;&quot;)]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[TestCase(&quot;B::version.hardware&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;PowerDebug&nbsp;USB&nbsp;3.0&nbsp;via&nbsp;USB&nbsp;3.0&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Serial&nbsp;Number:&nbsp;C1awfaw484&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Firmware&nbsp;R.2021.02&nbsp;(136263)&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Instance:&nbsp;1.&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;Automotive&nbsp;Debug&nbsp;Cable&nbsp;\r\n\r\n&quot;&nbsp;+</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial&nbsp;Numbeeeer:&nbsp;C16468551&quot;)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Parse_IncorrectValues_ThrowException(string&nbsp;file)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.Throws&lt;ArgumentException&gt;(()&nbsp;=&gt;&nbsp;DebuggerInfoParser.Parse(file));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line9" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - DebuggerInfoParserTests()"><i class="icon-cube"></i>DebuggerInfoParserTests()</a><br />
+<a href="#file0_line37" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse_CorrectValues_ReturnSerials(string, string, string)"><i class="icon-cube"></i>Parse_CorrectValues_ReturnSerials(string, string, string)</a><br />
+<a href="#file0_line61" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Parse_IncorrectValues_ThrowException(string)"><i class="icon-cube"></i>Parse_IncorrectValues_ThrowException(string)</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html
new file mode 100644
index 0000000..686512c
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_InfoFetcherTests.html
@@ -0,0 +1,294 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClientTests.detection.InfoFetcherTests - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClientTests.detection.InfoFetcherTests">LDClientTests.detection.InfoFetcherTests</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionInfoFetcherTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\InfoFetcherTests.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="59">59</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="59">59</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="117">117</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="59 of 59">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="InfoFetcherTests()"><a href="#file0_line15" class="navigatetohash">InfoFetcherTests()</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Setup()"><a href="#file0_line22" class="navigatetohash">Setup()</a></td><td>9</td><td>0</td></tr>
+<tr><td title="FetchDataAsync_ExecuteAll_ExecutedAndFetched()"><a href="#file0_line43" class="navigatetohash">FetchDataAsync_ExecuteAll_ExecutedAndFetched()</a></td><td>59</td><td>0</td></tr>
+<tr><td title="FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()"><a href="#file0_line65" class="navigatetohash">FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()</a></td><td>64</td><td>0</td></tr>
+<tr><td title="FetchDataAsync_ExecuteWithoutParameters_NotExecuted()"><a href="#file0_line83" class="navigatetohash">FetchDataAsync_ExecuteWithoutParameters_NotExecuted()</a></td><td>64</td><td>0</td></tr>
+<tr><td title="FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()"><a href="#file0_line100" class="navigatetohash">FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()</a></td><td>65</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionInfoFetcherTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\InfoFetcherTests.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.IO;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.utils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;Moq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;NUnit.Framework;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClientTests.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code>internal&nbsp;class&nbsp;InfoFetcherTests&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;InfoFetcher&nbsp;_defaultFetcher;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;InfoFetcher&nbsp;_fetcherWithoutPars;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string[]&nbsp;_defaultArguments&nbsp;=&nbsp;new[]&nbsp;{&nbsp;&quot;argument&nbsp;1&quot;,&nbsp;&quot;argument&nbsp;2&quot;&nbsp;,&nbsp;&quot;argument&nbsp;3&quot;};</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;const&nbsp;uint&nbsp;DefaultMaxAttempts&nbsp;=&nbsp;5;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IProcessUtils&gt;&nbsp;_mockProcessUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IFileUtils&gt;&nbsp;_mockFileUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[SetUp]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Setup()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils&nbsp;=&nbsp;new&nbsp;Mock&lt;IProcessUtils&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils&nbsp;=&nbsp;new&nbsp;Mock&lt;IFileUtils&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_defaultFetcher&nbsp;=&nbsp;new&nbsp;InfoFetcher(DefaultMaxAttempts,&nbsp;50,&nbsp;&quot;info.txt&quot;,&nbsp;&quot;executable.exe&quot;,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_defaultArguments,&nbsp;0,&nbsp;50)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileUtils&nbsp;=&nbsp;_mockFileUtils.Object,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessUtils&nbsp;=&nbsp;_mockProcessUtils.Object</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fetcherWithoutPars&nbsp;=&nbsp;new&nbsp;InfoFetcher(DefaultMaxAttempts,&nbsp;50,&nbsp;&quot;info.txt&quot;,&nbsp;&quot;executable.exe&quot;,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;null,&nbsp;0,&nbsp;50)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileUtils&nbsp;=&nbsp;_mockFileUtils.Object,</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessUtils&nbsp;=&nbsp;_mockProcessUtils.Object</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;FetchDataAsync_ExecuteAll_ExecutedAndFetched()&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;())).Returns(true);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Setup(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;())).</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns(DebuggerInfoParserTests.CorrectFileContent.Split(&quot;\n&quot;));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;_defaultFetcher.FetchDataAsync();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsTrue(result);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Verify(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;()),&nbsp;Times.Exactly(_defaultArguments.Length));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(DebuggerInfoParserTests.BodySerialNumber,&nbsp;_defaultFetcher.BodySerialNumber);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.AreEqual(DebuggerInfoParserTests.HeadSerialNumber,&nbsp;_defaultFetcher.HeadSerialNumber);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;())).Returns(false);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Setup(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;())).</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns(new&nbsp;[]{&quot;&quot;});</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;_defaultFetcher.FetchDataAsync();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsFalse(result);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Verify(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;()),&nbsp;Times.Exactly(1));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Verify(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;FetchDataAsync_ExecuteWithoutParameters_NotExecuted()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;())).Returns(false);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Setup(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;())).</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Returns(new[]&nbsp;{&nbsp;&quot;&quot;&nbsp;});</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;_fetcherWithoutPars.FetchDataAsync();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsFalse(result);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Verify(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Verify(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;async&nbsp;Task&nbsp;FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;())).Returns(true);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Setup(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;())).Throws(new&nbsp;FileNotFoundException());</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;result&nbsp;=&nbsp;await&nbsp;_defaultFetcher.FetchDataAsync();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Assert.IsFalse(result);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Verify(x&nbsp;=&gt;&nbsp;x.ExecuteNewProcess(It.IsAny&lt;string&gt;(),&nbsp;It.IsAny&lt;string&gt;(),</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;It.IsAny&lt;int&gt;(),&nbsp;It.IsAny&lt;int&gt;()),&nbsp;Times.Exactly(_defaultArguments.Length));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockFileUtils.Verify(x&nbsp;=&gt;&nbsp;x.ReadFileAllLines(It.IsAny&lt;string&gt;()),&nbsp;Times.Exactly((int)DefaultMaxAttempts));</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line15" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - InfoFetcherTests()"><i class="icon-cube"></i>InfoFetcherTests()</a><br />
+<a href="#file0_line22" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br />
+<a href="#file0_line43" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteAll_ExecutedAndFetched()"><i class="icon-cube"></i>FetchDataAsync_ExecuteAll_ExecutedAndFetched()</a><br />
+<a href="#file0_line65" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()"><i class="icon-cube"></i>FetchDataAsync_ExecuteNonExistentProgram_ExecutionFailed()</a><br />
+<a href="#file0_line83" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteWithoutParameters_NotExecuted()"><i class="icon-cube"></i>FetchDataAsync_ExecuteWithoutParameters_NotExecuted()</a><br />
+<a href="#file0_line100" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()"><i class="icon-cube"></i>FetchDataAsync_ExecuteInfoNotCreated_FetchFailed()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html
new file mode 100644
index 0000000..b46a892
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/ldclienttests.dll_ProcessDetectionTests.html
@@ -0,0 +1,311 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1.0" />
+<meta http-equiv="X-UA-Compatible" content="IE=EDGE,chrome=1" />
+<link href="data:image/png;base64,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" rel="icon" type="image/x-icon" />
+<title>LDClientTests.detection.ProcessDetectionTests - Coverage Report</title>
+<link rel="stylesheet" type="text/css" href="report.css" />
+</head><body><div class="container"><div class="containerleft">
+<h1><a href="index.html" class="back">&lt;</a> Summary</h1>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Information</div>
+<div class="card-body">
+<div class="table">
+<table>
+<tr>
+<th>Class:</th>
+<td class="limit-width " title="LDClientTests.detection.ProcessDetectionTests">LDClientTests.detection.ProcessDetectionTests</td>
+</tr>
+<tr>
+<th>Assembly:</th>
+<td class="limit-width " title="ldclienttests.dll">ldclienttests.dll</td>
+</tr>
+<tr>
+<th>File(s):</th>
+<td class="overflow-wrap"><a href="#CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionProcessDetectionTestscs" class="navigatetohash">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\ProcessDetectionTests.cs</a></td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+</div>
+<div class="card-group">
+<div class="card">
+<div class="card-header">Line coverage</div>
+<div class="card-body">
+<div class="large cardpercentagebar cardpercentagebar0">100%</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered lines:</th>
+<td class="limit-width right" title="61">61</td>
+</tr>
+<tr>
+<th>Uncovered lines:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Coverable lines:</th>
+<td class="limit-width right" title="61">61</td>
+</tr>
+<tr>
+<th>Total lines:</th>
+<td class="limit-width right" title="132">132</td>
+</tr>
+<tr>
+<th>Line coverage:</th>
+<td class="limit-width right" title="61 of 61">100%</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Branch coverage</div>
+<div class="card-body">
+<div class="large">N/A</div>
+<div class="table">
+<table>
+<tr>
+<th>Covered branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Total branches:</th>
+<td class="limit-width right" title="0">0</td>
+</tr>
+<tr>
+<th>Branch coverage:</th>
+<td class="limit-width right" title="N/A">N/A</td>
+</tr>
+</table>
+</div>
+</div>
+</div>
+<div class="card">
+<div class="card-header">Method coverage</div>
+<div class="card-body">
+<div class="center">
+<p>Method coverage is only available for sponsors.</p>
+<a class="pro-button" href="https://danielpalme.github.io/ReportGenerator/pro" target="_blank">Upgrade to PRO version</a>
+</div>
+</div>
+</div>
+</div>
+<h1>Metrics</h1>
+<div class="table-responsive">
+<table class="overview table-fixed">
+<thead><tr><th>Method</th><th>Blocks covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th><th>Blocks not covered <a href="https://en.wikipedia.org/wiki/Code_coverage"><i class="icon-info-circled"></i></a></th></tr></thead>
+<tbody>
+<tr><td title="ProcessDetectionTests()"><a href="#file0_line20" class="navigatetohash">ProcessDetectionTests()</a></td><td>2</td><td>0</td></tr>
+<tr><td title="Setup()"><a href="#file0_line24" class="navigatetohash">Setup()</a></td><td>33</td><td>0</td></tr>
+<tr><td title="StartAndStopDetection(int)"><a href="#file0_line40" class="navigatetohash">StartAndStopDetection(...)</a></td><td>6</td><td>0</td></tr>
+<tr><td title="RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()"><a href="#file0_line53" class="navigatetohash">RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()</a></td><td>39</td><td>0</td></tr>
+<tr><td title="RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()"><a href="#file0_line66" class="navigatetohash">RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()</a></td><td>39</td><td>0</td></tr>
+<tr><td title="RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()"><a href="#file0_line81" class="navigatetohash">RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()</a></td><td>54</td><td>0</td></tr>
+<tr><td title="RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()"><a href="#file0_line105" class="navigatetohash">RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()</a></td><td>76</td><td>0</td></tr>
+</tbody>
+</table>
+</div>
+<h1>File(s)</h1>
+<h2 id="CUserspultaOneDrivePlochaSchoolN2ASWIaswi2022bugthugsld_clientLDClientTestsdetectionProcessDetectionTestscs">C:\Users\pulta\OneDrive\Plocha\School\N\2\ASWI\aswi2022bug-thugs\ld_client\LDClientTests\detection\ProcessDetectionTests.cs</h2>
+<div class="table-responsive">
+<table class="lineAnalysis">
+<thead><tr><th></th><th>#</th><th>Line</th><th></th><th>Line coverage</th></tr></thead>
+<tbody>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line1"></a><code>1</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line2"></a><code>2</code></td><td></td><td class="lightgray"><code>using&nbsp;System.Threading.Tasks;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line3"></a><code>3</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line4"></a><code>4</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line5"></a><code>5</code></td><td></td><td class="lightgray"><code>using&nbsp;LDClient.network.data;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line6"></a><code>6</code></td><td></td><td class="lightgray"><code>using&nbsp;Moq;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line7"></a><code>7</code></td><td></td><td class="lightgray"><code>using&nbsp;NUnit.Framework;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line8"></a><code>8</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line9"></a><code>9</code></td><td></td><td class="lightgray"><code>namespace&nbsp;LDClientTests.detection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line10"></a><code>10</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line11"></a><code>11</code></td><td></td><td class="lightgray"><code>public&nbsp;class&nbsp;ProcessDetectionTests&nbsp;{</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line12"></a><code>12</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line13"></a><code>13</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;ProcessDetection&nbsp;_processDetection;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line14"></a><code>14</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line15"></a><code>15</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line16"></a><code>16</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IApiClient&gt;&nbsp;_mockApiClient;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line17"></a><code>17</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IInfoFetcher&gt;&nbsp;_mockInfoFetcher;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line18"></a><code>18</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;Mock&lt;IProcessUtils&gt;&nbsp;_mockProcessUtils;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line19"></a><code>19</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line20"></a><code>20</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;readonly&nbsp;string&nbsp;_defaultSerialNumber&nbsp;=&nbsp;&quot;C12345678912&quot;;</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line21"></a><code>21</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line22"></a><code>22</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line23"></a><code>23</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[SetUp]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line24"></a><code>24</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;Setup()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line25"></a><code>25</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient&nbsp;=&nbsp;new&nbsp;Mock&lt;IApiClient&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line26"></a><code>26</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient.Setup(x&nbsp;=&gt;&nbsp;x.SendPayloadAsync(It.IsAny&lt;Payload&gt;())).Returns(Task.CompletedTask);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line27"></a><code>27</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line28"></a><code>28</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line29"></a><code>29</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher&nbsp;=&nbsp;new&nbsp;Mock&lt;IInfoFetcher&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line30"></a><code>30</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.BodySerialNumber).Returns(_defaultSerialNumber);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line31"></a><code>31</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.HeadSerialNumber).Returns(_defaultSerialNumber);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line32"></a><code>32</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line33"></a><code>33</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils&nbsp;=&nbsp;new&nbsp;Mock&lt;IProcessUtils&gt;(MockBehavior.Strict);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line34"></a><code>34</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line35"></a><code>35</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line36"></a><code>36</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processDetection&nbsp;=&nbsp;new&nbsp;ProcessDetection(&quot;process&quot;,&nbsp;50,&nbsp;_mockInfoFetcher.Object,&nbsp;_mockApiClient.Object,&nbsp;_mockPro</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line37"></a><code>37</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line38"></a><code>38</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line39"></a><code>39</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line40"></a><code>40</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;void&nbsp;StartAndStopDetection(int&nbsp;timeout)&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line41"></a><code>41</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;detectionThread&nbsp;=&nbsp;new&nbsp;Thread(_processDetection.RunPeriodicDetection);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line42"></a><code>42</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line43"></a><code>43</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line44"></a><code>44</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line45"></a><code>45</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(timeout);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line46"></a><code>46</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line47"></a><code>47</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processDetection.DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line48"></a><code>48</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Join();</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line49"></a><code>49</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line50"></a><code>50</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line51"></a><code>51</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line52"></a><code>52</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(1000)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line53"></a><code>53</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line54"></a><code>54</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.FetchDataAsync()).Returns(Task.FromResult(false));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line55"></a><code>55</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(true);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line56"></a><code>56</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line57"></a><code>57</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line58"></a><code>58</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StartAndStopDetection(500);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line59"></a><code>59</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line60"></a><code>60</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient.Verify(x&nbsp;=&gt;&nbsp;x.SendPayloadAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Never);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line61"></a><code>61</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Verify(x&nbsp;=&gt;&nbsp;x.FetchDataAsync(),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line62"></a><code>62</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line63"></a><code>63</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line64"></a><code>64</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line65"></a><code>65</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(1000)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line66"></a><code>66</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line67"></a><code>67</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line68"></a><code>68</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(true);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line69"></a><code>69</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line70"></a><code>70</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line71"></a><code>71</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;StartAndStopDetection(500);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line72"></a><code>72</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line73"></a><code>73</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient.Verify(x&nbsp;=&gt;&nbsp;x.SendPayloadAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line74"></a><code>74</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Verify(x&nbsp;=&gt;&nbsp;x.FetchDataAsync(),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line75"></a><code>75</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line76"></a><code>76</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line77"></a><code>77</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line78"></a><code>78</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line79"></a><code>79</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line80"></a><code>80</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(1000)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line81"></a><code>81</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line82"></a><code>82</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line83"></a><code>83</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(true);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line84"></a><code>84</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line85"></a><code>85</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;detectionThread&nbsp;=&nbsp;new&nbsp;Thread(_processDetection.RunPeriodicDetection);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line86"></a><code>86</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line87"></a><code>87</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line88"></a><code>88</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line89"></a><code>89</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(250);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line90"></a><code>90</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(false);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line91"></a><code>91</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line92"></a><code>92</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(250);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line93"></a><code>93</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line94"></a><code>94</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processDetection.DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line95"></a><code>95</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Join();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line96"></a><code>96</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line97"></a><code>97</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient.Verify(x&nbsp;=&gt;&nbsp;x.SendPayloadAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Exactly(2));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line98"></a><code>98</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Verify(x&nbsp;=&gt;&nbsp;x.FetchDataAsync(),&nbsp;Times.Once);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line99"></a><code>99</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line100"></a><code>100</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line101"></a><code>101</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line102"></a><code>102</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line103"></a><code>103</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Test]</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line104"></a><code>104</code></td><td></td><td class="lightgray"><code>&nbsp;&nbsp;&nbsp;&nbsp;[Timeout(2000)]</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line105"></a><code>105</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;void&nbsp;RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()&nbsp;{</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line106"></a><code>106</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Setup(x&nbsp;=&gt;&nbsp;x.FetchDataAsync()).Returns(Task.FromResult(true));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line107"></a><code>107</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(true);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line108"></a><code>108</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line109"></a><code>109</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var&nbsp;detectionThread&nbsp;=&nbsp;new&nbsp;Thread(_processDetection.RunPeriodicDetection);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line110"></a><code>110</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line111"></a><code>111</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Start();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line112"></a><code>112</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line113"></a><code>113</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(200);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line114"></a><code>114</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(false);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line115"></a><code>115</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line116"></a><code>116</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(200);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line117"></a><code>117</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(true);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line118"></a><code>118</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line119"></a><code>119</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line120"></a><code>120</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(200);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line121"></a><code>121</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockProcessUtils.Setup(x&nbsp;=&gt;&nbsp;x.IsProcessRunning(It.IsAny&lt;string&gt;())).Returns(false);</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line122"></a><code>122</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Thread.Sleep(200);</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line123"></a><code>123</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line124"></a><code>124</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_processDetection.DetectionRunning&nbsp;=&nbsp;false;</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line125"></a><code>125</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;detectionThread.Join();</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line126"></a><code>126</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line127"></a><code>127</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockApiClient.Verify(x&nbsp;=&gt;&nbsp;x.SendPayloadAsync(It.IsAny&lt;Payload&gt;()),&nbsp;Times.Exactly(4));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line128"></a><code>128</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_mockInfoFetcher.Verify(x&nbsp;=&gt;&nbsp;x.FetchDataAsync(),&nbsp;Times.Exactly(2));</code></td></tr>
+<tr class="coverableline" title="Covered (1 visits)" data-coverage="{'AllTestMethods': {'VC': '1', 'LVS': 'green'}}"><td class="green">&nbsp;</td><td class="leftmargin rightmargin right">1</td><td class="rightmargin right"><a id="file0_line129"></a><code>129</code></td><td></td><td class="lightgreen"><code>&nbsp;&nbsp;&nbsp;&nbsp;}</code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line130"></a><code>130</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line131"></a><code>131</code></td><td></td><td class="lightgray"><code></code></td></tr>
+<tr class="" title="Not coverable" data-coverage="{'AllTestMethods': {'VC': '', 'LVS': 'gray'}}"><td class="gray">&nbsp;</td><td class="leftmargin rightmargin right"></td><td class="rightmargin right"><a id="file0_line132"></a><code>132</code></td><td></td><td class="lightgray"><code>}</code></td></tr>
+</tbody>
+</table>
+</div>
+<div class="footer">Generated by: ReportGenerator 5.1.5.0<br />27.04.2022 - 19:47:47<br /><a href="https://github.com/danielpalme/ReportGenerator">GitHub</a> | <a href="http://www.palmmedia.de">www.palmmedia.de</a></div></div>
+<div class="containerright">
+<div class="containerrightfixed">
+<h1>Methods/Properties</h1>
+<a href="#file0_line20" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - ProcessDetectionTests()"><i class="icon-cube"></i>ProcessDetectionTests()</a><br />
+<a href="#file0_line24" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - Setup()"><i class="icon-cube"></i>Setup()</a><br />
+<a href="#file0_line40" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - StartAndStopDetection(int)"><i class="icon-cube"></i>StartAndStopDetection(int)</a><br />
+<a href="#file0_line53" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartFetchFailed_1Fetch0PayloadSent()</a><br />
+<a href="#file0_line66" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartFetchSuccess_1Fetch1PayloadSent()</a><br />
+<a href="#file0_line81" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_ProcessStartAndStopped_1Fetch2PayloadSent()</a><br />
+<a href="#file0_line105" class="navigatetohash percentagebar percentagebar100" title="Line coverage: 100% - RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()"><i class="icon-cube"></i>RunPeriodicDetection_2xProcessStartAndStopped_2Fetch4PayloadSent()</a><br />
+<br/></div>
+</div></div>
+<script type="text/javascript">
+/* <![CDATA[ */
+(function() {
+    var url = window.location.href;
+    var startOfQueryString = url.indexOf('?');
+    var queryString = startOfQueryString > -1 ? url.substr(startOfQueryString) : '';
+
+    if (startOfQueryString > -1) {
+        var i = 0, href= null;
+        var css = document.getElementsByTagName('link');
+
+        for (i = 0; i < css.length; i++) {
+            if (css[i].getAttribute('rel') !== 'stylesheet') {
+            continue;
+            }
+
+            href = css[i].getAttribute('href');
+
+            if (href) {
+            css[i].setAttribute('href', href + queryString);
+            }
+        }
+
+        var links = document.getElementsByTagName('a');
+
+        for (i = 0; i < links.length; i++) {
+            href = links[i].getAttribute('href');
+
+            if (href
+                && !href.startsWith('http://')
+                && !href.startsWith('https://')
+                && !href.startsWith('#')
+                && href.indexOf('?') === -1) {
+            links[i].setAttribute('href', href + queryString);
+            }
+        }
+    }
+
+    var newScript = document.createElement('script');
+    newScript.src = 'class.js' + queryString;
+    document.getElementsByTagName('body')[0].appendChild(newScript);
+})();
+/* ]]> */ 
+</script>
+</body></html>
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/main.js b/ld_client/doc/coverage/coveragereport/main.js
new file mode 100644
index 0000000..51d2896
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/main.js
@@ -0,0 +1,301 @@
+/* Chartist.js 0.11.4
+ * Copyright © 2019 Gion Kunz
+ * Free to use under either the WTFPL license or the MIT license.
+ * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-WTFPL
+ * https://raw.githubusercontent.com/gionkunz/chartist-js/master/LICENSE-MIT
+ */
+
+!function (a, b) { "function" == typeof define && define.amd ? define("Chartist", [], function () { return a.Chartist = b() }) : "object" == typeof module && module.exports ? module.exports = b() : a.Chartist = b() }(this, function () {
+    var a = { version: "0.11.4" }; return function (a, b) { "use strict"; var c = a.window, d = a.document; b.namespaces = { svg: "http://www.w3.org/2000/svg", xmlns: "http://www.w3.org/2000/xmlns/", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", ct: "http://gionkunz.github.com/chartist-js/ct" }, b.noop = function (a) { return a }, b.alphaNumerate = function (a) { return String.fromCharCode(97 + a % 26) }, b.extend = function (a) { var c, d, e; for (a = a || {}, c = 1; c < arguments.length; c++) { d = arguments[c]; for (var f in d) e = d[f], "object" != typeof e || null === e || e instanceof Array ? a[f] = e : a[f] = b.extend(a[f], e) } return a }, b.replaceAll = function (a, b, c) { return a.replace(new RegExp(b, "g"), c) }, b.ensureUnit = function (a, b) { return "number" == typeof a && (a += b), a }, b.quantity = function (a) { if ("string" == typeof a) { var b = /^(\d+)\s*(.*)$/g.exec(a); return { value: +b[1], unit: b[2] || void 0 } } return { value: a } }, b.querySelector = function (a) { return a instanceof Node ? a : d.querySelector(a) }, b.times = function (a) { return Array.apply(null, new Array(a)) }, b.sum = function (a, b) { return a + (b ? b : 0) }, b.mapMultiply = function (a) { return function (b) { return b * a } }, b.mapAdd = function (a) { return function (b) { return b + a } }, b.serialMap = function (a, c) { var d = [], e = Math.max.apply(null, a.map(function (a) { return a.length })); return b.times(e).forEach(function (b, e) { var f = a.map(function (a) { return a[e] }); d[e] = c.apply(null, f) }), d }, b.roundWithPrecision = function (a, c) { var d = Math.pow(10, c || b.precision); return Math.round(a * d) / d }, b.precision = 8, b.escapingMap = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#039;" }, b.serialize = function (a) { return null === a || void 0 === a ? a : ("number" == typeof a ? a = "" + a : "object" == typeof a && (a = JSON.stringify({ data: a })), Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, c, b.escapingMap[c]) }, a)) }, b.deserialize = function (a) { if ("string" != typeof a) return a; a = Object.keys(b.escapingMap).reduce(function (a, c) { return b.replaceAll(a, b.escapingMap[c], c) }, a); try { a = JSON.parse(a), a = void 0 !== a.data ? a.data : a } catch (c) { } return a }, b.createSvg = function (a, c, d, e) { var f; return c = c || "100%", d = d || "100%", Array.prototype.slice.call(a.querySelectorAll("svg")).filter(function (a) { return a.getAttributeNS(b.namespaces.xmlns, "ct") }).forEach(function (b) { a.removeChild(b) }), f = new b.Svg("svg").attr({ width: c, height: d }).addClass(e), f._node.style.width = c, f._node.style.height = d, a.appendChild(f._node), f }, b.normalizeData = function (a, c, d) { var e, f = { raw: a, normalized: {} }; return f.normalized.series = b.getDataArray({ series: a.series || [] }, c, d), e = f.normalized.series.every(function (a) { return a instanceof Array }) ? Math.max.apply(null, f.normalized.series.map(function (a) { return a.length })) : f.normalized.series.length, f.normalized.labels = (a.labels || []).slice(), Array.prototype.push.apply(f.normalized.labels, b.times(Math.max(0, e - f.normalized.labels.length)).map(function () { return "" })), c && b.reverseData(f.normalized), f }, b.safeHasProperty = function (a, b) { return null !== a && "object" == typeof a && a.hasOwnProperty(b) }, b.isDataHoleValue = function (a) { return null === a || void 0 === a || "number" == typeof a && isNaN(a) }, b.reverseData = function (a) { a.labels.reverse(), a.series.reverse(); for (var b = 0; b < a.series.length; b++)"object" == typeof a.series[b] && void 0 !== a.series[b].data ? a.series[b].data.reverse() : a.series[b] instanceof Array && a.series[b].reverse() }, b.getDataArray = function (a, c, d) { function e(a) { if (b.safeHasProperty(a, "value")) return e(a.value); if (b.safeHasProperty(a, "data")) return e(a.data); if (a instanceof Array) return a.map(e); if (!b.isDataHoleValue(a)) { if (d) { var c = {}; return "string" == typeof d ? c[d] = b.getNumberOrUndefined(a) : c.y = b.getNumberOrUndefined(a), c.x = a.hasOwnProperty("x") ? b.getNumberOrUndefined(a.x) : c.x, c.y = a.hasOwnProperty("y") ? b.getNumberOrUndefined(a.y) : c.y, c } return b.getNumberOrUndefined(a) } } return a.series.map(e) }, b.normalizePadding = function (a, b) { return b = b || 0, "number" == typeof a ? { top: a, right: a, bottom: a, left: a } : { top: "number" == typeof a.top ? a.top : b, right: "number" == typeof a.right ? a.right : b, bottom: "number" == typeof a.bottom ? a.bottom : b, left: "number" == typeof a.left ? a.left : b } }, b.getMetaData = function (a, b) { var c = a.data ? a.data[b] : a[b]; return c ? c.meta : void 0 }, b.orderOfMagnitude = function (a) { return Math.floor(Math.log(Math.abs(a)) / Math.LN10) }, b.projectLength = function (a, b, c) { return b / c.range * a }, b.getAvailableHeight = function (a, c) { return Math.max((b.quantity(c.height).value || a.height()) - (c.chartPadding.top + c.chartPadding.bottom) - c.axisX.offset, 0) }, b.getHighLow = function (a, c, d) { function e(a) { if (void 0 !== a) if (a instanceof Array) for (var b = 0; b < a.length; b++)e(a[b]); else { var c = d ? +a[d] : +a; g && c > f.high && (f.high = c), h && c < f.low && (f.low = c) } } c = b.extend({}, c, d ? c["axis" + d.toUpperCase()] : {}); var f = { high: void 0 === c.high ? -Number.MAX_VALUE : +c.high, low: void 0 === c.low ? Number.MAX_VALUE : +c.low }, g = void 0 === c.high, h = void 0 === c.low; return (g || h) && e(a), (c.referenceValue || 0 === c.referenceValue) && (f.high = Math.max(c.referenceValue, f.high), f.low = Math.min(c.referenceValue, f.low)), f.high <= f.low && (0 === f.low ? f.high = 1 : f.low < 0 ? f.high = 0 : f.high > 0 ? f.low = 0 : (f.high = 1, f.low = 0)), f }, b.isNumeric = function (a) { return null !== a && isFinite(a) }, b.isFalseyButZero = function (a) { return !a && 0 !== a }, b.getNumberOrUndefined = function (a) { return b.isNumeric(a) ? +a : void 0 }, b.isMultiValue = function (a) { return "object" == typeof a && ("x" in a || "y" in a) }, b.getMultiValue = function (a, c) { return b.isMultiValue(a) ? b.getNumberOrUndefined(a[c || "y"]) : b.getNumberOrUndefined(a) }, b.rho = function (a) { function b(a, c) { return a % c === 0 ? c : b(c, a % c) } function c(a) { return a * a + 1 } if (1 === a) return a; var d, e = 2, f = 2; if (a % 2 === 0) return 2; do e = c(e) % a, f = c(c(f)) % a, d = b(Math.abs(e - f), a); while (1 === d); return d }, b.getBounds = function (a, c, d, e) { function f(a, b) { return a === (a += b) && (a *= 1 + (b > 0 ? o : -o)), a } var g, h, i, j = 0, k = { high: c.high, low: c.low }; k.valueRange = k.high - k.low, k.oom = b.orderOfMagnitude(k.valueRange), k.step = Math.pow(10, k.oom), k.min = Math.floor(k.low / k.step) * k.step, k.max = Math.ceil(k.high / k.step) * k.step, k.range = k.max - k.min, k.numberOfSteps = Math.round(k.range / k.step); var l = b.projectLength(a, k.step, k), m = l < d, n = e ? b.rho(k.range) : 0; if (e && b.projectLength(a, 1, k) >= d) k.step = 1; else if (e && n < k.step && b.projectLength(a, n, k) >= d) k.step = n; else for (; ;) { if (m && b.projectLength(a, k.step, k) <= d) k.step *= 2; else { if (m || !(b.projectLength(a, k.step / 2, k) >= d)) break; if (k.step /= 2, e && k.step % 1 !== 0) { k.step *= 2; break } } if (j++ > 1e3) throw new Error("Exceeded maximum number of iterations while optimizing scale step!") } var o = 2.221e-16; for (k.step = Math.max(k.step, o), h = k.min, i = k.max; h + k.step <= k.low;)h = f(h, k.step); for (; i - k.step >= k.high;)i = f(i, -k.step); k.min = h, k.max = i, k.range = k.max - k.min; var p = []; for (g = k.min; g <= k.max; g = f(g, k.step)) { var q = b.roundWithPrecision(g); q !== p[p.length - 1] && p.push(q) } return k.values = p, k }, b.polarToCartesian = function (a, b, c, d) { var e = (d - 90) * Math.PI / 180; return { x: a + c * Math.cos(e), y: b + c * Math.sin(e) } }, b.createChartRect = function (a, c, d) { var e = !(!c.axisX && !c.axisY), f = e ? c.axisY.offset : 0, g = e ? c.axisX.offset : 0, h = a.width() || b.quantity(c.width).value || 0, i = a.height() || b.quantity(c.height).value || 0, j = b.normalizePadding(c.chartPadding, d); h = Math.max(h, f + j.left + j.right), i = Math.max(i, g + j.top + j.bottom); var k = { padding: j, width: function () { return this.x2 - this.x1 }, height: function () { return this.y1 - this.y2 } }; return e ? ("start" === c.axisX.position ? (k.y2 = j.top + g, k.y1 = Math.max(i - j.bottom, k.y2 + 1)) : (k.y2 = j.top, k.y1 = Math.max(i - j.bottom - g, k.y2 + 1)), "start" === c.axisY.position ? (k.x1 = j.left + f, k.x2 = Math.max(h - j.right, k.x1 + 1)) : (k.x1 = j.left, k.x2 = Math.max(h - j.right - f, k.x1 + 1))) : (k.x1 = j.left, k.x2 = Math.max(h - j.right, k.x1 + 1), k.y2 = j.top, k.y1 = Math.max(i - j.bottom, k.y2 + 1)), k }, b.createGrid = function (a, c, d, e, f, g, h, i) { var j = {}; j[d.units.pos + "1"] = a, j[d.units.pos + "2"] = a, j[d.counterUnits.pos + "1"] = e, j[d.counterUnits.pos + "2"] = e + f; var k = g.elem("line", j, h.join(" ")); i.emit("draw", b.extend({ type: "grid", axis: d, index: c, group: g, element: k }, j)) }, b.createGridBackground = function (a, b, c, d) { var e = a.elem("rect", { x: b.x1, y: b.y2, width: b.width(), height: b.height() }, c, !0); d.emit("draw", { type: "gridBackground", group: a, element: e }) }, b.createLabel = function (a, c, e, f, g, h, i, j, k, l, m) { var n, o = {}; if (o[g.units.pos] = a + i[g.units.pos], o[g.counterUnits.pos] = i[g.counterUnits.pos], o[g.units.len] = c, o[g.counterUnits.len] = Math.max(0, h - 10), l) { var p = d.createElement("span"); p.className = k.join(" "), p.setAttribute("xmlns", b.namespaces.xhtml), p.innerText = f[e], p.style[g.units.len] = Math.round(o[g.units.len]) + "px", p.style[g.counterUnits.len] = Math.round(o[g.counterUnits.len]) + "px", n = j.foreignObject(p, b.extend({ style: "overflow: visible;" }, o)) } else n = j.elem("text", o, k.join(" ")).text(f[e]); m.emit("draw", b.extend({ type: "label", axis: g, index: e, group: j, element: n, text: f[e] }, o)) }, b.getSeriesOption = function (a, b, c) { if (a.name && b.series && b.series[a.name]) { var d = b.series[a.name]; return d.hasOwnProperty(c) ? d[c] : b[c] } return b[c] }, b.optionsProvider = function (a, d, e) { function f(a) { var f = h; if (h = b.extend({}, j), d) for (i = 0; i < d.length; i++) { var g = c.matchMedia(d[i][0]); g.matches && (h = b.extend(h, d[i][1])) } e && a && e.emit("optionsChanged", { previousOptions: f, currentOptions: h }) } function g() { k.forEach(function (a) { a.removeListener(f) }) } var h, i, j = b.extend({}, a), k = []; if (!c.matchMedia) throw "window.matchMedia not found! Make sure you're using a polyfill."; if (d) for (i = 0; i < d.length; i++) { var l = c.matchMedia(d[i][0]); l.addListener(f), k.push(l) } return f(), { removeMediaQueryListeners: g, getCurrentOptions: function () { return b.extend({}, h) } } }, b.splitIntoSegments = function (a, c, d) { var e = { increasingX: !1, fillHoles: !1 }; d = b.extend({}, e, d); for (var f = [], g = !0, h = 0; h < a.length; h += 2)void 0 === b.getMultiValue(c[h / 2].value) ? d.fillHoles || (g = !0) : (d.increasingX && h >= 2 && a[h] <= a[h - 2] && (g = !0), g && (f.push({ pathCoordinates: [], valueData: [] }), g = !1), f[f.length - 1].pathCoordinates.push(a[h], a[h + 1]), f[f.length - 1].valueData.push(c[h / 2])); return f } }(this || global, a), function (a, b) { "use strict"; b.Interpolation = {}, b.Interpolation.none = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e = new b.Svg.Path, f = !0, g = 0; g < c.length; g += 2) { var h = c[g], i = c[g + 1], j = d[g / 2]; void 0 !== b.getMultiValue(j.value) ? (f ? e.move(h, i, !1, j) : e.line(h, i, !1, j), f = !1) : a.fillHoles || (f = !0) } return e } }, b.Interpolation.simple = function (a) { var c = { divisor: 2, fillHoles: !1 }; a = b.extend({}, c, a); var d = 1 / Math.max(1, a.divisor); return function (c, e) { for (var f, g, h, i = new b.Svg.Path, j = 0; j < c.length; j += 2) { var k = c[j], l = c[j + 1], m = (k - f) * d, n = e[j / 2]; void 0 !== n.value ? (void 0 === h ? i.move(k, l, !1, n) : i.curve(f + m, g, k - m, l, k, l, !1, n), f = k, g = l, h = n) : a.fillHoles || (f = k = h = void 0) } return i } }, b.Interpolation.cardinal = function (a) { var c = { tension: 1, fillHoles: !1 }; a = b.extend({}, c, a); var d = Math.min(1, Math.max(0, a.tension)), e = 1 - d; return function f(c, g) { var h = b.splitIntoSegments(c, g, { fillHoles: a.fillHoles }); if (h.length) { if (h.length > 1) { var i = []; return h.forEach(function (a) { i.push(f(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(i) } if (c = h[0].pathCoordinates, g = h[0].valueData, c.length <= 4) return b.Interpolation.none()(c, g); for (var j, k = (new b.Svg.Path).move(c[0], c[1], !1, g[0]), l = 0, m = c.length; m - 2 * !j > l; l += 2) { var n = [{ x: +c[l - 2], y: +c[l - 1] }, { x: +c[l], y: +c[l + 1] }, { x: +c[l + 2], y: +c[l + 3] }, { x: +c[l + 4], y: +c[l + 5] }]; j ? l ? m - 4 === l ? n[3] = { x: +c[0], y: +c[1] } : m - 2 === l && (n[2] = { x: +c[0], y: +c[1] }, n[3] = { x: +c[2], y: +c[3] }) : n[0] = { x: +c[m - 2], y: +c[m - 1] } : m - 4 === l ? n[3] = n[2] : l || (n[0] = { x: +c[l], y: +c[l + 1] }), k.curve(d * (-n[0].x + 6 * n[1].x + n[2].x) / 6 + e * n[2].x, d * (-n[0].y + 6 * n[1].y + n[2].y) / 6 + e * n[2].y, d * (n[1].x + 6 * n[2].x - n[3].x) / 6 + e * n[2].x, d * (n[1].y + 6 * n[2].y - n[3].y) / 6 + e * n[2].y, n[2].x, n[2].y, !1, g[(l + 2) / 2]) } return k } return b.Interpolation.none()([]) } }, b.Interpolation.monotoneCubic = function (a) { var c = { fillHoles: !1 }; return a = b.extend({}, c, a), function d(c, e) { var f = b.splitIntoSegments(c, e, { fillHoles: a.fillHoles, increasingX: !0 }); if (f.length) { if (f.length > 1) { var g = []; return f.forEach(function (a) { g.push(d(a.pathCoordinates, a.valueData)) }), b.Svg.Path.join(g) } if (c = f[0].pathCoordinates, e = f[0].valueData, c.length <= 4) return b.Interpolation.none()(c, e); var h, i, j = [], k = [], l = c.length / 2, m = [], n = [], o = [], p = []; for (h = 0; h < l; h++)j[h] = c[2 * h], k[h] = c[2 * h + 1]; for (h = 0; h < l - 1; h++)o[h] = k[h + 1] - k[h], p[h] = j[h + 1] - j[h], n[h] = o[h] / p[h]; for (m[0] = n[0], m[l - 1] = n[l - 2], h = 1; h < l - 1; h++)0 === n[h] || 0 === n[h - 1] || n[h - 1] > 0 != n[h] > 0 ? m[h] = 0 : (m[h] = 3 * (p[h - 1] + p[h]) / ((2 * p[h] + p[h - 1]) / n[h - 1] + (p[h] + 2 * p[h - 1]) / n[h]), isFinite(m[h]) || (m[h] = 0)); for (i = (new b.Svg.Path).move(j[0], k[0], !1, e[0]), h = 0; h < l - 1; h++)i.curve(j[h] + p[h] / 3, k[h] + m[h] * p[h] / 3, j[h + 1] - p[h] / 3, k[h + 1] - m[h + 1] * p[h] / 3, j[h + 1], k[h + 1], !1, e[h + 1]); return i } return b.Interpolation.none()([]) } }, b.Interpolation.step = function (a) { var c = { postpone: !0, fillHoles: !1 }; return a = b.extend({}, c, a), function (c, d) { for (var e, f, g, h = new b.Svg.Path, i = 0; i < c.length; i += 2) { var j = c[i], k = c[i + 1], l = d[i / 2]; void 0 !== l.value ? (void 0 === g ? h.move(j, k, !1, l) : (a.postpone ? h.line(j, f, !1, g) : h.line(e, k, !1, l), h.line(j, k, !1, l)), e = j, f = k, g = l) : a.fillHoles || (e = f = g = void 0) } return h } } }(this || global, a), function (a, b) { "use strict"; b.EventEmitter = function () { function a(a, b) { d[a] = d[a] || [], d[a].push(b) } function b(a, b) { d[a] && (b ? (d[a].splice(d[a].indexOf(b), 1), 0 === d[a].length && delete d[a]) : delete d[a]) } function c(a, b) { d[a] && d[a].forEach(function (a) { a(b) }), d["*"] && d["*"].forEach(function (c) { c(a, b) }) } var d = []; return { addEventHandler: a, removeEventHandler: b, emit: c } } }(this || global, a), function (a, b) { "use strict"; function c(a) { var b = []; if (a.length) for (var c = 0; c < a.length; c++)b.push(a[c]); return b } function d(a, c) { var d = c || this.prototype || b.Class, e = Object.create(d); b.Class.cloneDefinitions(e, a); var f = function () { var a, c = e.constructor || function () { }; return a = this === b ? Object.create(e) : this, c.apply(a, Array.prototype.slice.call(arguments, 0)), a }; return f.prototype = e, f["super"] = d, f.extend = this.extend, f } function e() { var a = c(arguments), b = a[0]; return a.splice(1, a.length - 1).forEach(function (a) { Object.getOwnPropertyNames(a).forEach(function (c) { delete b[c], Object.defineProperty(b, c, Object.getOwnPropertyDescriptor(a, c)) }) }), b } b.Class = { extend: d, cloneDefinitions: e } }(this || global, a), function (a, b) { "use strict"; function c(a, c, d) { return a && (this.data = a || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.eventEmitter.emit("data", { type: "update", data: this.data })), c && (this.options = b.extend({}, d ? this.options : this.defaultOptions, c), this.initializeTimeoutId || (this.optionsProvider.removeMediaQueryListeners(), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter))), this.initializeTimeoutId || this.createChart(this.optionsProvider.getCurrentOptions()), this } function d() { return this.initializeTimeoutId ? i.clearTimeout(this.initializeTimeoutId) : (i.removeEventListener("resize", this.resizeListener), this.optionsProvider.removeMediaQueryListeners()), this } function e(a, b) { return this.eventEmitter.addEventHandler(a, b), this } function f(a, b) { return this.eventEmitter.removeEventHandler(a, b), this } function g() { i.addEventListener("resize", this.resizeListener), this.optionsProvider = b.optionsProvider(this.options, this.responsiveOptions, this.eventEmitter), this.eventEmitter.addEventHandler("optionsChanged", function () { this.update() }.bind(this)), this.options.plugins && this.options.plugins.forEach(function (a) { a instanceof Array ? a[0](this, a[1]) : a(this) }.bind(this)), this.eventEmitter.emit("data", { type: "initial", data: this.data }), this.createChart(this.optionsProvider.getCurrentOptions()), this.initializeTimeoutId = void 0 } function h(a, c, d, e, f) { this.container = b.querySelector(a), this.data = c || {}, this.data.labels = this.data.labels || [], this.data.series = this.data.series || [], this.defaultOptions = d, this.options = e, this.responsiveOptions = f, this.eventEmitter = b.EventEmitter(), this.supportsForeignObject = b.Svg.isSupported("Extensibility"), this.supportsAnimations = b.Svg.isSupported("AnimationEventsAttribute"), this.resizeListener = function () { this.update() }.bind(this), this.container && (this.container.__chartist__ && this.container.__chartist__.detach(), this.container.__chartist__ = this), this.initializeTimeoutId = setTimeout(g.bind(this), 0) } var i = a.window; b.Base = b.Class.extend({ constructor: h, optionsProvider: void 0, container: void 0, svg: void 0, eventEmitter: void 0, createChart: function () { throw new Error("Base chart type can't be instantiated!") }, update: c, detach: d, on: e, off: f, version: b.version, supportsForeignObject: !1 }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f) { a instanceof Element ? this._node = a : (this._node = y.createElementNS(b.namespaces.svg, a), "svg" === a && this.attr({ "xmlns:ct": b.namespaces.ct })), c && this.attr(c), d && this.addClass(d), e && (f && e._node.firstChild ? e._node.insertBefore(this._node, e._node.firstChild) : e._node.appendChild(this._node)) } function d(a, c) { return "string" == typeof a ? c ? this._node.getAttributeNS(c, a) : this._node.getAttribute(a) : (Object.keys(a).forEach(function (c) { if (void 0 !== a[c]) if (c.indexOf(":") !== -1) { var d = c.split(":"); this._node.setAttributeNS(b.namespaces[d[0]], c, a[c]) } else this._node.setAttribute(c, a[c]) }.bind(this)), this) } function e(a, c, d, e) { return new b.Svg(a, c, d, this, e) } function f() { return this._node.parentNode instanceof SVGElement ? new b.Svg(this._node.parentNode) : null } function g() { for (var a = this._node; "svg" !== a.nodeName;)a = a.parentNode; return new b.Svg(a) } function h(a) { var c = this._node.querySelector(a); return c ? new b.Svg(c) : null } function i(a) { var c = this._node.querySelectorAll(a); return c.length ? new b.Svg.List(c) : null } function j() { return this._node } function k(a, c, d, e) { if ("string" == typeof a) { var f = y.createElement("div"); f.innerHTML = a, a = f.firstChild } a.setAttribute("xmlns", b.namespaces.xmlns); var g = this.elem("foreignObject", c, d, e); return g._node.appendChild(a), g } function l(a) { return this._node.appendChild(y.createTextNode(a)), this } function m() { for (; this._node.firstChild;)this._node.removeChild(this._node.firstChild); return this } function n() { return this._node.parentNode.removeChild(this._node), this.parent() } function o(a) { return this._node.parentNode.replaceChild(a._node, this._node), a } function p(a, b) { return b && this._node.firstChild ? this._node.insertBefore(a._node, this._node.firstChild) : this._node.appendChild(a._node), this } function q() { return this._node.getAttribute("class") ? this._node.getAttribute("class").trim().split(/\s+/) : [] } function r(a) { return this._node.setAttribute("class", this.classes(this._node).concat(a.trim().split(/\s+/)).filter(function (a, b, c) { return c.indexOf(a) === b }).join(" ")), this } function s(a) { var b = a.trim().split(/\s+/); return this._node.setAttribute("class", this.classes(this._node).filter(function (a) { return b.indexOf(a) === -1 }).join(" ")), this } function t() { return this._node.setAttribute("class", ""), this } function u() { return this._node.getBoundingClientRect().height } function v() { return this._node.getBoundingClientRect().width } function w(a, c, d) { return void 0 === c && (c = !0), Object.keys(a).forEach(function (e) { function f(a, c) { var f, g, h, i = {}; a.easing && (h = a.easing instanceof Array ? a.easing : b.Svg.Easing[a.easing], delete a.easing), a.begin = b.ensureUnit(a.begin, "ms"), a.dur = b.ensureUnit(a.dur, "ms"), h && (a.calcMode = "spline", a.keySplines = h.join(" "), a.keyTimes = "0;1"), c && (a.fill = "freeze", i[e] = a.from, this.attr(i), g = b.quantity(a.begin || 0).value, a.begin = "indefinite"), f = this.elem("animate", b.extend({ attributeName: e }, a)), c && setTimeout(function () { try { f._node.beginElement() } catch (b) { i[e] = a.to, this.attr(i), f.remove() } }.bind(this), g), d && f._node.addEventListener("beginEvent", function () { d.emit("animationBegin", { element: this, animate: f._node, params: a }) }.bind(this)), f._node.addEventListener("endEvent", function () { d && d.emit("animationEnd", { element: this, animate: f._node, params: a }), c && (i[e] = a.to, this.attr(i), f.remove()) }.bind(this)) } a[e] instanceof Array ? a[e].forEach(function (a) { f.bind(this)(a, !1) }.bind(this)) : f.bind(this)(a[e], c) }.bind(this)), this } function x(a) { var c = this; this.svgElements = []; for (var d = 0; d < a.length; d++)this.svgElements.push(new b.Svg(a[d])); Object.keys(b.Svg.prototype).filter(function (a) { return ["constructor", "parent", "querySelector", "querySelectorAll", "replace", "append", "classes", "height", "width"].indexOf(a) === -1 }).forEach(function (a) { c[a] = function () { var d = Array.prototype.slice.call(arguments, 0); return c.svgElements.forEach(function (c) { b.Svg.prototype[a].apply(c, d) }), c } }) } var y = a.document; b.Svg = b.Class.extend({ constructor: c, attr: d, elem: e, parent: f, root: g, querySelector: h, querySelectorAll: i, getNode: j, foreignObject: k, text: l, empty: m, remove: n, replace: o, append: p, classes: q, addClass: r, removeClass: s, removeAllClasses: t, height: u, width: v, animate: w }), b.Svg.isSupported = function (a) { return y.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#" + a, "1.1") }; var z = { easeInSine: [.47, 0, .745, .715], easeOutSine: [.39, .575, .565, 1], easeInOutSine: [.445, .05, .55, .95], easeInQuad: [.55, .085, .68, .53], easeOutQuad: [.25, .46, .45, .94], easeInOutQuad: [.455, .03, .515, .955], easeInCubic: [.55, .055, .675, .19], easeOutCubic: [.215, .61, .355, 1], easeInOutCubic: [.645, .045, .355, 1], easeInQuart: [.895, .03, .685, .22], easeOutQuart: [.165, .84, .44, 1], easeInOutQuart: [.77, 0, .175, 1], easeInQuint: [.755, .05, .855, .06], easeOutQuint: [.23, 1, .32, 1], easeInOutQuint: [.86, 0, .07, 1], easeInExpo: [.95, .05, .795, .035], easeOutExpo: [.19, 1, .22, 1], easeInOutExpo: [1, 0, 0, 1], easeInCirc: [.6, .04, .98, .335], easeOutCirc: [.075, .82, .165, 1], easeInOutCirc: [.785, .135, .15, .86], easeInBack: [.6, -.28, .735, .045], easeOutBack: [.175, .885, .32, 1.275], easeInOutBack: [.68, -.55, .265, 1.55] }; b.Svg.Easing = z, b.Svg.List = b.Class.extend({ constructor: x }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e, f, g) { var h = b.extend({ command: f ? a.toLowerCase() : a.toUpperCase() }, c, g ? { data: g } : {}); d.splice(e, 0, h) } function d(a, b) { a.forEach(function (c, d) { t[c.command.toLowerCase()].forEach(function (e, f) { b(c, e, d, f, a) }) }) } function e(a, c) { this.pathElements = [], this.pos = 0, this.close = a, this.options = b.extend({}, u, c) } function f(a) { return void 0 !== a ? (this.pos = Math.max(0, Math.min(this.pathElements.length, a)), this) : this.pos } function g(a) { return this.pathElements.splice(this.pos, a), this } function h(a, b, d, e) { return c("M", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function i(a, b, d, e) { return c("L", { x: +a, y: +b }, this.pathElements, this.pos++, d, e), this } function j(a, b, d, e, f, g, h, i) { return c("C", { x1: +a, y1: +b, x2: +d, y2: +e, x: +f, y: +g }, this.pathElements, this.pos++, h, i), this } function k(a, b, d, e, f, g, h, i, j) { return c("A", { rx: +a, ry: +b, xAr: +d, lAf: +e, sf: +f, x: +g, y: +h }, this.pathElements, this.pos++, i, j), this } function l(a) { var c = a.replace(/([A-Za-z])([0-9])/g, "$1 $2").replace(/([0-9])([A-Za-z])/g, "$1 $2").split(/[\s,]+/).reduce(function (a, b) { return b.match(/[A-Za-z]/) && a.push([]), a[a.length - 1].push(b), a }, []); "Z" === c[c.length - 1][0].toUpperCase() && c.pop(); var d = c.map(function (a) { var c = a.shift(), d = t[c.toLowerCase()]; return b.extend({ command: c }, d.reduce(function (b, c, d) { return b[c] = +a[d], b }, {})) }), e = [this.pos, 0]; return Array.prototype.push.apply(e, d), Array.prototype.splice.apply(this.pathElements, e), this.pos += d.length, this } function m() { var a = Math.pow(10, this.options.accuracy); return this.pathElements.reduce(function (b, c) { var d = t[c.command.toLowerCase()].map(function (b) { return this.options.accuracy ? Math.round(c[b] * a) / a : c[b] }.bind(this)); return b + c.command + d.join(",") }.bind(this), "") + (this.close ? "Z" : "") } function n(a, b) { return d(this.pathElements, function (c, d) { c[d] *= "x" === d[0] ? a : b }), this } function o(a, b) { return d(this.pathElements, function (c, d) { c[d] += "x" === d[0] ? a : b }), this } function p(a) { return d(this.pathElements, function (b, c, d, e, f) { var g = a(b, c, d, e, f); (g || 0 === g) && (b[c] = g) }), this } function q(a) { var c = new b.Svg.Path(a || this.close); return c.pos = this.pos, c.pathElements = this.pathElements.slice().map(function (a) { return b.extend({}, a) }), c.options = b.extend({}, this.options), c } function r(a) { var c = [new b.Svg.Path]; return this.pathElements.forEach(function (d) { d.command === a.toUpperCase() && 0 !== c[c.length - 1].pathElements.length && c.push(new b.Svg.Path), c[c.length - 1].pathElements.push(d) }), c } function s(a, c, d) { for (var e = new b.Svg.Path(c, d), f = 0; f < a.length; f++)for (var g = a[f], h = 0; h < g.pathElements.length; h++)e.pathElements.push(g.pathElements[h]); return e } var t = { m: ["x", "y"], l: ["x", "y"], c: ["x1", "y1", "x2", "y2", "x", "y"], a: ["rx", "ry", "xAr", "lAf", "sf", "x", "y"] }, u = { accuracy: 3 }; b.Svg.Path = b.Class.extend({ constructor: e, position: f, remove: g, move: h, line: i, curve: j, arc: k, scale: n, translate: o, transform: p, parse: l, stringify: m, clone: q, splitByCommand: r }), b.Svg.Path.elementDescriptions = t, b.Svg.Path.join = s }(this || global, a), function (a, b) { "use strict"; function c(a, b, c, d) { this.units = a, this.counterUnits = a === e.x ? e.y : e.x, this.chartRect = b, this.axisLength = b[a.rectEnd] - b[a.rectStart], this.gridOffset = b[a.rectOffset], this.ticks = c, this.options = d } function d(a, c, d, e, f) { var g = e["axis" + this.units.pos.toUpperCase()], h = this.ticks.map(this.projectValue.bind(this)), i = this.ticks.map(g.labelInterpolationFnc); h.forEach(function (j, k) { var l, m = { x: 0, y: 0 }; l = h[k + 1] ? h[k + 1] - j : Math.max(this.axisLength - j, 30), b.isFalseyButZero(i[k]) && "" !== i[k] || ("x" === this.units.pos ? (j = this.chartRect.x1 + j, m.x = e.axisX.labelOffset.x, "start" === e.axisX.position ? m.y = this.chartRect.padding.top + e.axisX.labelOffset.y + (d ? 5 : 20) : m.y = this.chartRect.y1 + e.axisX.labelOffset.y + (d ? 5 : 20)) : (j = this.chartRect.y1 - j, m.y = e.axisY.labelOffset.y - (d ? l : 0), "start" === e.axisY.position ? m.x = d ? this.chartRect.padding.left + e.axisY.labelOffset.x : this.chartRect.x1 - 10 : m.x = this.chartRect.x2 + e.axisY.labelOffset.x + 10), g.showGrid && b.createGrid(j, k, this, this.gridOffset, this.chartRect[this.counterUnits.len](), a, [e.classNames.grid, e.classNames[this.units.dir]], f), g.showLabel && b.createLabel(j, l, k, i, this, g.offset, m, c, [e.classNames.label, e.classNames[this.units.dir], "start" === g.position ? e.classNames[g.position] : e.classNames.end], d, f)) }.bind(this)) } var e = (a.window, a.document, { x: { pos: "x", len: "width", dir: "horizontal", rectStart: "x1", rectEnd: "x2", rectOffset: "y2" }, y: { pos: "y", len: "height", dir: "vertical", rectStart: "y2", rectEnd: "y1", rectOffset: "x1" } }); b.Axis = b.Class.extend({ constructor: c, createGridAndLabels: d, projectValue: function (a, b, c) { throw new Error("Base axis can't be instantiated!") } }), b.Axis.units = e }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.bounds = b.getBounds(d[a.rectEnd] - d[a.rectStart], f, e.scaleMinSpace || 20, e.onlyInteger), this.range = { min: this.bounds.min, max: this.bounds.max }, b.AutoScaleAxis["super"].constructor.call(this, a, d, this.bounds.values, e) } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.bounds.min) / this.bounds.range } a.window, a.document; b.AutoScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { var f = e.highLow || b.getHighLow(c, e, a.pos); this.divisor = e.divisor || 1, this.ticks = e.ticks || b.times(this.divisor).map(function (a, b) { return f.low + (f.high - f.low) / this.divisor * b }.bind(this)), this.ticks.sort(function (a, b) { return a - b }), this.range = { min: f.low, max: f.high }, b.FixedScaleAxis["super"].constructor.call(this, a, d, this.ticks, e), this.stepLength = this.axisLength / this.divisor } function d(a) { return this.axisLength * (+b.getMultiValue(a, this.units.pos) - this.range.min) / (this.range.max - this.range.min) } a.window, a.document; b.FixedScaleAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a, c, d, e) { b.StepAxis["super"].constructor.call(this, a, d, e.ticks, e); var f = Math.max(1, e.ticks.length - (e.stretch ? 1 : 0)); this.stepLength = this.axisLength / f } function d(a, b) { return this.stepLength * b } a.window, a.document; b.StepAxis = b.Axis.extend({ constructor: c, projectValue: d }) }(this || global, a), function (a, b) { "use strict"; function c(a) { var c = b.normalizeData(this.data, a.reverseData, !0); this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart); var d, f, g = this.svg.elem("g").addClass(a.classNames.gridGroup), h = this.svg.elem("g"), i = this.svg.elem("g").addClass(a.classNames.labelGroup), j = b.createChartRect(this.svg, a, e.padding); d = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, j, b.extend({}, a.axisX, { ticks: c.normalized.labels, stretch: a.fullWidth })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, j, a.axisX), f = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, j, b.extend({}, a.axisY, { high: b.isNumeric(a.high) ? a.high : a.axisY.high, low: b.isNumeric(a.low) ? a.low : a.axisY.low })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, j, a.axisY), d.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), f.createGridAndLabels(g, i, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(g, j, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (e, g) { var i = h.elem("g"); i.attr({ "ct:series-name": e.name, "ct:meta": b.serialize(e.meta) }), i.addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(g)].join(" ")); var k = [], l = []; c.normalized.series[g].forEach(function (a, h) { var i = { x: j.x1 + d.projectValue(a, h, c.normalized.series[g]), y: j.y1 - f.projectValue(a, h, c.normalized.series[g]) }; k.push(i.x, i.y), l.push({ value: a, valueIndex: h, meta: b.getMetaData(e, h) }) }.bind(this)); var m = { lineSmooth: b.getSeriesOption(e, a, "lineSmooth"), showPoint: b.getSeriesOption(e, a, "showPoint"), showLine: b.getSeriesOption(e, a, "showLine"), showArea: b.getSeriesOption(e, a, "showArea"), areaBase: b.getSeriesOption(e, a, "areaBase") }, n = "function" == typeof m.lineSmooth ? m.lineSmooth : m.lineSmooth ? b.Interpolation.monotoneCubic() : b.Interpolation.none(), o = n(k, l); if (m.showPoint && o.pathElements.forEach(function (c) { var h = i.elem("line", { x1: c.x, y1: c.y, x2: c.x + .01, y2: c.y }, a.classNames.point).attr({ "ct:value": [c.data.value.x, c.data.value.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(c.data.meta) }); this.eventEmitter.emit("draw", { type: "point", value: c.data.value, index: c.data.valueIndex, meta: c.data.meta, series: e, seriesIndex: g, axisX: d, axisY: f, group: i, element: h, x: c.x, y: c.y }) }.bind(this)), m.showLine) { var p = i.elem("path", { d: o.stringify() }, a.classNames.line, !0); this.eventEmitter.emit("draw", { type: "line", values: c.normalized.series[g], path: o.clone(), chartRect: j, index: g, series: e, seriesIndex: g, seriesMeta: e.meta, axisX: d, axisY: f, group: i, element: p }) } if (m.showArea && f.range) { var q = Math.max(Math.min(m.areaBase, f.range.max), f.range.min), r = j.y1 - f.projectValue(q); o.splitByCommand("M").filter(function (a) { return a.pathElements.length > 1 }).map(function (a) { var b = a.pathElements[0], c = a.pathElements[a.pathElements.length - 1]; return a.clone(!0).position(0).remove(1).move(b.x, r).line(b.x, b.y).position(a.pathElements.length + 1).line(c.x, r) }).forEach(function (b) { var h = i.elem("path", { d: b.stringify() }, a.classNames.area, !0); this.eventEmitter.emit("draw", { type: "area", values: c.normalized.series[g], path: b.clone(), series: e, seriesIndex: g, axisX: d, axisY: f, chartRect: j, index: g, group: i, element: h }) }.bind(this)) } }.bind(this)), this.eventEmitter.emit("created", { bounds: f.bounds, chartRect: j, axisX: d, axisY: f, svg: this.svg, options: a }) } function d(a, c, d, f) { b.Line["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, type: void 0, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, showLine: !0, showPoint: !0, showArea: !1, areaBase: 0, lineSmooth: !0, showGridBackground: !1, low: void 0, high: void 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, fullWidth: !1, reverseData: !1, classNames: { chart: "ct-chart-line", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", line: "ct-line", point: "ct-point", area: "ct-area", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Line = b.Base.extend({ constructor: d, createChart: c }) }(this || global, a), function (a, b) {
+        "use strict"; function c(a) {
+            var c, d; a.distributeSeries ? (c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), c.normalized.series = c.normalized.series.map(function (a) { return [a] })) : c = b.normalizeData(this.data, a.reverseData, a.horizontalBars ? "x" : "y"), this.svg = b.createSvg(this.container, a.width, a.height, a.classNames.chart + (a.horizontalBars ? " " + a.classNames.horizontalBars : "")); var f = this.svg.elem("g").addClass(a.classNames.gridGroup), g = this.svg.elem("g"), h = this.svg.elem("g").addClass(a.classNames.labelGroup);
+            if (a.stackBars && 0 !== c.normalized.series.length) { var i = b.serialMap(c.normalized.series, function () { return Array.prototype.slice.call(arguments).map(function (a) { return a }).reduce(function (a, b) { return { x: a.x + (b && b.x) || 0, y: a.y + (b && b.y) || 0 } }, { x: 0, y: 0 }) }); d = b.getHighLow([i], a, a.horizontalBars ? "x" : "y") } else d = b.getHighLow(c.normalized.series, a, a.horizontalBars ? "x" : "y"); d.high = +a.high || (0 === a.high ? 0 : d.high), d.low = +a.low || (0 === a.low ? 0 : d.low); var j, k, l, m, n, o = b.createChartRect(this.svg, a, e.padding); k = a.distributeSeries && a.stackBars ? c.normalized.labels.slice(0, 1) : c.normalized.labels, a.horizontalBars ? (j = m = void 0 === a.axisX.type ? new b.AutoScaleAxis(b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, b.extend({}, a.axisX, { highLow: d, referenceValue: 0 })), l = n = void 0 === a.axisY.type ? new b.StepAxis(b.Axis.units.y, c.normalized.series, o, { ticks: k }) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, a.axisY)) : (l = m = void 0 === a.axisX.type ? new b.StepAxis(b.Axis.units.x, c.normalized.series, o, { ticks: k }) : a.axisX.type.call(b, b.Axis.units.x, c.normalized.series, o, a.axisX), j = n = void 0 === a.axisY.type ? new b.AutoScaleAxis(b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 })) : a.axisY.type.call(b, b.Axis.units.y, c.normalized.series, o, b.extend({}, a.axisY, { highLow: d, referenceValue: 0 }))); var p = a.horizontalBars ? o.x1 + j.projectValue(0) : o.y1 - j.projectValue(0), q = []; l.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), j.createGridAndLabels(f, h, this.supportsForeignObject, a, this.eventEmitter), a.showGridBackground && b.createGridBackground(f, o, a.classNames.gridBackground, this.eventEmitter), c.raw.series.forEach(function (d, e) { var f, h, i = e - (c.raw.series.length - 1) / 2; f = a.distributeSeries && !a.stackBars ? l.axisLength / c.normalized.series.length / 2 : a.distributeSeries && a.stackBars ? l.axisLength / 2 : l.axisLength / c.normalized.series[e].length / 2, h = g.elem("g"), h.attr({ "ct:series-name": d.name, "ct:meta": b.serialize(d.meta) }), h.addClass([a.classNames.series, d.className || a.classNames.series + "-" + b.alphaNumerate(e)].join(" ")), c.normalized.series[e].forEach(function (g, k) { var r, s, t, u; if (u = a.distributeSeries && !a.stackBars ? e : a.distributeSeries && a.stackBars ? 0 : k, r = a.horizontalBars ? { x: o.x1 + j.projectValue(g && g.x ? g.x : 0, k, c.normalized.series[e]), y: o.y1 - l.projectValue(g && g.y ? g.y : 0, u, c.normalized.series[e]) } : { x: o.x1 + l.projectValue(g && g.x ? g.x : 0, u, c.normalized.series[e]), y: o.y1 - j.projectValue(g && g.y ? g.y : 0, k, c.normalized.series[e]) }, l instanceof b.StepAxis && (l.options.stretch || (r[l.units.pos] += f * (a.horizontalBars ? -1 : 1)), r[l.units.pos] += a.stackBars || a.distributeSeries ? 0 : i * a.seriesBarDistance * (a.horizontalBars ? -1 : 1)), t = q[k] || p, q[k] = t - (p - r[l.counterUnits.pos]), void 0 !== g) { var v = {}; v[l.units.pos + "1"] = r[l.units.pos], v[l.units.pos + "2"] = r[l.units.pos], !a.stackBars || "accumulate" !== a.stackMode && a.stackMode ? (v[l.counterUnits.pos + "1"] = p, v[l.counterUnits.pos + "2"] = r[l.counterUnits.pos]) : (v[l.counterUnits.pos + "1"] = t, v[l.counterUnits.pos + "2"] = q[k]), v.x1 = Math.min(Math.max(v.x1, o.x1), o.x2), v.x2 = Math.min(Math.max(v.x2, o.x1), o.x2), v.y1 = Math.min(Math.max(v.y1, o.y2), o.y1), v.y2 = Math.min(Math.max(v.y2, o.y2), o.y1); var w = b.getMetaData(d, k); s = h.elem("line", v, a.classNames.bar).attr({ "ct:value": [g.x, g.y].filter(b.isNumeric).join(","), "ct:meta": b.serialize(w) }), this.eventEmitter.emit("draw", b.extend({ type: "bar", value: g, index: k, meta: w, series: d, seriesIndex: e, axisX: m, axisY: n, chartRect: o, group: h, element: s }, v)) } }.bind(this)) }.bind(this)), this.eventEmitter.emit("created", { bounds: j.bounds, chartRect: o, axisX: m, axisY: n, svg: this.svg, options: a })
+        } function d(a, c, d, f) { b.Bar["super"].constructor.call(this, a, c, e, b.extend({}, e, d), f) } var e = (a.window, a.document, { axisX: { offset: 30, position: "end", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 30, onlyInteger: !1 }, axisY: { offset: 40, position: "start", labelOffset: { x: 0, y: 0 }, showLabel: !0, showGrid: !0, labelInterpolationFnc: b.noop, scaleMinSpace: 20, onlyInteger: !1 }, width: void 0, height: void 0, high: void 0, low: void 0, referenceValue: 0, chartPadding: { top: 15, right: 15, bottom: 5, left: 10 }, seriesBarDistance: 15, stackBars: !1, stackMode: "accumulate", horizontalBars: !1, distributeSeries: !1, reverseData: !1, showGridBackground: !1, classNames: { chart: "ct-chart-bar", horizontalBars: "ct-horizontal-bars", label: "ct-label", labelGroup: "ct-labels", series: "ct-series", bar: "ct-bar", grid: "ct-grid", gridGroup: "ct-grids", gridBackground: "ct-grid-background", vertical: "ct-vertical", horizontal: "ct-horizontal", start: "ct-start", end: "ct-end" } }); b.Bar = b.Base.extend({ constructor: d, createChart: c })
+    }(this || global, a), function (a, b) { "use strict"; function c(a, b, c) { var d = b.x > a.x; return d && "explode" === c || !d && "implode" === c ? "start" : d && "implode" === c || !d && "explode" === c ? "end" : "middle" } function d(a) { var d, e, g, h, i, j = b.normalizeData(this.data), k = [], l = a.startAngle; this.svg = b.createSvg(this.container, a.width, a.height, a.donut ? a.classNames.chartDonut : a.classNames.chartPie), e = b.createChartRect(this.svg, a, f.padding), g = Math.min(e.width() / 2, e.height() / 2), i = a.total || j.normalized.series.reduce(function (a, b) { return a + b }, 0); var m = b.quantity(a.donutWidth); "%" === m.unit && (m.value *= g / 100), g -= a.donut && !a.donutSolid ? m.value / 2 : 0, h = "outside" === a.labelPosition || a.donut && !a.donutSolid ? g : "center" === a.labelPosition ? 0 : a.donutSolid ? g - m.value / 2 : g / 2, h += a.labelOffset; var n = { x: e.x1 + e.width() / 2, y: e.y2 + e.height() / 2 }, o = 1 === j.raw.series.filter(function (a) { return a.hasOwnProperty("value") ? 0 !== a.value : 0 !== a }).length; j.raw.series.forEach(function (a, b) { k[b] = this.svg.elem("g", null, null) }.bind(this)), a.showLabel && (d = this.svg.elem("g", null, null)), j.raw.series.forEach(function (e, f) { if (0 !== j.normalized.series[f] || !a.ignoreEmptyValues) { k[f].attr({ "ct:series-name": e.name }), k[f].addClass([a.classNames.series, e.className || a.classNames.series + "-" + b.alphaNumerate(f)].join(" ")); var p = i > 0 ? l + j.normalized.series[f] / i * 360 : 0, q = Math.max(0, l - (0 === f || o ? 0 : .2)); p - q >= 359.99 && (p = q + 359.99); var r, s, t, u = b.polarToCartesian(n.x, n.y, g, q), v = b.polarToCartesian(n.x, n.y, g, p), w = new b.Svg.Path(!a.donut || a.donutSolid).move(v.x, v.y).arc(g, g, 0, p - l > 180, 0, u.x, u.y); a.donut ? a.donutSolid && (t = g - m.value, r = b.polarToCartesian(n.x, n.y, t, l - (0 === f || o ? 0 : .2)), s = b.polarToCartesian(n.x, n.y, t, p), w.line(r.x, r.y), w.arc(t, t, 0, p - l > 180, 1, s.x, s.y)) : w.line(n.x, n.y); var x = a.classNames.slicePie; a.donut && (x = a.classNames.sliceDonut, a.donutSolid && (x = a.classNames.sliceDonutSolid)); var y = k[f].elem("path", { d: w.stringify() }, x); if (y.attr({ "ct:value": j.normalized.series[f], "ct:meta": b.serialize(e.meta) }), a.donut && !a.donutSolid && (y._node.style.strokeWidth = m.value + "px"), this.eventEmitter.emit("draw", { type: "slice", value: j.normalized.series[f], totalDataSum: i, index: f, meta: e.meta, series: e, group: k[f], element: y, path: w.clone(), center: n, radius: g, startAngle: l, endAngle: p }), a.showLabel) { var z; z = 1 === j.raw.series.length ? { x: n.x, y: n.y } : b.polarToCartesian(n.x, n.y, h, l + (p - l) / 2); var A; A = j.normalized.labels && !b.isFalseyButZero(j.normalized.labels[f]) ? j.normalized.labels[f] : j.normalized.series[f]; var B = a.labelInterpolationFnc(A, f); if (B || 0 === B) { var C = d.elem("text", { dx: z.x, dy: z.y, "text-anchor": c(n, z, a.labelDirection) }, a.classNames.label).text("" + B); this.eventEmitter.emit("draw", { type: "label", index: f, group: d, element: C, text: "" + B, x: z.x, y: z.y }) } } l = p } }.bind(this)), this.eventEmitter.emit("created", { chartRect: e, svg: this.svg, options: a }) } function e(a, c, d, e) { b.Pie["super"].constructor.call(this, a, c, f, b.extend({}, f, d), e) } var f = (a.window, a.document, { width: void 0, height: void 0, chartPadding: 5, classNames: { chartPie: "ct-chart-pie", chartDonut: "ct-chart-donut", series: "ct-series", slicePie: "ct-slice-pie", sliceDonut: "ct-slice-donut", sliceDonutSolid: "ct-slice-donut-solid", label: "ct-label" }, startAngle: 0, total: void 0, donut: !1, donutSolid: !1, donutWidth: 60, showLabel: !0, labelOffset: 0, labelPosition: "inside", labelInterpolationFnc: b.noop, labelDirection: "neutral", reverseData: !1, ignoreEmptyValues: !1 }); b.Pie = b.Base.extend({ constructor: e, createChart: d, determineAnchorPosition: c }) }(this || global, a), a
+});
+//# sourceMappingURL=chartist.min.js.map
+
+var i, l, selectedLine = null;
+
+/* Navigate to hash without browser history entry */
+var navigateToHash = function () {
+    if (window.history !== undefined && window.history.replaceState !== undefined) {
+        window.history.replaceState(undefined, undefined, this.getAttribute("href"));
+    }
+};
+
+var hashLinks = document.getElementsByClassName('navigatetohash');
+for (i = 0, l = hashLinks.length; i < l; i++) {
+    hashLinks[i].addEventListener('click', navigateToHash);
+}
+
+/* Switch test method */
+var switchTestMethod = function () {
+    var method = this.getAttribute("value");
+    console.log("Selected test method: " + method);
+
+    var lines, i, l, coverageData, lineAnalysis, cells;
+
+    lines = document.querySelectorAll('.lineAnalysis tr');
+
+    for (i = 1, l = lines.length; i < l; i++) {
+        coverageData = JSON.parse(lines[i].getAttribute('data-coverage').replace(/'/g, '"'));
+        lineAnalysis = coverageData[method];
+        cells = lines[i].querySelectorAll('td');
+        if (lineAnalysis === undefined) {
+            lineAnalysis = coverageData.AllTestMethods;
+            if (lineAnalysis.LVS !== 'gray') {
+                cells[0].setAttribute('class', 'red');
+                cells[1].innerText = cells[1].textContent = '0';
+                cells[4].setAttribute('class', 'lightred');
+            }
+        } else {
+            cells[0].setAttribute('class', lineAnalysis.LVS);
+            cells[1].innerText = cells[1].textContent = lineAnalysis.VC;
+            cells[4].setAttribute('class', 'light' + lineAnalysis.LVS);
+        }
+    }
+};
+
+var testMethods = document.getElementsByClassName('switchtestmethod');
+for (i = 0, l = testMethods.length; i < l; i++) {
+    testMethods[i].addEventListener('change', switchTestMethod);
+}
+
+/* Highlight test method by line */
+var toggleLine = function () {
+    if (selectedLine === this) {
+        selectedLine = null;
+    } else {
+        selectedLine = null;
+        unhighlightTestMethods();
+        highlightTestMethods.call(this);
+        selectedLine = this;
+    }
+    
+};
+var highlightTestMethods = function () {
+    if (selectedLine !== null) {
+        return;
+    }
+
+    var lineAnalysis;
+    var coverageData = JSON.parse(this.getAttribute('data-coverage').replace(/'/g, '"'));
+    var testMethods = document.getElementsByClassName('testmethod');
+
+    for (i = 0, l = testMethods.length; i < l; i++) {
+        lineAnalysis = coverageData[testMethods[i].id];
+        if (lineAnalysis === undefined) {
+            testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, "");
+        } else {
+            testMethods[i].className += ' light' + lineAnalysis.LVS;
+        }
+    }
+};
+var unhighlightTestMethods = function () {
+    if (selectedLine !== null) {
+        return;
+    }
+
+    var testMethods = document.getElementsByClassName('testmethod');
+    for (i = 0, l = testMethods.length; i < l; i++) {
+        testMethods[i].className = testMethods[i].className.replace(/\s*light.+/g, "");
+    }
+};
+var coverableLines = document.getElementsByClassName('coverableline');
+for (i = 0, l = coverableLines.length; i < l; i++) {
+    coverableLines[i].addEventListener('click', toggleLine);
+    coverableLines[i].addEventListener('mouseenter', highlightTestMethods);
+    coverableLines[i].addEventListener('mouseleave', unhighlightTestMethods);
+}
+
+/* History charts */
+var renderChart = function (chart) {
+    // Remove current children (e.g. PNG placeholder)
+    while (chart.firstChild) {
+        chart.firstChild.remove();
+    }
+
+    var chartData = window[chart.getAttribute('data-data')];
+    var options = {
+        axisY: {
+            type: undefined,
+            onlyInteger: true
+        },
+        lineSmooth: false,
+        low: 0,
+        high: 100,
+        scaleMinSpace: 20,
+        onlyInteger: true,
+        fullWidth: true
+    };
+    var lineChart = new Chartist.Line(chart, {
+        labels: [],
+        series: chartData.series
+    }, options);
+
+    /* Zoom */
+    var zoomButtonDiv = document.createElement("div");
+    zoomButtonDiv.className = "toggleZoom";
+    var zoomButtonLink = document.createElement("a");
+    zoomButtonLink.setAttribute("href", "");
+    var zoomButtonText = document.createElement("i");
+    zoomButtonText.className = "icon-search-plus";
+
+    zoomButtonLink.appendChild(zoomButtonText);
+    zoomButtonDiv.appendChild(zoomButtonLink);
+
+    chart.appendChild(zoomButtonDiv);
+
+    zoomButtonDiv.addEventListener('click', function (event) {
+        event.preventDefault();
+
+        if (options.axisY.type === undefined) {
+            options.axisY.type = Chartist.AutoScaleAxis;
+            zoomButtonText.className = "icon-search-minus";
+        } else {
+            options.axisY.type = undefined;
+            zoomButtonText.className = "icon-search-plus";
+        }
+
+        lineChart.update(null, options);
+    });
+
+    var tooltip = document.createElement("div");
+    tooltip.className = "tooltip";
+
+    chart.appendChild(tooltip);
+
+    /* Tooltips */
+    var showToolTip = function () {
+        var index = this.getAttribute('ct:meta');
+
+        tooltip.innerHTML = chartData.tooltips[index];
+        tooltip.style.display = 'block';
+    };
+
+    var moveToolTip = function (event) {
+        var box = chart.getBoundingClientRect();
+        var left = event.pageX - box.left - window.pageXOffset;
+        var top = event.pageY - box.top - window.pageYOffset;
+
+        left = left + 20;
+        top = top - tooltip.offsetHeight / 2;
+
+        if (left + tooltip.offsetWidth > box.width) {
+            left -= tooltip.offsetWidth + 40;
+        }
+
+        if (top < 0) {
+            top = 0;
+        }
+
+        if (top + tooltip.offsetHeight > box.height) {
+            top = box.height - tooltip.offsetHeight;
+        }
+
+        tooltip.style.left = left + 'px';
+        tooltip.style.top = top + 'px';
+    };
+
+    var hideToolTip = function () {
+        tooltip.style.display = 'none';
+    };
+    chart.addEventListener('mousemove', moveToolTip);
+
+    lineChart.on('created', function () {
+        var chartPoints = chart.getElementsByClassName('ct-point');
+        for (i = 0, l = chartPoints.length; i < l; i++) {
+            chartPoints[i].addEventListener('mousemove', showToolTip);
+            chartPoints[i].addEventListener('mouseout', hideToolTip);
+        }
+    });
+};
+
+var charts = document.getElementsByClassName('historychart');
+for (i = 0, l = charts.length; i < l; i++) {
+    renderChart(charts[i]);
+}
+
+var assemblies = [
+  {
+    "name": "ldclient.dll",
+    "classes": [
+      { "name": "LDClient.detection.DebuggerInfoParser", "rp": "ldclient.dll_DebuggerInfoParser.html", "cl": 7, "ucl": 0, "cal": 7, "tl": 21, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.detection.InfoFetcher", "rp": "ldclient.dll_InfoFetcher.html", "cl": 52, "ucl": 0, "cal": 52, "tl": 86, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.detection.ProcessDetection", "rp": "ldclient.dll_ProcessDetection.html", "cl": 62, "ucl": 0, "cal": 62, "tl": 91, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.detection.ProcessUtils", "rp": "ldclient.dll_ProcessUtils.html", "cl": 0, "ucl": 20, "cal": 20, "tl": 40, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.network.ApiClient", "rp": "ldclient.dll_ApiClient.html", "cl": 75, "ucl": 0, "cal": 75, "tl": 108, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.network.data.DebuggerInfo", "rp": "ldclient.dll_DebuggerInfo.html", "cl": 1, "ucl": 0, "cal": 1, "tl": 9, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.network.data.Payload", "rp": "ldclient.dll_Payload.html", "cl": 17, "ucl": 3, "cal": 20, "tl": 49, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.network.HttpClient", "rp": "ldclient.dll_HttpClient.html", "cl": 4, "ucl": 7, "cal": 11, "tl": 32, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.Program", "rp": "ldclient.dll_Program.html", "cl": 11, "ucl": 32, "cal": 43, "tl": 67, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.utils.ConfigLoader", "rp": "ldclient.dll_ConfigLoader.html", "cl": 74, "ucl": 12, "cal": 86, "tl": 127, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.utils.FileUtils", "rp": "ldclient.dll_FileUtils.html", "cl": 0, "ucl": 3, "cal": 3, "tl": 13, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.utils.loggers.ALogger", "rp": "ldclient.dll_ALogger.html", "cl": 58, "ucl": 14, "cal": 72, "tl": 109, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.utils.loggers.ConsoleLogger", "rp": "ldclient.dll_ConsoleLogger.html", "cl": 3, "ucl": 0, "cal": 3, "tl": 7, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClient.utils.loggers.FileLogger", "rp": "ldclient.dll_FileLogger.html", "cl": 0, "ucl": 59, "cal": 59, "tl": 95, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+    ]},
+  {
+    "name": "ldclienttests.dll",
+    "classes": [
+      { "name": "LDClientTests.detection.DebuggerInfoParserTests", "rp": "ldclienttests.dll_DebuggerInfoParserTests.html", "cl": 18, "ucl": 0, "cal": 18, "tl": 66, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClientTests.detection.InfoFetcherTests", "rp": "ldclienttests.dll_InfoFetcherTests.html", "cl": 59, "ucl": 0, "cal": 59, "tl": 117, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClientTests.detection.ProcessDetectionTests", "rp": "ldclienttests.dll_ProcessDetectionTests.html", "cl": 61, "ucl": 0, "cal": 61, "tl": 132, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+      { "name": "LDClientTests.network.ApiClientTests", "rp": "ldclienttests.dll_ApiClientTests.html", "cl": 81, "ucl": 0, "cal": 81, "tl": 167, "ct": "LineCoverage", "cbm": "-", "cb": 0, "tb": 0, "cm": 0, "tm": 0, "lch": [], "bch": [], "mch": [], "hc": [] },
+    ]},
+];
+
+var historicCoverageExecutionTimes = [];
+
+var riskHotspotMetrics = [
+];
+
+var riskHotspots = [
+];
+
+var branchCoverageAvailable = false;
+var methodCoverageAvailable = false;
+
+
+var translations = {
+'top': 'Top:',
+'all': 'All',
+'assembly': 'Assembly',
+'class': 'Class',
+'method': 'Method',
+'lineCoverage': 'LineCoverage',
+'noGrouping': 'No grouping',
+'byAssembly': 'By assembly',
+'byNamespace': 'By namespace, Level:',
+'all': 'All',
+'collapseAll': 'Collapse all',
+'expandAll': 'Expand all',
+'grouping': 'Grouping:',
+'filter': 'Filter:',
+'name': 'Name',
+'covered': 'Covered',
+'uncovered': 'Uncovered',
+'coverable': 'Coverable',
+'total': 'Total',
+'coverage': 'Line coverage',
+'branchCoverage': 'Branch coverage',
+'methodCoverage': 'Method coverage',
+'percentage': 'Percentage',
+'history': 'Coverage History',
+'compareHistory': 'Compare with:',
+'date': 'Date',
+'allChanges': 'All changes',
+'lineCoverageIncreaseOnly': 'Line coverage: Increase only',
+'lineCoverageDecreaseOnly': 'Line coverage: Decrease only',
+'branchCoverageIncreaseOnly': 'Branch coverage: Increase only',
+'branchCoverageDecreaseOnly': 'Branch coverage: Decrease only',
+'methodCoverageIncreaseOnly': 'Method coverage: Increase only',
+'methodCoverageDecreaseOnly': 'Method coverage: Decrease only'
+};
+
+
+(()=>{"use strict";var e,_={},p={};function n(e){var a=p[e];if(void 0!==a)return a.exports;var r=p[e]={exports:{}};return _[e](r,r.exports,n),r.exports}n.m=_,e=[],n.O=(a,r,u,l)=>{if(!r){var o=1/0;for(f=0;f<e.length;f++){for(var[r,u,l]=e[f],v=!0,t=0;t<r.length;t++)(!1&l||o>=l)&&Object.keys(n.O).every(h=>n.O[h](r[t]))?r.splice(t--,1):(v=!1,l<o&&(o=l));if(v){e.splice(f--,1);var c=u();void 0!==c&&(a=c)}}return a}l=l||0;for(var f=e.length;f>0&&e[f-1][2]>l;f--)e[f]=e[f-1];e[f]=[r,u,l]},n.n=e=>{var a=e&&e.__esModule?()=>e.default:()=>e;return n.d(a,{a}),a},n.d=(e,a)=>{for(var r in a)n.o(a,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:a[r]})},n.o=(e,a)=>Object.prototype.hasOwnProperty.call(e,a),(()=>{var e={666:0};n.O.j=u=>0===e[u];var a=(u,l)=>{var t,c,[f,o,v]=l,s=0;if(f.some(d=>0!==e[d])){for(t in o)n.o(o,t)&&(n.m[t]=o[t]);if(v)var b=v(n)}for(u&&u(l);s<f.length;s++)n.o(e,c=f[s])&&e[c]&&e[c][0](),e[c]=0;return n.O(b)},r=self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[];r.forEach(a.bind(null,0)),r.push=a.bind(null,r.push.bind(r))})()})();
+"use strict";(self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[]).push([[429],{435:(we,ue,he)=>{he(583)},583:()=>{!function(e){const n=e.performance;function i(I){n&&n.mark&&n.mark(I)}function r(I,p){n&&n.measure&&n.measure(I,p)}i("Zone");const c=e.__Zone_symbol_prefix||"__zone_symbol__";function u(I){return c+I}const f=!0===e[u("forceDuplicateZoneCheck")];if(e.Zone){if(f||"function"!=typeof e.Zone.__symbol__)throw new Error("Zone already loaded.");return e.Zone}let _=(()=>{class I{constructor(t,o){this._parent=t,this._name=o?o.name||"unnamed":"<root>",this._properties=o&&o.properties||{},this._zoneDelegate=new T(this,this._parent&&this._parent._zoneDelegate,o)}static assertZonePatched(){if(e.Promise!==J.ZoneAwarePromise)throw new Error("Zone.js has detected that ZoneAwarePromise `(window|global).Promise` has been overwritten.\nMost likely cause is that a Promise polyfill has been loaded after Zone.js (Polyfilling Promise api is not necessary when zone.js is loaded. If you must load one, do so before loading zone.js.)")}static get root(){let t=I.current;for(;t.parent;)t=t.parent;return t}static get current(){return G.zone}static get currentTask(){return te}static __load_patch(t,o,g=!1){if(J.hasOwnProperty(t)){if(!g&&f)throw Error("Already loaded patch: "+t)}else if(!e["__Zone_disable_"+t]){const P="Zone:"+t;i(P),J[t]=o(e,I,le),r(P,P)}}get parent(){return this._parent}get name(){return this._name}get(t){const o=this.getZoneWith(t);if(o)return o._properties[t]}getZoneWith(t){let o=this;for(;o;){if(o._properties.hasOwnProperty(t))return o;o=o._parent}return null}fork(t){if(!t)throw new Error("ZoneSpec required!");return this._zoneDelegate.fork(this,t)}wrap(t,o){if("function"!=typeof t)throw new Error("Expecting function got: "+t);const g=this._zoneDelegate.intercept(this,t,o),P=this;return function(){return P.runGuarded(g,this,arguments,o)}}run(t,o,g,P){G={parent:G,zone:this};try{return this._zoneDelegate.invoke(this,t,o,g,P)}finally{G=G.parent}}runGuarded(t,o=null,g,P){G={parent:G,zone:this};try{try{return this._zoneDelegate.invoke(this,t,o,g,P)}catch(K){if(this._zoneDelegate.handleError(this,K))throw K}}finally{G=G.parent}}runTask(t,o,g){if(t.zone!=this)throw new Error("A task can only be run in the zone of creation! (Creation: "+(t.zone||z).name+"; Execution: "+this.name+")");if(t.state===j&&(t.type===R||t.type===M))return;const P=t.state!=X;P&&t._transitionTo(X,O),t.runCount++;const K=te;te=t,G={parent:G,zone:this};try{t.type==M&&t.data&&!t.data.isPeriodic&&(t.cancelFn=void 0);try{return this._zoneDelegate.invokeTask(this,t,o,g)}catch(l){if(this._zoneDelegate.handleError(this,l))throw l}}finally{t.state!==j&&t.state!==Y&&(t.type==R||t.data&&t.data.isPeriodic?P&&t._transitionTo(O,X):(t.runCount=0,this._updateTaskCount(t,-1),P&&t._transitionTo(j,X,j))),G=G.parent,te=K}}scheduleTask(t){if(t.zone&&t.zone!==this){let g=this;for(;g;){if(g===t.zone)throw Error(`can not reschedule task to ${this.name} which is descendants of the original zone ${t.zone.name}`);g=g.parent}}t._transitionTo(q,j);const o=[];t._zoneDelegates=o,t._zone=this;try{t=this._zoneDelegate.scheduleTask(this,t)}catch(g){throw t._transitionTo(Y,q,j),this._zoneDelegate.handleError(this,g),g}return t._zoneDelegates===o&&this._updateTaskCount(t,1),t.state==q&&t._transitionTo(O,q),t}scheduleMicroTask(t,o,g,P){return this.scheduleTask(new m(v,t,o,g,P,void 0))}scheduleMacroTask(t,o,g,P,K){return this.scheduleTask(new m(M,t,o,g,P,K))}scheduleEventTask(t,o,g,P,K){return this.scheduleTask(new m(R,t,o,g,P,K))}cancelTask(t){if(t.zone!=this)throw new Error("A task can only be cancelled in the zone of creation! (Creation: "+(t.zone||z).name+"; Execution: "+this.name+")");t._transitionTo(A,O,X);try{this._zoneDelegate.cancelTask(this,t)}catch(o){throw t._transitionTo(Y,A),this._zoneDelegate.handleError(this,o),o}return this._updateTaskCount(t,-1),t._transitionTo(j,A),t.runCount=0,t}_updateTaskCount(t,o){const g=t._zoneDelegates;-1==o&&(t._zoneDelegates=null);for(let P=0;P<g.length;P++)g[P]._updateTaskCount(t.type,o)}}return I.__symbol__=u,I})();const y={name:"",onHasTask:(I,p,t,o)=>I.hasTask(t,o),onScheduleTask:(I,p,t,o)=>I.scheduleTask(t,o),onInvokeTask:(I,p,t,o,g,P)=>I.invokeTask(t,o,g,P),onCancelTask:(I,p,t,o)=>I.cancelTask(t,o)};class T{constructor(p,t,o){this._taskCounts={microTask:0,macroTask:0,eventTask:0},this.zone=p,this._parentDelegate=t,this._forkZS=o&&(o&&o.onFork?o:t._forkZS),this._forkDlgt=o&&(o.onFork?t:t._forkDlgt),this._forkCurrZone=o&&(o.onFork?this.zone:t._forkCurrZone),this._interceptZS=o&&(o.onIntercept?o:t._interceptZS),this._interceptDlgt=o&&(o.onIntercept?t:t._interceptDlgt),this._interceptCurrZone=o&&(o.onIntercept?this.zone:t._interceptCurrZone),this._invokeZS=o&&(o.onInvoke?o:t._invokeZS),this._invokeDlgt=o&&(o.onInvoke?t:t._invokeDlgt),this._invokeCurrZone=o&&(o.onInvoke?this.zone:t._invokeCurrZone),this._handleErrorZS=o&&(o.onHandleError?o:t._handleErrorZS),this._handleErrorDlgt=o&&(o.onHandleError?t:t._handleErrorDlgt),this._handleErrorCurrZone=o&&(o.onHandleError?this.zone:t._handleErrorCurrZone),this._scheduleTaskZS=o&&(o.onScheduleTask?o:t._scheduleTaskZS),this._scheduleTaskDlgt=o&&(o.onScheduleTask?t:t._scheduleTaskDlgt),this._scheduleTaskCurrZone=o&&(o.onScheduleTask?this.zone:t._scheduleTaskCurrZone),this._invokeTaskZS=o&&(o.onInvokeTask?o:t._invokeTaskZS),this._invokeTaskDlgt=o&&(o.onInvokeTask?t:t._invokeTaskDlgt),this._invokeTaskCurrZone=o&&(o.onInvokeTask?this.zone:t._invokeTaskCurrZone),this._cancelTaskZS=o&&(o.onCancelTask?o:t._cancelTaskZS),this._cancelTaskDlgt=o&&(o.onCancelTask?t:t._cancelTaskDlgt),this._cancelTaskCurrZone=o&&(o.onCancelTask?this.zone:t._cancelTaskCurrZone),this._hasTaskZS=null,this._hasTaskDlgt=null,this._hasTaskDlgtOwner=null,this._hasTaskCurrZone=null;const g=o&&o.onHasTask;(g||t&&t._hasTaskZS)&&(this._hasTaskZS=g?o:y,this._hasTaskDlgt=t,this._hasTaskDlgtOwner=this,this._hasTaskCurrZone=p,o.onScheduleTask||(this._scheduleTaskZS=y,this._scheduleTaskDlgt=t,this._scheduleTaskCurrZone=this.zone),o.onInvokeTask||(this._invokeTaskZS=y,this._invokeTaskDlgt=t,this._invokeTaskCurrZone=this.zone),o.onCancelTask||(this._cancelTaskZS=y,this._cancelTaskDlgt=t,this._cancelTaskCurrZone=this.zone))}fork(p,t){return this._forkZS?this._forkZS.onFork(this._forkDlgt,this.zone,p,t):new _(p,t)}intercept(p,t,o){return this._interceptZS?this._interceptZS.onIntercept(this._interceptDlgt,this._interceptCurrZone,p,t,o):t}invoke(p,t,o,g,P){return this._invokeZS?this._invokeZS.onInvoke(this._invokeDlgt,this._invokeCurrZone,p,t,o,g,P):t.apply(o,g)}handleError(p,t){return!this._handleErrorZS||this._handleErrorZS.onHandleError(this._handleErrorDlgt,this._handleErrorCurrZone,p,t)}scheduleTask(p,t){let o=t;if(this._scheduleTaskZS)this._hasTaskZS&&o._zoneDelegates.push(this._hasTaskDlgtOwner),o=this._scheduleTaskZS.onScheduleTask(this._scheduleTaskDlgt,this._scheduleTaskCurrZone,p,t),o||(o=t);else if(t.scheduleFn)t.scheduleFn(t);else{if(t.type!=v)throw new Error("Task is missing scheduleFn.");d(t)}return o}invokeTask(p,t,o,g){return this._invokeTaskZS?this._invokeTaskZS.onInvokeTask(this._invokeTaskDlgt,this._invokeTaskCurrZone,p,t,o,g):t.callback.apply(o,g)}cancelTask(p,t){let o;if(this._cancelTaskZS)o=this._cancelTaskZS.onCancelTask(this._cancelTaskDlgt,this._cancelTaskCurrZone,p,t);else{if(!t.cancelFn)throw Error("Task is not cancelable");o=t.cancelFn(t)}return o}hasTask(p,t){try{this._hasTaskZS&&this._hasTaskZS.onHasTask(this._hasTaskDlgt,this._hasTaskCurrZone,p,t)}catch(o){this.handleError(p,o)}}_updateTaskCount(p,t){const o=this._taskCounts,g=o[p],P=o[p]=g+t;if(P<0)throw new Error("More tasks executed then were scheduled.");0!=g&&0!=P||this.hasTask(this.zone,{microTask:o.microTask>0,macroTask:o.macroTask>0,eventTask:o.eventTask>0,change:p})}}class m{constructor(p,t,o,g,P,K){if(this._zone=null,this.runCount=0,this._zoneDelegates=null,this._state="notScheduled",this.type=p,this.source=t,this.data=g,this.scheduleFn=P,this.cancelFn=K,!o)throw new Error("callback is not defined");this.callback=o;const l=this;this.invoke=p===R&&g&&g.useG?m.invokeTask:function(){return m.invokeTask.call(e,l,this,arguments)}}static invokeTask(p,t,o){p||(p=this),re++;try{return p.runCount++,p.zone.runTask(p,t,o)}finally{1==re&&L(),re--}}get zone(){return this._zone}get state(){return this._state}cancelScheduleRequest(){this._transitionTo(j,q)}_transitionTo(p,t,o){if(this._state!==t&&this._state!==o)throw new Error(`${this.type} '${this.source}': can not transition to '${p}', expecting state '${t}'${o?" or '"+o+"'":""}, was '${this._state}'.`);this._state=p,p==j&&(this._zoneDelegates=null)}toString(){return this.data&&void 0!==this.data.handleId?this.data.handleId.toString():Object.prototype.toString.call(this)}toJSON(){return{type:this.type,state:this.state,source:this.source,zone:this.zone.name,runCount:this.runCount}}}const S=u("setTimeout"),D=u("Promise"),Z=u("then");let E,B=[],V=!1;function d(I){if(0===re&&0===B.length)if(E||e[D]&&(E=e[D].resolve(0)),E){let p=E[Z];p||(p=E.then),p.call(E,L)}else e[S](L,0);I&&B.push(I)}function L(){if(!V){for(V=!0;B.length;){const I=B;B=[];for(let p=0;p<I.length;p++){const t=I[p];try{t.zone.runTask(t,null,null)}catch(o){le.onUnhandledError(o)}}}le.microtaskDrainDone(),V=!1}}const z={name:"NO ZONE"},j="notScheduled",q="scheduling",O="scheduled",X="running",A="canceling",Y="unknown",v="microTask",M="macroTask",R="eventTask",J={},le={symbol:u,currentZoneFrame:()=>G,onUnhandledError:F,microtaskDrainDone:F,scheduleMicroTask:d,showUncaughtError:()=>!_[u("ignoreConsoleErrorUncaughtError")],patchEventTarget:()=>[],patchOnProperties:F,patchMethod:()=>F,bindArguments:()=>[],patchThen:()=>F,patchMacroTask:()=>F,patchEventPrototype:()=>F,isIEOrEdge:()=>!1,getGlobalObjects:()=>{},ObjectDefineProperty:()=>F,ObjectGetOwnPropertyDescriptor:()=>{},ObjectCreate:()=>{},ArraySlice:()=>[],patchClass:()=>F,wrapWithCurrentZone:()=>F,filterProperties:()=>[],attachOriginToPatched:()=>F,_redefineProperty:()=>F,patchCallbacks:()=>F};let G={parent:null,zone:new _(null,null)},te=null,re=0;function F(){}r("Zone","Zone"),e.Zone=_}("undefined"!=typeof window&&window||"undefined"!=typeof self&&self||global);const ue=Object.getOwnPropertyDescriptor,he=Object.defineProperty,de=Object.getPrototypeOf,Be=Object.create,ut=Array.prototype.slice,Se="addEventListener",Oe="removeEventListener",Ze=Zone.__symbol__(Se),Ie=Zone.__symbol__(Oe),se="true",ie="false",ke=Zone.__symbol__("");function Le(e,n){return Zone.current.wrap(e,n)}function Me(e,n,i,r,c){return Zone.current.scheduleMacroTask(e,n,i,r,c)}const x=Zone.__symbol__,Pe="undefined"!=typeof window,pe=Pe?window:void 0,$=Pe&&pe||"object"==typeof self&&self||global,ht=[null];function Ae(e,n){for(let i=e.length-1;i>=0;i--)"function"==typeof e[i]&&(e[i]=Le(e[i],n+"_"+i));return e}function Fe(e){return!e||!1!==e.writable&&!("function"==typeof e.get&&void 0===e.set)}const Ue="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope,Re=!("nw"in $)&&void 0!==$.process&&"[object process]"==={}.toString.call($.process),je=!Re&&!Ue&&!(!Pe||!pe.HTMLElement),We=void 0!==$.process&&"[object process]"==={}.toString.call($.process)&&!Ue&&!(!Pe||!pe.HTMLElement),Ce={},qe=function(e){if(!(e=e||$.event))return;let n=Ce[e.type];n||(n=Ce[e.type]=x("ON_PROPERTY"+e.type));const i=this||e.target||$,r=i[n];let c;if(je&&i===pe&&"error"===e.type){const u=e;c=r&&r.call(this,u.message,u.filename,u.lineno,u.colno,u.error),!0===c&&e.preventDefault()}else c=r&&r.apply(this,arguments),null!=c&&!c&&e.preventDefault();return c};function Xe(e,n,i){let r=ue(e,n);if(!r&&i&&ue(i,n)&&(r={enumerable:!0,configurable:!0}),!r||!r.configurable)return;const c=x("on"+n+"patched");if(e.hasOwnProperty(c)&&e[c])return;delete r.writable,delete r.value;const u=r.get,f=r.set,_=n.substr(2);let y=Ce[_];y||(y=Ce[_]=x("ON_PROPERTY"+_)),r.set=function(T){let m=this;!m&&e===$&&(m=$),m&&(m[y]&&m.removeEventListener(_,qe),f&&f.apply(m,ht),"function"==typeof T?(m[y]=T,m.addEventListener(_,qe,!1)):m[y]=null)},r.get=function(){let T=this;if(!T&&e===$&&(T=$),!T)return null;const m=T[y];if(m)return m;if(u){let S=u&&u.call(this);if(S)return r.set.call(this,S),"function"==typeof T.removeAttribute&&T.removeAttribute(n),S}return null},he(e,n,r),e[c]=!0}function Ye(e,n,i){if(n)for(let r=0;r<n.length;r++)Xe(e,"on"+n[r],i);else{const r=[];for(const c in e)"on"==c.substr(0,2)&&r.push(c);for(let c=0;c<r.length;c++)Xe(e,r[c],i)}}const ne=x("originalInstance");function ve(e){const n=$[e];if(!n)return;$[x(e)]=n,$[e]=function(){const c=Ae(arguments,e);switch(c.length){case 0:this[ne]=new n;break;case 1:this[ne]=new n(c[0]);break;case 2:this[ne]=new n(c[0],c[1]);break;case 3:this[ne]=new n(c[0],c[1],c[2]);break;case 4:this[ne]=new n(c[0],c[1],c[2],c[3]);break;default:throw new Error("Arg list too long.")}},ae($[e],n);const i=new n(function(){});let r;for(r in i)"XMLHttpRequest"===e&&"responseBlob"===r||function(c){"function"==typeof i[c]?$[e].prototype[c]=function(){return this[ne][c].apply(this[ne],arguments)}:he($[e].prototype,c,{set:function(u){"function"==typeof u?(this[ne][c]=Le(u,e+"."+c),ae(this[ne][c],u)):this[ne][c]=u},get:function(){return this[ne][c]}})}(r);for(r in n)"prototype"!==r&&n.hasOwnProperty(r)&&($[e][r]=n[r])}function ce(e,n,i){let r=e;for(;r&&!r.hasOwnProperty(n);)r=de(r);!r&&e[n]&&(r=e);const c=x(n);let u=null;if(r&&(!(u=r[c])||!r.hasOwnProperty(c))&&(u=r[c]=r[n],Fe(r&&ue(r,n)))){const _=i(u,c,n);r[n]=function(){return _(this,arguments)},ae(r[n],u)}return u}function _t(e,n,i){let r=null;function c(u){const f=u.data;return f.args[f.cbIdx]=function(){u.invoke.apply(this,arguments)},r.apply(f.target,f.args),u}r=ce(e,n,u=>function(f,_){const y=i(f,_);return y.cbIdx>=0&&"function"==typeof _[y.cbIdx]?Me(y.name,_[y.cbIdx],y,c):u.apply(f,_)})}function ae(e,n){e[x("OriginalDelegate")]=n}let $e=!1,He=!1;function mt(){if($e)return He;$e=!0;try{const e=pe.navigator.userAgent;(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/")||-1!==e.indexOf("Edge/"))&&(He=!0)}catch(e){}return He}Zone.__load_patch("ZoneAwarePromise",(e,n,i)=>{const r=Object.getOwnPropertyDescriptor,c=Object.defineProperty,f=i.symbol,_=[],y=!0===e[f("DISABLE_WRAPPING_UNCAUGHT_PROMISE_REJECTION")],T=f("Promise"),m=f("then");i.onUnhandledError=l=>{if(i.showUncaughtError()){const s=l&&l.rejection;s?console.error("Unhandled Promise rejection:",s instanceof Error?s.message:s,"; Zone:",l.zone.name,"; Task:",l.task&&l.task.source,"; Value:",s,s instanceof Error?s.stack:void 0):console.error(l)}},i.microtaskDrainDone=()=>{for(;_.length;){const l=_.shift();try{l.zone.runGuarded(()=>{throw l.throwOriginal?l.rejection:l})}catch(s){Z(s)}}};const D=f("unhandledPromiseRejectionHandler");function Z(l){i.onUnhandledError(l);try{const s=n[D];"function"==typeof s&&s.call(this,l)}catch(s){}}function B(l){return l&&l.then}function V(l){return l}function E(l){return t.reject(l)}const d=f("state"),L=f("value"),z=f("finally"),j=f("parentPromiseValue"),q=f("parentPromiseState"),X=null,A=!0,Y=!1;function M(l,s){return a=>{try{G(l,s,a)}catch(h){G(l,!1,h)}}}const le=f("currentTaskTrace");function G(l,s,a){const h=function(){let l=!1;return function(a){return function(){l||(l=!0,a.apply(null,arguments))}}}();if(l===a)throw new TypeError("Promise resolved with itself");if(l[d]===X){let w=null;try{("object"==typeof a||"function"==typeof a)&&(w=a&&a.then)}catch(C){return h(()=>{G(l,!1,C)})(),l}if(s!==Y&&a instanceof t&&a.hasOwnProperty(d)&&a.hasOwnProperty(L)&&a[d]!==X)re(a),G(l,a[d],a[L]);else if(s!==Y&&"function"==typeof w)try{w.call(a,h(M(l,s)),h(M(l,!1)))}catch(C){h(()=>{G(l,!1,C)})()}else{l[d]=s;const C=l[L];if(l[L]=a,l[z]===z&&s===A&&(l[d]=l[q],l[L]=l[j]),s===Y&&a instanceof Error){const k=n.currentTask&&n.currentTask.data&&n.currentTask.data.__creationTrace__;k&&c(a,le,{configurable:!0,enumerable:!1,writable:!0,value:k})}for(let k=0;k<C.length;)F(l,C[k++],C[k++],C[k++],C[k++]);if(0==C.length&&s==Y){l[d]=0;let k=a;try{throw new Error("Uncaught (in promise): "+function u(l){return l&&l.toString===Object.prototype.toString?(l.constructor&&l.constructor.name||"")+": "+JSON.stringify(l):l?l.toString():Object.prototype.toString.call(l)}(a)+(a&&a.stack?"\n"+a.stack:""))}catch(b){k=b}y&&(k.throwOriginal=!0),k.rejection=a,k.promise=l,k.zone=n.current,k.task=n.currentTask,_.push(k),i.scheduleMicroTask()}}}return l}const te=f("rejectionHandledHandler");function re(l){if(0===l[d]){try{const s=n[te];s&&"function"==typeof s&&s.call(this,{rejection:l[L],promise:l})}catch(s){}l[d]=Y;for(let s=0;s<_.length;s++)l===_[s].promise&&_.splice(s,1)}}function F(l,s,a,h,w){re(l);const C=l[d],k=C?"function"==typeof h?h:V:"function"==typeof w?w:E;s.scheduleMicroTask("Promise.then",()=>{try{const b=l[L],N=!!a&&z===a[z];N&&(a[j]=b,a[q]=C);const H=s.run(k,void 0,N&&k!==E&&k!==V?[]:[b]);G(a,!0,H)}catch(b){G(a,!1,b)}},a)}const p=function(){};class t{static toString(){return"function ZoneAwarePromise() { [native code] }"}static resolve(s){return G(new this(null),A,s)}static reject(s){return G(new this(null),Y,s)}static race(s){let a,h,w=new this((b,N)=>{a=b,h=N});function C(b){a(b)}function k(b){h(b)}for(let b of s)B(b)||(b=this.resolve(b)),b.then(C,k);return w}static all(s){return t.allWithCallback(s)}static allSettled(s){return(this&&this.prototype instanceof t?this:t).allWithCallback(s,{thenCallback:h=>({status:"fulfilled",value:h}),errorCallback:h=>({status:"rejected",reason:h})})}static allWithCallback(s,a){let h,w,C=new this((H,U)=>{h=H,w=U}),k=2,b=0;const N=[];for(let H of s){B(H)||(H=this.resolve(H));const U=b;try{H.then(Q=>{N[U]=a?a.thenCallback(Q):Q,k--,0===k&&h(N)},Q=>{a?(N[U]=a.errorCallback(Q),k--,0===k&&h(N)):w(Q)})}catch(Q){w(Q)}k++,b++}return k-=2,0===k&&h(N),C}constructor(s){const a=this;if(!(a instanceof t))throw new Error("Must be an instanceof Promise.");a[d]=X,a[L]=[];try{s&&s(M(a,A),M(a,Y))}catch(h){G(a,!1,h)}}get[Symbol.toStringTag](){return"Promise"}get[Symbol.species](){return t}then(s,a){let h=this.constructor[Symbol.species];(!h||"function"!=typeof h)&&(h=this.constructor||t);const w=new h(p),C=n.current;return this[d]==X?this[L].push(C,w,s,a):F(this,C,w,s,a),w}catch(s){return this.then(null,s)}finally(s){let a=this.constructor[Symbol.species];(!a||"function"!=typeof a)&&(a=t);const h=new a(p);h[z]=z;const w=n.current;return this[d]==X?this[L].push(w,h,s,s):F(this,w,h,s,s),h}}t.resolve=t.resolve,t.reject=t.reject,t.race=t.race,t.all=t.all;const o=e[T]=e.Promise;e.Promise=t;const g=f("thenPatched");function P(l){const s=l.prototype,a=r(s,"then");if(a&&(!1===a.writable||!a.configurable))return;const h=s.then;s[m]=h,l.prototype.then=function(w,C){return new t((b,N)=>{h.call(this,b,N)}).then(w,C)},l[g]=!0}return i.patchThen=P,o&&(P(o),ce(e,"fetch",l=>function K(l){return function(s,a){let h=l.apply(s,a);if(h instanceof t)return h;let w=h.constructor;return w[g]||P(w),h}}(l))),Promise[n.__symbol__("uncaughtPromiseErrors")]=_,t}),Zone.__load_patch("toString",e=>{const n=Function.prototype.toString,i=x("OriginalDelegate"),r=x("Promise"),c=x("Error"),u=function(){if("function"==typeof this){const T=this[i];if(T)return"function"==typeof T?n.call(T):Object.prototype.toString.call(T);if(this===Promise){const m=e[r];if(m)return n.call(m)}if(this===Error){const m=e[c];if(m)return n.call(m)}}return n.call(this)};u[i]=n,Function.prototype.toString=u;const f=Object.prototype.toString;Object.prototype.toString=function(){return"function"==typeof Promise&&this instanceof Promise?"[object Promise]":f.call(this)}});let me=!1;if("undefined"!=typeof window)try{const e=Object.defineProperty({},"passive",{get:function(){me=!0}});window.addEventListener("test",e,e),window.removeEventListener("test",e,e)}catch(e){me=!1}const Et={useG:!0},ee={},Ke={},Je=new RegExp("^"+ke+"(\\w+)(true|false)$"),xe=x("propagationStopped");function Qe(e,n){const i=(n?n(e):e)+ie,r=(n?n(e):e)+se,c=ke+i,u=ke+r;ee[e]={},ee[e][ie]=c,ee[e][se]=u}function Tt(e,n,i){const r=i&&i.add||Se,c=i&&i.rm||Oe,u=i&&i.listeners||"eventListeners",f=i&&i.rmAll||"removeAllListeners",_=x(r),y="."+r+":",S=function(E,d,L){if(E.isRemoved)return;const z=E.callback;"object"==typeof z&&z.handleEvent&&(E.callback=q=>z.handleEvent(q),E.originalDelegate=z),E.invoke(E,d,[L]);const j=E.options;j&&"object"==typeof j&&j.once&&d[c].call(d,L.type,E.originalDelegate?E.originalDelegate:E.callback,j)},D=function(E){if(!(E=E||e.event))return;const d=this||E.target||e,L=d[ee[E.type][ie]];if(L)if(1===L.length)S(L[0],d,E);else{const z=L.slice();for(let j=0;j<z.length&&(!E||!0!==E[xe]);j++)S(z[j],d,E)}},Z=function(E){if(!(E=E||e.event))return;const d=this||E.target||e,L=d[ee[E.type][se]];if(L)if(1===L.length)S(L[0],d,E);else{const z=L.slice();for(let j=0;j<z.length&&(!E||!0!==E[xe]);j++)S(z[j],d,E)}};function B(E,d){if(!E)return!1;let L=!0;d&&void 0!==d.useG&&(L=d.useG);const z=d&&d.vh;let j=!0;d&&void 0!==d.chkDup&&(j=d.chkDup);let q=!1;d&&void 0!==d.rt&&(q=d.rt);let O=E;for(;O&&!O.hasOwnProperty(r);)O=de(O);if(!O&&E[r]&&(O=E),!O||O[_])return!1;const X=d&&d.eventNameToString,A={},Y=O[_]=O[r],v=O[x(c)]=O[c],M=O[x(u)]=O[u],R=O[x(f)]=O[f];let J;function le(s,a){return!me&&"object"==typeof s&&s?!!s.capture:me&&a?"boolean"==typeof s?{capture:s,passive:!0}:s?"object"==typeof s&&!1!==s.passive?Object.assign(Object.assign({},s),{passive:!0}):s:{passive:!0}:s}d&&d.prepend&&(J=O[x(d.prepend)]=O[d.prepend]);const p=L?function(s){if(!A.isExisting)return Y.call(A.target,A.eventName,A.capture?Z:D,A.options)}:function(s){return Y.call(A.target,A.eventName,s.invoke,A.options)},t=L?function(s){if(!s.isRemoved){const a=ee[s.eventName];let h;a&&(h=a[s.capture?se:ie]);const w=h&&s.target[h];if(w)for(let C=0;C<w.length;C++)if(w[C]===s){w.splice(C,1),s.isRemoved=!0,0===w.length&&(s.allRemoved=!0,s.target[h]=null);break}}if(s.allRemoved)return v.call(s.target,s.eventName,s.capture?Z:D,s.options)}:function(s){return v.call(s.target,s.eventName,s.invoke,s.options)},g=d&&d.diff?d.diff:function(s,a){const h=typeof a;return"function"===h&&s.callback===a||"object"===h&&s.originalDelegate===a},P=Zone[x("UNPATCHED_EVENTS")],K=e[x("PASSIVE_EVENTS")],l=function(s,a,h,w,C=!1,k=!1){return function(){const b=this||e;let N=arguments[0];d&&d.transferEventName&&(N=d.transferEventName(N));let H=arguments[1];if(!H)return s.apply(this,arguments);if(Re&&"uncaughtException"===N)return s.apply(this,arguments);let U=!1;if("function"!=typeof H){if(!H.handleEvent)return s.apply(this,arguments);U=!0}if(z&&!z(s,H,b,arguments))return;const Q=me&&!!K&&-1!==K.indexOf(N),oe=le(arguments[2],Q);if(P)for(let _e=0;_e<P.length;_e++)if(N===P[_e])return Q?s.call(b,N,H,oe):s.apply(this,arguments);const Ge=!!oe&&("boolean"==typeof oe||oe.capture),st=!(!oe||"object"!=typeof oe)&&oe.once,At=Zone.current;let ze=ee[N];ze||(Qe(N,X),ze=ee[N]);const it=ze[Ge?se:ie];let De,ye=b[it],ct=!1;if(ye){if(ct=!0,j)for(let _e=0;_e<ye.length;_e++)if(g(ye[_e],H))return}else ye=b[it]=[];const at=b.constructor.name,lt=Ke[at];lt&&(De=lt[N]),De||(De=at+a+(X?X(N):N)),A.options=oe,st&&(A.options.once=!1),A.target=b,A.capture=Ge,A.eventName=N,A.isExisting=ct;const be=L?Et:void 0;be&&(be.taskData=A);const fe=At.scheduleEventTask(De,H,be,h,w);return A.target=null,be&&(be.taskData=null),st&&(oe.once=!0),!me&&"boolean"==typeof fe.options||(fe.options=oe),fe.target=b,fe.capture=Ge,fe.eventName=N,U&&(fe.originalDelegate=H),k?ye.unshift(fe):ye.push(fe),C?b:void 0}};return O[r]=l(Y,y,p,t,q),J&&(O.prependListener=l(J,".prependListener:",function(s){return J.call(A.target,A.eventName,s.invoke,A.options)},t,q,!0)),O[c]=function(){const s=this||e;let a=arguments[0];d&&d.transferEventName&&(a=d.transferEventName(a));const h=arguments[2],w=!!h&&("boolean"==typeof h||h.capture),C=arguments[1];if(!C)return v.apply(this,arguments);if(z&&!z(v,C,s,arguments))return;const k=ee[a];let b;k&&(b=k[w?se:ie]);const N=b&&s[b];if(N)for(let H=0;H<N.length;H++){const U=N[H];if(g(U,C))return N.splice(H,1),U.isRemoved=!0,0===N.length&&(U.allRemoved=!0,s[b]=null,"string"==typeof a)&&(s[ke+"ON_PROPERTY"+a]=null),U.zone.cancelTask(U),q?s:void 0}return v.apply(this,arguments)},O[u]=function(){const s=this||e;let a=arguments[0];d&&d.transferEventName&&(a=d.transferEventName(a));const h=[],w=et(s,X?X(a):a);for(let C=0;C<w.length;C++){const k=w[C];h.push(k.originalDelegate?k.originalDelegate:k.callback)}return h},O[f]=function(){const s=this||e;let a=arguments[0];if(a){d&&d.transferEventName&&(a=d.transferEventName(a));const h=ee[a];if(h){const k=s[h[ie]],b=s[h[se]];if(k){const N=k.slice();for(let H=0;H<N.length;H++){const U=N[H];this[c].call(this,a,U.originalDelegate?U.originalDelegate:U.callback,U.options)}}if(b){const N=b.slice();for(let H=0;H<N.length;H++){const U=N[H];this[c].call(this,a,U.originalDelegate?U.originalDelegate:U.callback,U.options)}}}}else{const h=Object.keys(s);for(let w=0;w<h.length;w++){const k=Je.exec(h[w]);let b=k&&k[1];b&&"removeListener"!==b&&this[f].call(this,b)}this[f].call(this,"removeListener")}if(q)return this},ae(O[r],Y),ae(O[c],v),R&&ae(O[f],R),M&&ae(O[u],M),!0}let V=[];for(let E=0;E<n.length;E++)V[E]=B(n[E],i);return V}function et(e,n){if(!n){const u=[];for(let f in e){const _=Je.exec(f);let y=_&&_[1];if(y&&(!n||y===n)){const T=e[f];if(T)for(let m=0;m<T.length;m++)u.push(T[m])}}return u}let i=ee[n];i||(Qe(n),i=ee[n]);const r=e[i[ie]],c=e[i[se]];return r?c?r.concat(c):r.slice():c?c.slice():[]}function gt(e,n){const i=e.Event;i&&i.prototype&&n.patchMethod(i.prototype,"stopImmediatePropagation",r=>function(c,u){c[xe]=!0,r&&r.apply(c,u)})}function yt(e,n,i,r,c){const u=Zone.__symbol__(r);if(n[u])return;const f=n[u]=n[r];n[r]=function(_,y,T){return y&&y.prototype&&c.forEach(function(m){const S=`${i}.${r}::`+m,D=y.prototype;if(D.hasOwnProperty(m)){const Z=e.ObjectGetOwnPropertyDescriptor(D,m);Z&&Z.value?(Z.value=e.wrapWithCurrentZone(Z.value,S),e._redefineProperty(y.prototype,m,Z)):D[m]&&(D[m]=e.wrapWithCurrentZone(D[m],S))}else D[m]&&(D[m]=e.wrapWithCurrentZone(D[m],S))}),f.call(n,_,y,T)},e.attachOriginToPatched(n[r],f)}const Ve=["absolutedeviceorientation","afterinput","afterprint","appinstalled","beforeinstallprompt","beforeprint","beforeunload","devicelight","devicemotion","deviceorientation","deviceorientationabsolute","deviceproximity","hashchange","languagechange","message","mozbeforepaint","offline","online","paint","pageshow","pagehide","popstate","rejectionhandled","storage","unhandledrejection","unload","userproximity","vrdisplayconnected","vrdisplaydisconnected","vrdisplaypresentchange"],wt=["encrypted","waitingforkey","msneedkey","mozinterruptbegin","mozinterruptend"],tt=["load"],nt=["blur","error","focus","load","resize","scroll","messageerror"],Dt=["bounce","finish","start"],rt=["loadstart","progress","abort","error","load","progress","timeout","loadend","readystatechange"],Ee=["upgradeneeded","complete","abort","success","error","blocked","versionchange","close"],St=["close","error","open","message"],Ot=["error","message"],Te=["abort","animationcancel","animationend","animationiteration","auxclick","beforeinput","blur","cancel","canplay","canplaythrough","change","compositionstart","compositionupdate","compositionend","cuechange","click","close","contextmenu","curechange","dblclick","drag","dragend","dragenter","dragexit","dragleave","dragover","drop","durationchange","emptied","ended","error","focus","focusin","focusout","gotpointercapture","input","invalid","keydown","keypress","keyup","load","loadstart","loadeddata","loadedmetadata","lostpointercapture","mousedown","mouseenter","mouseleave","mousemove","mouseout","mouseover","mouseup","mousewheel","orientationchange","pause","play","playing","pointercancel","pointerdown","pointerenter","pointerleave","pointerlockchange","mozpointerlockchange","webkitpointerlockerchange","pointerlockerror","mozpointerlockerror","webkitpointerlockerror","pointermove","pointout","pointerover","pointerup","progress","ratechange","reset","resize","scroll","seeked","seeking","select","selectionchange","selectstart","show","sort","stalled","submit","suspend","timeupdate","volumechange","touchcancel","touchmove","touchstart","touchend","transitioncancel","transitionend","waiting","wheel"].concat(["webglcontextrestored","webglcontextlost","webglcontextcreationerror"],["autocomplete","autocompleteerror"],["toggle"],["afterscriptexecute","beforescriptexecute","DOMContentLoaded","freeze","fullscreenchange","mozfullscreenchange","webkitfullscreenchange","msfullscreenchange","fullscreenerror","mozfullscreenerror","webkitfullscreenerror","msfullscreenerror","readystatechange","visibilitychange","resume"],Ve,["beforecopy","beforecut","beforepaste","copy","cut","paste","dragstart","loadend","animationstart","search","transitionrun","transitionstart","webkitanimationend","webkitanimationiteration","webkitanimationstart","webkittransitionend"],["activate","afterupdate","ariarequest","beforeactivate","beforedeactivate","beforeeditfocus","beforeupdate","cellchange","controlselect","dataavailable","datasetchanged","datasetcomplete","errorupdate","filterchange","layoutcomplete","losecapture","move","moveend","movestart","propertychange","resizeend","resizestart","rowenter","rowexit","rowsdelete","rowsinserted","command","compassneedscalibration","deactivate","help","mscontentzoom","msmanipulationstatechanged","msgesturechange","msgesturedoubletap","msgestureend","msgesturehold","msgesturestart","msgesturetap","msgotpointercapture","msinertiastart","mslostpointercapture","mspointercancel","mspointerdown","mspointerenter","mspointerhover","mspointerleave","mspointermove","mspointerout","mspointerover","mspointerup","pointerout","mssitemodejumplistitemremoved","msthumbnailclick","stop","storagecommit"]);function ot(e,n,i){if(!i||0===i.length)return n;const r=i.filter(u=>u.target===e);if(!r||0===r.length)return n;const c=r[0].ignoreProperties;return n.filter(u=>-1===c.indexOf(u))}function W(e,n,i,r){e&&Ye(e,ot(e,n,i),r)}Zone.__load_patch("util",(e,n,i)=>{i.patchOnProperties=Ye,i.patchMethod=ce,i.bindArguments=Ae,i.patchMacroTask=_t;const r=n.__symbol__("BLACK_LISTED_EVENTS"),c=n.__symbol__("UNPATCHED_EVENTS");e[c]&&(e[r]=e[c]),e[r]&&(n[r]=n[c]=e[r]),i.patchEventPrototype=gt,i.patchEventTarget=Tt,i.isIEOrEdge=mt,i.ObjectDefineProperty=he,i.ObjectGetOwnPropertyDescriptor=ue,i.ObjectCreate=Be,i.ArraySlice=ut,i.patchClass=ve,i.wrapWithCurrentZone=Le,i.filterProperties=ot,i.attachOriginToPatched=ae,i._redefineProperty=Object.defineProperty,i.patchCallbacks=yt,i.getGlobalObjects=()=>({globalSources:Ke,zoneSymbolEventNames:ee,eventNames:Te,isBrowser:je,isMix:We,isNode:Re,TRUE_STR:se,FALSE_STR:ie,ZONE_SYMBOL_PREFIX:ke,ADD_EVENT_LISTENER_STR:Se,REMOVE_EVENT_LISTENER_STR:Oe})});const Ne=x("zoneTask");function ge(e,n,i,r){let c=null,u=null;i+=r;const f={};function _(T){const m=T.data;return m.args[0]=function(){return T.invoke.apply(this,arguments)},m.handleId=c.apply(e,m.args),T}function y(T){return u.call(e,T.data.handleId)}c=ce(e,n+=r,T=>function(m,S){if("function"==typeof S[0]){const D={isPeriodic:"Interval"===r,delay:"Timeout"===r||"Interval"===r?S[1]||0:void 0,args:S},Z=S[0];S[0]=function(){try{return Z.apply(this,arguments)}finally{D.isPeriodic||("number"==typeof D.handleId?delete f[D.handleId]:D.handleId&&(D.handleId[Ne]=null))}};const B=Me(n,S[0],D,_,y);if(!B)return B;const V=B.data.handleId;return"number"==typeof V?f[V]=B:V&&(V[Ne]=B),V&&V.ref&&V.unref&&"function"==typeof V.ref&&"function"==typeof V.unref&&(B.ref=V.ref.bind(V),B.unref=V.unref.bind(V)),"number"==typeof V||V?V:B}return T.apply(e,S)}),u=ce(e,i,T=>function(m,S){const D=S[0];let Z;"number"==typeof D?Z=f[D]:(Z=D&&D[Ne],Z||(Z=D)),Z&&"string"==typeof Z.type?"notScheduled"!==Z.state&&(Z.cancelFn&&Z.data.isPeriodic||0===Z.runCount)&&("number"==typeof D?delete f[D]:D&&(D[Ne]=null),Z.zone.cancelTask(Z)):T.apply(e,S)})}Zone.__load_patch("legacy",e=>{const n=e[Zone.__symbol__("legacyPatch")];n&&n()}),Zone.__load_patch("queueMicrotask",(e,n,i)=>{i.patchMethod(e,"queueMicrotask",r=>function(c,u){n.current.scheduleMicroTask("queueMicrotask",u[0])})}),Zone.__load_patch("timers",e=>{const n="set",i="clear";ge(e,n,i,"Timeout"),ge(e,n,i,"Interval"),ge(e,n,i,"Immediate")}),Zone.__load_patch("requestAnimationFrame",e=>{ge(e,"request","cancel","AnimationFrame"),ge(e,"mozRequest","mozCancel","AnimationFrame"),ge(e,"webkitRequest","webkitCancel","AnimationFrame")}),Zone.__load_patch("blocking",(e,n)=>{const i=["alert","prompt","confirm"];for(let r=0;r<i.length;r++)ce(e,i[r],(u,f,_)=>function(y,T){return n.current.run(u,e,T,_)})}),Zone.__load_patch("EventTarget",(e,n,i)=>{(function Mt(e,n){n.patchEventPrototype(e,n)})(e,i),function Lt(e,n){if(Zone[n.symbol("patchEventTarget")])return;const{eventNames:i,zoneSymbolEventNames:r,TRUE_STR:c,FALSE_STR:u,ZONE_SYMBOL_PREFIX:f}=n.getGlobalObjects();for(let y=0;y<i.length;y++){const T=i[y],D=f+(T+u),Z=f+(T+c);r[T]={},r[T][u]=D,r[T][c]=Z}const _=e.EventTarget;_&&_.prototype&&n.patchEventTarget(e,[_&&_.prototype])}(e,i);const r=e.XMLHttpRequestEventTarget;r&&r.prototype&&i.patchEventTarget(e,[r.prototype])}),Zone.__load_patch("MutationObserver",(e,n,i)=>{ve("MutationObserver"),ve("WebKitMutationObserver")}),Zone.__load_patch("IntersectionObserver",(e,n,i)=>{ve("IntersectionObserver")}),Zone.__load_patch("FileReader",(e,n,i)=>{ve("FileReader")}),Zone.__load_patch("on_property",(e,n,i)=>{!function Zt(e,n){if(Re&&!We||Zone[e.symbol("patchEvents")])return;const i="undefined"!=typeof WebSocket,r=n.__Zone_ignore_on_properties;if(je){const f=window,_=function pt(){try{const e=pe.navigator.userAgent;if(-1!==e.indexOf("MSIE ")||-1!==e.indexOf("Trident/"))return!0}catch(e){}return!1}()?[{target:f,ignoreProperties:["error"]}]:[];W(f,Te.concat(["messageerror"]),r&&r.concat(_),de(f)),W(Document.prototype,Te,r),void 0!==f.SVGElement&&W(f.SVGElement.prototype,Te,r),W(Element.prototype,Te,r),W(HTMLElement.prototype,Te,r),W(HTMLMediaElement.prototype,wt,r),W(HTMLFrameSetElement.prototype,Ve.concat(nt),r),W(HTMLBodyElement.prototype,Ve.concat(nt),r),W(HTMLFrameElement.prototype,tt,r),W(HTMLIFrameElement.prototype,tt,r);const y=f.HTMLMarqueeElement;y&&W(y.prototype,Dt,r);const T=f.Worker;T&&W(T.prototype,Ot,r)}const c=n.XMLHttpRequest;c&&W(c.prototype,rt,r);const u=n.XMLHttpRequestEventTarget;u&&W(u&&u.prototype,rt,r),"undefined"!=typeof IDBIndex&&(W(IDBIndex.prototype,Ee,r),W(IDBRequest.prototype,Ee,r),W(IDBOpenDBRequest.prototype,Ee,r),W(IDBDatabase.prototype,Ee,r),W(IDBTransaction.prototype,Ee,r),W(IDBCursor.prototype,Ee,r)),i&&W(WebSocket.prototype,St,r)}(i,e)}),Zone.__load_patch("customElements",(e,n,i)=>{!function It(e,n){const{isBrowser:i,isMix:r}=n.getGlobalObjects();(i||r)&&e.customElements&&"customElements"in e&&n.patchCallbacks(n,e.customElements,"customElements","define",["connectedCallback","disconnectedCallback","adoptedCallback","attributeChangedCallback"])}(e,i)}),Zone.__load_patch("XHR",(e,n)=>{!function y(T){const m=T.XMLHttpRequest;if(!m)return;const S=m.prototype;let Z=S[Ze],B=S[Ie];if(!Z){const v=T.XMLHttpRequestEventTarget;if(v){const M=v.prototype;Z=M[Ze],B=M[Ie]}}const V="readystatechange",E="scheduled";function d(v){const M=v.data,R=M.target;R[u]=!1,R[_]=!1;const J=R[c];Z||(Z=R[Ze],B=R[Ie]),J&&B.call(R,V,J);const le=R[c]=()=>{if(R.readyState===R.DONE)if(!M.aborted&&R[u]&&v.state===E){const te=R[n.__symbol__("loadfalse")];if(0!==R.status&&te&&te.length>0){const re=v.invoke;v.invoke=function(){const F=R[n.__symbol__("loadfalse")];for(let I=0;I<F.length;I++)F[I]===v&&F.splice(I,1);!M.aborted&&v.state===E&&re.call(v)},te.push(v)}else v.invoke()}else!M.aborted&&!1===R[u]&&(R[_]=!0)};return Z.call(R,V,le),R[i]||(R[i]=v),A.apply(R,M.args),R[u]=!0,v}function L(){}function z(v){const M=v.data;return M.aborted=!0,Y.apply(M.target,M.args)}const j=ce(S,"open",()=>function(v,M){return v[r]=0==M[2],v[f]=M[1],j.apply(v,M)}),O=x("fetchTaskAborting"),X=x("fetchTaskScheduling"),A=ce(S,"send",()=>function(v,M){if(!0===n.current[X]||v[r])return A.apply(v,M);{const R={target:v,url:v[f],isPeriodic:!1,args:M,aborted:!1},J=Me("XMLHttpRequest.send",L,R,d,z);v&&!0===v[_]&&!R.aborted&&J.state===E&&J.invoke()}}),Y=ce(S,"abort",()=>function(v,M){const R=function D(v){return v[i]}(v);if(R&&"string"==typeof R.type){if(null==R.cancelFn||R.data&&R.data.aborted)return;R.zone.cancelTask(R)}else if(!0===n.current[O])return Y.apply(v,M)})}(e);const i=x("xhrTask"),r=x("xhrSync"),c=x("xhrListener"),u=x("xhrScheduled"),f=x("xhrURL"),_=x("xhrErrorBeforeScheduled")}),Zone.__load_patch("geolocation",e=>{e.navigator&&e.navigator.geolocation&&function dt(e,n){const i=e.constructor.name;for(let r=0;r<n.length;r++){const c=n[r],u=e[c];if(u){if(!Fe(ue(e,c)))continue;e[c]=(_=>{const y=function(){return _.apply(this,Ae(arguments,i+"."+c))};return ae(y,_),y})(u)}}}(e.navigator.geolocation,["getCurrentPosition","watchPosition"])}),Zone.__load_patch("PromiseRejectionEvent",(e,n)=>{function i(r){return function(c){et(e,r).forEach(f=>{const _=e.PromiseRejectionEvent;if(_){const y=new _(r,{promise:c.promise,reason:c.rejection});f.invoke(y)}})}}e.PromiseRejectionEvent&&(n[x("unhandledPromiseRejectionHandler")]=i("unhandledrejection"),n[x("rejectionHandledHandler")]=i("rejectionhandled"))})}},we=>{we(we.s=435)}]);
+
+"use strict";(self.webpackChunkcoverage_app=self.webpackChunkcoverage_app||[]).push([[179],{873:()=>{function pe(e){return"function"==typeof e}function xo(e){const n=e(r=>{Error.call(r),r.stack=(new Error).stack});return n.prototype=Object.create(Error.prototype),n.prototype.constructor=n,n}const No=xo(e=>function(n){e(this),this.message=n?`${n.length} errors occurred during unsubscription:\n${n.map((r,o)=>`${o+1}) ${r.toString()}`).join("\n  ")}`:"",this.name="UnsubscriptionError",this.errors=n});function Fr(e,t){if(e){const n=e.indexOf(t);0<=n&&e.splice(n,1)}}class Tt{constructor(t){this.initialTeardown=t,this.closed=!1,this._parentage=null,this._teardowns=null}unsubscribe(){let t;if(!this.closed){this.closed=!0;const{_parentage:n}=this;if(n)if(this._parentage=null,Array.isArray(n))for(const i of n)i.remove(this);else n.remove(this);const{initialTeardown:r}=this;if(pe(r))try{r()}catch(i){t=i instanceof No?i.errors:[i]}const{_teardowns:o}=this;if(o){this._teardowns=null;for(const i of o)try{uc(i)}catch(s){t=null!=t?t:[],s instanceof No?t=[...t,...s.errors]:t.push(s)}}if(t)throw new No(t)}}add(t){var n;if(t&&t!==this)if(this.closed)uc(t);else{if(t instanceof Tt){if(t.closed||t._hasParent(this))return;t._addParent(this)}(this._teardowns=null!==(n=this._teardowns)&&void 0!==n?n:[]).push(t)}}_hasParent(t){const{_parentage:n}=this;return n===t||Array.isArray(n)&&n.includes(t)}_addParent(t){const{_parentage:n}=this;this._parentage=Array.isArray(n)?(n.push(t),n):n?[n,t]:t}_removeParent(t){const{_parentage:n}=this;n===t?this._parentage=null:Array.isArray(n)&&Fr(n,t)}remove(t){const{_teardowns:n}=this;n&&Fr(n,t),t instanceof Tt&&t._removeParent(this)}}Tt.EMPTY=(()=>{const e=new Tt;return e.closed=!0,e})();const ac=Tt.EMPTY;function lc(e){return e instanceof Tt||e&&"closed"in e&&pe(e.remove)&&pe(e.add)&&pe(e.unsubscribe)}function uc(e){pe(e)?e():e.unsubscribe()}const yn={onUnhandledError:null,onStoppedNotification:null,Promise:void 0,useDeprecatedSynchronousErrorHandling:!1,useDeprecatedNextContext:!1},Fo={setTimeout(...e){const{delegate:t}=Fo;return((null==t?void 0:t.setTimeout)||setTimeout)(...e)},clearTimeout(e){const{delegate:t}=Fo;return((null==t?void 0:t.clearTimeout)||clearTimeout)(e)},delegate:void 0};function cc(e){Fo.setTimeout(()=>{const{onUnhandledError:t}=yn;if(!t)throw e;t(e)})}function Oo(){}const Z_=gs("C",void 0,void 0);function gs(e,t,n){return{kind:e,value:t,error:n}}let Cn=null;function Ro(e){if(yn.useDeprecatedSynchronousErrorHandling){const t=!Cn;if(t&&(Cn={errorThrown:!1,error:null}),e(),t){const{errorThrown:n,error:r}=Cn;if(Cn=null,n)throw r}}else e()}class ms extends Tt{constructor(t){super(),this.isStopped=!1,t?(this.destination=t,lc(t)&&t.add(this)):this.destination=X_}static create(t,n,r){return new _s(t,n,r)}next(t){this.isStopped?ys(function K_(e){return gs("N",e,void 0)}(t),this):this._next(t)}error(t){this.isStopped?ys(function Y_(e){return gs("E",void 0,e)}(t),this):(this.isStopped=!0,this._error(t))}complete(){this.isStopped?ys(Z_,this):(this.isStopped=!0,this._complete())}unsubscribe(){this.closed||(this.isStopped=!0,super.unsubscribe(),this.destination=null)}_next(t){this.destination.next(t)}_error(t){try{this.destination.error(t)}finally{this.unsubscribe()}}_complete(){try{this.destination.complete()}finally{this.unsubscribe()}}}class _s extends ms{constructor(t,n,r){let o;if(super(),pe(t))o=t;else if(t){let i;({next:o,error:n,complete:r}=t),this&&yn.useDeprecatedNextContext?(i=Object.create(t),i.unsubscribe=()=>this.unsubscribe()):i=t,o=null==o?void 0:o.bind(i),n=null==n?void 0:n.bind(i),r=null==r?void 0:r.bind(i)}this.destination={next:o?vs(o):Oo,error:vs(null!=n?n:dc),complete:r?vs(r):Oo}}}function vs(e,t){return(...n)=>{try{e(...n)}catch(r){yn.useDeprecatedSynchronousErrorHandling?function J_(e){yn.useDeprecatedSynchronousErrorHandling&&Cn&&(Cn.errorThrown=!0,Cn.error=e)}(r):cc(r)}}}function dc(e){throw e}function ys(e,t){const{onStoppedNotification:n}=yn;n&&Fo.setTimeout(()=>n(e,t))}const X_={closed:!0,next:Oo,error:dc,complete:Oo},Cs="function"==typeof Symbol&&Symbol.observable||"@@observable";function fc(e){return e}let Le=(()=>{class e{constructor(n){n&&(this._subscribe=n)}lift(n){const r=new e;return r.source=this,r.operator=n,r}subscribe(n,r,o){const i=function tv(e){return e&&e instanceof ms||function ev(e){return e&&pe(e.next)&&pe(e.error)&&pe(e.complete)}(e)&&lc(e)}(n)?n:new _s(n,r,o);return Ro(()=>{const{operator:s,source:a}=this;i.add(s?s.call(i,a):a?this._subscribe(i):this._trySubscribe(i))}),i}_trySubscribe(n){try{return this._subscribe(n)}catch(r){n.error(r)}}forEach(n,r){return new(r=pc(r))((o,i)=>{let s;s=this.subscribe(a=>{try{n(a)}catch(l){i(l),null==s||s.unsubscribe()}},i,o)})}_subscribe(n){var r;return null===(r=this.source)||void 0===r?void 0:r.subscribe(n)}[Cs](){return this}pipe(...n){return function hc(e){return 0===e.length?fc:1===e.length?e[0]:function(n){return e.reduce((r,o)=>o(r),n)}}(n)(this)}toPromise(n){return new(n=pc(n))((r,o)=>{let i;this.subscribe(s=>i=s,s=>o(s),()=>r(i))})}}return e.create=t=>new e(t),e})();function pc(e){var t;return null!==(t=null!=e?e:yn.Promise)&&void 0!==t?t:Promise}const nv=xo(e=>function(){e(this),this.name="ObjectUnsubscribedError",this.message="object unsubscribed"});let Ds=(()=>{class e extends Le{constructor(){super(),this.closed=!1,this.observers=[],this.isStopped=!1,this.hasError=!1,this.thrownError=null}lift(n){const r=new gc(this,this);return r.operator=n,r}_throwIfClosed(){if(this.closed)throw new nv}next(n){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){const r=this.observers.slice();for(const o of r)o.next(n)}})}error(n){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){this.hasError=this.isStopped=!0,this.thrownError=n;const{observers:r}=this;for(;r.length;)r.shift().error(n)}})}complete(){Ro(()=>{if(this._throwIfClosed(),!this.isStopped){this.isStopped=!0;const{observers:n}=this;for(;n.length;)n.shift().complete()}})}unsubscribe(){this.isStopped=this.closed=!0,this.observers=null}get observed(){var n;return(null===(n=this.observers)||void 0===n?void 0:n.length)>0}_trySubscribe(n){return this._throwIfClosed(),super._trySubscribe(n)}_subscribe(n){return this._throwIfClosed(),this._checkFinalizedStatuses(n),this._innerSubscribe(n)}_innerSubscribe(n){const{hasError:r,isStopped:o,observers:i}=this;return r||o?ac:(i.push(n),new Tt(()=>Fr(i,n)))}_checkFinalizedStatuses(n){const{hasError:r,thrownError:o,isStopped:i}=this;r?n.error(o):i&&n.complete()}asObservable(){const n=new Le;return n.source=this,n}}return e.create=(t,n)=>new gc(t,n),e})();class gc extends Ds{constructor(t,n){super(),this.destination=t,this.source=n}next(t){var n,r;null===(r=null===(n=this.destination)||void 0===n?void 0:n.next)||void 0===r||r.call(n,t)}error(t){var n,r;null===(r=null===(n=this.destination)||void 0===n?void 0:n.error)||void 0===r||r.call(n,t)}complete(){var t,n;null===(n=null===(t=this.destination)||void 0===t?void 0:t.complete)||void 0===n||n.call(t)}_subscribe(t){var n,r;return null!==(r=null===(n=this.source)||void 0===n?void 0:n.subscribe(t))&&void 0!==r?r:ac}}function Ln(e){return t=>{if(function rv(e){return pe(null==e?void 0:e.lift)}(t))return t.lift(function(n){try{return e(n,this)}catch(r){this.error(r)}});throw new TypeError("Unable to lift unknown Observable type")}}class Bn extends ms{constructor(t,n,r,o,i){super(t),this.onFinalize=i,this._next=n?function(s){try{n(s)}catch(a){t.error(a)}}:super._next,this._error=o?function(s){try{o(s)}catch(a){t.error(a)}finally{this.unsubscribe()}}:super._error,this._complete=r?function(){try{r()}catch(s){t.error(s)}finally{this.unsubscribe()}}:super._complete}unsubscribe(){var t;const{closed:n}=this;super.unsubscribe(),!n&&(null===(t=this.onFinalize)||void 0===t||t.call(this))}}function ws(e,t){return Ln((n,r)=>{let o=0;n.subscribe(new Bn(r,i=>{r.next(e.call(t,i,o++))}))})}function Dn(e){return this instanceof Dn?(this.v=e,this):new Dn(e)}function sv(e,t,n){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var o,r=n.apply(e,t||[]),i=[];return o={},s("next"),s("throw"),s("return"),o[Symbol.asyncIterator]=function(){return this},o;function s(f){r[f]&&(o[f]=function(p){return new Promise(function(m,D){i.push([f,p,m,D])>1||a(f,p)})})}function a(f,p){try{!function l(f){f.value instanceof Dn?Promise.resolve(f.value.v).then(u,c):d(i[0][2],f)}(r[f](p))}catch(m){d(i[0][3],m)}}function u(f){a("next",f)}function c(f){a("throw",f)}function d(f,p){f(p),i.shift(),i.length&&a(i[0][0],i[0][1])}}function av(e){if(!Symbol.asyncIterator)throw new TypeError("Symbol.asyncIterator is not defined.");var n,t=e[Symbol.asyncIterator];return t?t.call(e):(e=function vc(e){var t="function"==typeof Symbol&&Symbol.iterator,n=t&&e[t],r=0;if(n)return n.call(e);if(e&&"number"==typeof e.length)return{next:function(){return e&&r>=e.length&&(e=void 0),{value:e&&e[r++],done:!e}}};throw new TypeError(t?"Object is not iterable.":"Symbol.iterator is not defined.")}(e),n={},r("next"),r("throw"),r("return"),n[Symbol.asyncIterator]=function(){return this},n);function r(i){n[i]=e[i]&&function(s){return new Promise(function(a,l){!function o(i,s,a,l){Promise.resolve(l).then(function(u){i({value:u,done:a})},s)}(a,l,(s=e[i](s)).done,s.value)})}}}const yc=e=>e&&"number"==typeof e.length&&"function"!=typeof e;function Cc(e){return pe(null==e?void 0:e.then)}function Dc(e){return pe(e[Cs])}function wc(e){return Symbol.asyncIterator&&pe(null==e?void 0:e[Symbol.asyncIterator])}function bc(e){return new TypeError(`You provided ${null!==e&&"object"==typeof e?"an invalid object":`'${e}'`} where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.`)}const Ec=function uv(){return"function"==typeof Symbol&&Symbol.iterator?Symbol.iterator:"@@iterator"}();function Mc(e){return pe(null==e?void 0:e[Ec])}function Ic(e){return sv(this,arguments,function*(){const n=e.getReader();try{for(;;){const{value:r,done:o}=yield Dn(n.read());if(o)return yield Dn(void 0);yield yield Dn(r)}}finally{n.releaseLock()}})}function Ac(e){return pe(null==e?void 0:e.getReader)}function wn(e){if(e instanceof Le)return e;if(null!=e){if(Dc(e))return function cv(e){return new Le(t=>{const n=e[Cs]();if(pe(n.subscribe))return n.subscribe(t);throw new TypeError("Provided object does not correctly implement Symbol.observable")})}(e);if(yc(e))return function dv(e){return new Le(t=>{for(let n=0;n<e.length&&!t.closed;n++)t.next(e[n]);t.complete()})}(e);if(Cc(e))return function fv(e){return new Le(t=>{e.then(n=>{t.closed||(t.next(n),t.complete())},n=>t.error(n)).then(null,cc)})}(e);if(wc(e))return Tc(e);if(Mc(e))return function hv(e){return new Le(t=>{for(const n of e)if(t.next(n),t.closed)return;t.complete()})}(e);if(Ac(e))return function pv(e){return Tc(Ic(e))}(e)}throw bc(e)}function Tc(e){return new Le(t=>{(function gv(e,t){var n,r,o,i;return function ov(e,t,n,r){return new(n||(n=Promise))(function(i,s){function a(c){try{u(r.next(c))}catch(d){s(d)}}function l(c){try{u(r.throw(c))}catch(d){s(d)}}function u(c){c.done?i(c.value):function o(i){return i instanceof n?i:new n(function(s){s(i)})}(c.value).then(a,l)}u((r=r.apply(e,t||[])).next())})}(this,void 0,void 0,function*(){try{for(n=av(e);!(r=yield n.next()).done;)if(t.next(r.value),t.closed)return}catch(s){o={error:s}}finally{try{r&&!r.done&&(i=n.return)&&(yield i.call(n))}finally{if(o)throw o.error}}t.complete()})})(e,t).catch(n=>t.error(n))})}function en(e,t,n,r=0,o=!1){const i=t.schedule(function(){n(),o?e.add(this.schedule(null,r)):this.unsubscribe()},r);if(e.add(i),!o)return i}function Sc(e,t,n=1/0){return pe(t)?Sc((r,o)=>ws((i,s)=>t(r,i,o,s))(wn(e(r,o))),n):("number"==typeof t&&(n=t),Ln((r,o)=>function mv(e,t,n,r,o,i,s,a){const l=[];let u=0,c=0,d=!1;const f=()=>{d&&!l.length&&!u&&t.complete()},p=D=>u<r?m(D):l.push(D),m=D=>{i&&t.next(D),u++;let M=!1;wn(n(D,c++)).subscribe(new Bn(t,I=>{null==o||o(I),i?p(I):t.next(I)},()=>{M=!0},void 0,()=>{if(M)try{for(u--;l.length&&u<r;){const I=l.shift();s?en(t,s,()=>m(I)):m(I)}f()}catch(I){t.error(I)}}))};return e.subscribe(new Bn(t,p,()=>{d=!0,f()})),()=>{null==a||a()}}(r,o,e,n)))}const Es=new Le(e=>e.complete());function Ms(e){return e[e.length-1]}function xc(e,t=0){return Ln((n,r)=>{n.subscribe(new Bn(r,o=>en(r,e,()=>r.next(o),t),()=>en(r,e,()=>r.complete(),t),o=>en(r,e,()=>r.error(o),t)))})}function Nc(e,t=0){return Ln((n,r)=>{r.add(e.schedule(()=>n.subscribe(r),t))})}function Fc(e,t){if(!e)throw new Error("Iterable cannot be null");return new Le(n=>{en(n,t,()=>{const r=e[Symbol.asyncIterator]();en(n,t,()=>{r.next().then(o=>{o.done?n.complete():n.next(o.value)})},0,!0)})})}function Is(e,t){return t?function Tv(e,t){if(null!=e){if(Dc(e))return function bv(e,t){return wn(e).pipe(Nc(t),xc(t))}(e,t);if(yc(e))return function Mv(e,t){return new Le(n=>{let r=0;return t.schedule(function(){r===e.length?n.complete():(n.next(e[r++]),n.closed||this.schedule())})})}(e,t);if(Cc(e))return function Ev(e,t){return wn(e).pipe(Nc(t),xc(t))}(e,t);if(wc(e))return Fc(e,t);if(Mc(e))return function Iv(e,t){return new Le(n=>{let r;return en(n,t,()=>{r=e[Ec](),en(n,t,()=>{let o,i;try{({value:o,done:i}=r.next())}catch(s){return void n.error(s)}i?n.complete():n.next(o)},0,!0)}),()=>pe(null==r?void 0:r.return)&&r.return()})}(e,t);if(Ac(e))return function Av(e,t){return Fc(Ic(e),t)}(e,t)}throw bc(e)}(e,t):wn(e)}function Sv(...e){const t=function Dv(e){return function yv(e){return e&&pe(e.schedule)}(Ms(e))?e.pop():void 0}(e),n=function wv(e,t){return"number"==typeof Ms(e)?e.pop():t}(e,1/0),r=e;return r.length?1===r.length?wn(r[0]):function _v(e=1/0){return Sc(fc,e)}(n)(Is(r,t)):Es}function As(e,t,...n){return!0===t?(e(),null):!1===t?null:t(...n).pipe(function xv(e){return e<=0?()=>Es:Ln((t,n)=>{let r=0;t.subscribe(new Bn(n,o=>{++r<=e&&(n.next(o),e<=r&&n.complete())}))})}(1)).subscribe(()=>e())}function ie(e){for(let t in e)if(e[t]===ie)return t;throw Error("Could not find renamed property on target object.")}function Ts(e,t){for(const n in t)t.hasOwnProperty(n)&&!e.hasOwnProperty(n)&&(e[n]=t[n])}function te(e){if("string"==typeof e)return e;if(Array.isArray(e))return"["+e.map(te).join(", ")+"]";if(null==e)return""+e;if(e.overriddenName)return`${e.overriddenName}`;if(e.name)return`${e.name}`;const t=e.toString();if(null==t)return""+t;const n=t.indexOf("\n");return-1===n?t:t.substring(0,n)}function Ss(e,t){return null==e||""===e?null===t?"":t:null==t||""===t?e:e+" "+t}const Fv=ie({__forward_ref__:ie});function ae(e){return e.__forward_ref__=ae,e.toString=function(){return te(this())},e}function H(e){return Oc(e)?e():e}function Oc(e){return"function"==typeof e&&e.hasOwnProperty(Fv)&&e.__forward_ref__===ae}class Y extends Error{constructor(t,n){super(function xs(e,t){return`NG0${Math.abs(e)}${t?": "+t:""}`}(t,n)),this.code=t}}function V(e){return"string"==typeof e?e:null==e?"":String(e)}function Be(e){return"function"==typeof e?e.name||e.toString():"object"==typeof e&&null!=e&&"function"==typeof e.type?e.type.name||e.type.toString():V(e)}function Po(e,t){const n=t?` in ${t}`:"";throw new Y(-201,`No provider for ${Be(e)} found${n}`)}function Ke(e,t){null==e&&function ce(e,t,n,r){throw new Error(`ASSERTION ERROR: ${e}`+(null==r?"":` [Expected=> ${n} ${r} ${t} <=Actual]`))}(t,e,null,"!=")}function de(e){return{token:e.token,providedIn:e.providedIn||null,factory:e.factory,value:void 0}}function Gt(e){return{providers:e.providers||[],imports:e.imports||[]}}function Ns(e){return Rc(e,Vo)||Rc(e,Vc)}function Rc(e,t){return e.hasOwnProperty(t)?e[t]:null}function Pc(e){return e&&(e.hasOwnProperty(Fs)||e.hasOwnProperty(Bv))?e[Fs]:null}const Vo=ie({\u0275prov:ie}),Fs=ie({\u0275inj:ie}),Vc=ie({ngInjectableDef:ie}),Bv=ie({ngInjectorDef:ie});var B=(()=>((B=B||{})[B.Default=0]="Default",B[B.Host=1]="Host",B[B.Self=2]="Self",B[B.SkipSelf=4]="SkipSelf",B[B.Optional=8]="Optional",B))();let Os;function tn(e){const t=Os;return Os=e,t}function kc(e,t,n){const r=Ns(e);return r&&"root"==r.providedIn?void 0===r.value?r.value=r.factory():r.value:n&B.Optional?null:void 0!==t?t:void Po(te(e),"Injector")}function nn(e){return{toString:e}.toString()}var gt=(()=>((gt=gt||{})[gt.OnPush=0]="OnPush",gt[gt.Default=1]="Default",gt))(),St=(()=>{return(e=St||(St={}))[e.Emulated=0]="Emulated",e[e.None=2]="None",e[e.ShadowDom=3]="ShadowDom",St;var e})();const jv="undefined"!=typeof globalThis&&globalThis,$v="undefined"!=typeof window&&window,Uv="undefined"!=typeof self&&"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&self,re=jv||"undefined"!=typeof global&&global||$v||Uv,Hn={},se=[],ko=ie({\u0275cmp:ie}),Rs=ie({\u0275dir:ie}),Ps=ie({\u0275pipe:ie}),Lc=ie({\u0275mod:ie}),qt=ie({\u0275fac:ie}),Or=ie({__NG_ELEMENT_ID__:ie});let zv=0;function rn(e){return nn(()=>{const n={},r={type:e.type,providersResolver:null,decls:e.decls,vars:e.vars,factory:null,template:e.template||null,consts:e.consts||null,ngContentSelectors:e.ngContentSelectors,hostBindings:e.hostBindings||null,hostVars:e.hostVars||0,hostAttrs:e.hostAttrs||null,contentQueries:e.contentQueries||null,declaredInputs:n,inputs:null,outputs:null,exportAs:e.exportAs||null,onPush:e.changeDetection===gt.OnPush,directiveDefs:null,pipeDefs:null,selectors:e.selectors||se,viewQuery:e.viewQuery||null,features:e.features||null,data:e.data||{},encapsulation:e.encapsulation||St.Emulated,id:"c",styles:e.styles||se,_:null,setInput:null,schemas:e.schemas||null,tView:null},o=e.directives,i=e.features,s=e.pipes;return r.id+=zv++,r.inputs=$c(e.inputs,n),r.outputs=$c(e.outputs),i&&i.forEach(a=>a(r)),r.directiveDefs=o?()=>("function"==typeof o?o():o).map(Bc):null,r.pipeDefs=s?()=>("function"==typeof s?s():s).map(Hc):null,r})}function Bc(e){return Ne(e)||function sn(e){return e[Rs]||null}(e)}function Hc(e){return function bn(e){return e[Ps]||null}(e)}const jc={};function on(e){return nn(()=>{const t={type:e.type,bootstrap:e.bootstrap||se,declarations:e.declarations||se,imports:e.imports||se,exports:e.exports||se,transitiveCompileScopes:null,schemas:e.schemas||null,id:e.id||null};return null!=e.id&&(jc[e.id]=e.type),t})}function $c(e,t){if(null==e)return Hn;const n={};for(const r in e)if(e.hasOwnProperty(r)){let o=e[r],i=o;Array.isArray(o)&&(i=o[1],o=o[0]),n[o]=r,t&&(t[o]=i)}return n}const k=rn;function qe(e){return{type:e.type,name:e.name,factory:null,pure:!1!==e.pure,onDestroy:e.type.prototype.ngOnDestroy||null}}function Ne(e){return e[ko]||null}function it(e,t){const n=e[Lc]||null;if(!n&&!0===t)throw new Error(`Type ${te(e)} does not have '\u0275mod' property.`);return n}const j=11;function xt(e){return Array.isArray(e)&&"object"==typeof e[1]}function _t(e){return Array.isArray(e)&&!0===e[1]}function Ls(e){return 0!=(8&e.flags)}function jo(e){return 2==(2&e.flags)}function $o(e){return 1==(1&e.flags)}function vt(e){return null!==e.template}function Yv(e){return 0!=(512&e[2])}function An(e,t){return e.hasOwnProperty(qt)?e[qt]:null}class Xv{constructor(t,n,r){this.previousValue=t,this.currentValue=n,this.firstChange=r}isFirstChange(){return this.firstChange}}function Wt(){return zc}function zc(e){return e.type.prototype.ngOnChanges&&(e.setInput=ty),ey}function ey(){const e=qc(this),t=null==e?void 0:e.current;if(t){const n=e.previous;if(n===Hn)e.previous=t;else for(let r in t)n[r]=t[r];e.current=null,this.ngOnChanges(t)}}function ty(e,t,n,r){const o=qc(e)||function ny(e,t){return e[Gc]=t}(e,{previous:Hn,current:null}),i=o.current||(o.current={}),s=o.previous,a=this.declaredInputs[n],l=s[a];i[a]=new Xv(l&&l.currentValue,t,s===Hn),e[r]=t}Wt.ngInherit=!0;const Gc="__ngSimpleChanges__";function qc(e){return e[Gc]||null}let Us;function me(e){return!!e.listen}const Wc={createRenderer:(e,t)=>function zs(){return void 0!==Us?Us:"undefined"!=typeof document?document:void 0}()};function De(e){for(;Array.isArray(e);)e=e[0];return e}function Uo(e,t){return De(t[e])}function lt(e,t){return De(t[e.index])}function Gs(e,t){return e.data[t]}function Xe(e,t){const n=t[e];return xt(n)?n:n[0]}function qs(e){return 128==(128&e[2])}function an(e,t){return null==t?null:e[t]}function Zc(e){e[18]=0}function Ws(e,t){e[5]+=t;let n=e,r=e[3];for(;null!==r&&(1===t&&1===n[5]||-1===t&&0===n[5]);)r[5]+=t,n=r,r=r[3]}const P={lFrame:rd(null),bindingsEnabled:!0,isInCheckNoChangesMode:!1};function Yc(){return P.bindingsEnabled}function w(){return P.lFrame.lView}function K(){return P.lFrame.tView}function ee(e){return P.lFrame.contextLView=e,e[8]}function Me(){let e=Kc();for(;null!==e&&64===e.type;)e=e.parent;return e}function Kc(){return P.lFrame.currentTNode}function Nt(e,t){const n=P.lFrame;n.currentTNode=e,n.isParent=t}function Qs(){return P.lFrame.isParent}function Zs(){P.lFrame.isParent=!1}function zo(){return P.isInCheckNoChangesMode}function Go(e){P.isInCheckNoChangesMode=e}function He(){const e=P.lFrame;let t=e.bindingRootIndex;return-1===t&&(t=e.bindingRootIndex=e.tView.bindingStartIndex),t}function qn(){return P.lFrame.bindingIndex++}function Zt(e){const t=P.lFrame,n=t.bindingIndex;return t.bindingIndex=t.bindingIndex+e,n}function yy(e,t){const n=P.lFrame;n.bindingIndex=n.bindingRootIndex=e,Ys(t)}function Ys(e){P.lFrame.currentDirectiveIndex=e}function Js(e){P.lFrame.currentQueryIndex=e}function Dy(e){const t=e[1];return 2===t.type?t.declTNode:1===t.type?e[6]:null}function td(e,t,n){if(n&B.SkipSelf){let o=t,i=e;for(;!(o=o.parent,null!==o||n&B.Host||(o=Dy(i),null===o||(i=i[15],10&o.type))););if(null===o)return!1;t=o,e=i}const r=P.lFrame=nd();return r.currentTNode=t,r.lView=e,!0}function qo(e){const t=nd(),n=e[1];P.lFrame=t,t.currentTNode=n.firstChild,t.lView=e,t.tView=n,t.contextLView=e,t.bindingIndex=n.bindingStartIndex,t.inI18n=!1}function nd(){const e=P.lFrame,t=null===e?null:e.child;return null===t?rd(e):t}function rd(e){const t={currentTNode:null,isParent:!0,lView:null,tView:null,selectedIndex:-1,contextLView:null,elementDepthCount:0,currentNamespace:null,currentDirectiveIndex:-1,bindingRootIndex:-1,bindingIndex:-1,currentQueryIndex:0,parent:e,child:null,inI18n:!1};return null!==e&&(e.child=t),t}function od(){const e=P.lFrame;return P.lFrame=e.parent,e.currentTNode=null,e.lView=null,e}const id=od;function Wo(){const e=od();e.isParent=!0,e.tView=null,e.selectedIndex=-1,e.contextLView=null,e.elementDepthCount=0,e.currentDirectiveIndex=-1,e.currentNamespace=null,e.bindingRootIndex=-1,e.bindingIndex=-1,e.currentQueryIndex=0}function je(){return P.lFrame.selectedIndex}function ln(e){P.lFrame.selectedIndex=e}function _e(){const e=P.lFrame;return Gs(e.tView,e.selectedIndex)}function Qo(e,t){for(let n=t.directiveStart,r=t.directiveEnd;n<r;n++){const i=e.data[n].type.prototype,{ngAfterContentInit:s,ngAfterContentChecked:a,ngAfterViewInit:l,ngAfterViewChecked:u,ngOnDestroy:c}=i;s&&(e.contentHooks||(e.contentHooks=[])).push(-n,s),a&&((e.contentHooks||(e.contentHooks=[])).push(n,a),(e.contentCheckHooks||(e.contentCheckHooks=[])).push(n,a)),l&&(e.viewHooks||(e.viewHooks=[])).push(-n,l),u&&((e.viewHooks||(e.viewHooks=[])).push(n,u),(e.viewCheckHooks||(e.viewCheckHooks=[])).push(n,u)),null!=c&&(e.destroyHooks||(e.destroyHooks=[])).push(n,c)}}function Zo(e,t,n){ad(e,t,3,n)}function Yo(e,t,n,r){(3&e[2])===n&&ad(e,t,n,r)}function Xs(e,t){let n=e[2];(3&n)===t&&(n&=2047,n+=1,e[2]=n)}function ad(e,t,n,r){const i=null!=r?r:-1,s=t.length-1;let a=0;for(let l=void 0!==r?65535&e[18]:0;l<s;l++)if("number"==typeof t[l+1]){if(a=t[l],null!=r&&a>=r)break}else t[l]<0&&(e[18]+=65536),(a<i||-1==i)&&(Sy(e,n,t,l),e[18]=(4294901760&e[18])+l+2),l++}function Sy(e,t,n,r){const o=n[r]<0,i=n[r+1],a=e[o?-n[r]:n[r]];if(o){if(e[2]>>11<e[18]>>16&&(3&e[2])===t){e[2]+=2048;try{i.call(a)}finally{}}}else try{i.call(a)}finally{}}class Lr{constructor(t,n,r){this.factory=t,this.resolving=!1,this.canSeeViewProviders=n,this.injectImpl=r}}function Ko(e,t,n){const r=me(e);let o=0;for(;o<n.length;){const i=n[o];if("number"==typeof i){if(0!==i)break;o++;const s=n[o++],a=n[o++],l=n[o++];r?e.setAttribute(t,a,l,s):t.setAttributeNS(s,a,l)}else{const s=i,a=n[++o];ta(s)?r&&e.setProperty(t,s,a):r?e.setAttribute(t,s,a):t.setAttribute(s,a),o++}}return o}function ld(e){return 3===e||4===e||6===e}function ta(e){return 64===e.charCodeAt(0)}function Jo(e,t){if(null!==t&&0!==t.length)if(null===e||0===e.length)e=t.slice();else{let n=-1;for(let r=0;r<t.length;r++){const o=t[r];"number"==typeof o?n=o:0===n||ud(e,n,o,null,-1===n||2===n?t[++r]:null)}}return e}function ud(e,t,n,r,o){let i=0,s=e.length;if(-1===t)s=-1;else for(;i<e.length;){const a=e[i++];if("number"==typeof a){if(a===t){s=-1;break}if(a>t){s=i-1;break}}}for(;i<e.length;){const a=e[i];if("number"==typeof a)break;if(a===n){if(null===r)return void(null!==o&&(e[i+1]=o));if(r===e[i+1])return void(e[i+2]=o)}i++,null!==r&&i++,null!==o&&i++}-1!==s&&(e.splice(s,0,t),i=s+1),e.splice(i++,0,n),null!==r&&e.splice(i++,0,r),null!==o&&e.splice(i++,0,o)}function cd(e){return-1!==e}function Wn(e){return 32767&e}function Qn(e,t){let n=function Ry(e){return e>>16}(e),r=t;for(;n>0;)r=r[15],n--;return r}let na=!0;function Xo(e){const t=na;return na=e,t}let Py=0;function Hr(e,t){const n=oa(e,t);if(-1!==n)return n;const r=t[1];r.firstCreatePass&&(e.injectorIndex=t.length,ra(r.data,e),ra(t,null),ra(r.blueprint,null));const o=ei(e,t),i=e.injectorIndex;if(cd(o)){const s=Wn(o),a=Qn(o,t),l=a[1].data;for(let u=0;u<8;u++)t[i+u]=a[s+u]|l[s+u]}return t[i+8]=o,i}function ra(e,t){e.push(0,0,0,0,0,0,0,0,t)}function oa(e,t){return-1===e.injectorIndex||e.parent&&e.parent.injectorIndex===e.injectorIndex||null===t[e.injectorIndex+8]?-1:e.injectorIndex}function ei(e,t){if(e.parent&&-1!==e.parent.injectorIndex)return e.parent.injectorIndex;let n=0,r=null,o=t;for(;null!==o;){const i=o[1],s=i.type;if(r=2===s?i.declTNode:1===s?o[6]:null,null===r)return-1;if(n++,o=o[15],-1!==r.injectorIndex)return r.injectorIndex|n<<16}return-1}function ti(e,t,n){!function Vy(e,t,n){let r;"string"==typeof n?r=n.charCodeAt(0)||0:n.hasOwnProperty(Or)&&(r=n[Or]),null==r&&(r=n[Or]=Py++);const o=255&r;t.data[e+(o>>5)]|=1<<o}(e,t,n)}function hd(e,t,n){if(n&B.Optional)return e;Po(t,"NodeInjector")}function pd(e,t,n,r){if(n&B.Optional&&void 0===r&&(r=null),0==(n&(B.Self|B.Host))){const o=e[9],i=tn(void 0);try{return o?o.get(t,r,n&B.Optional):kc(t,r,n&B.Optional)}finally{tn(i)}}return hd(r,t,n)}function gd(e,t,n,r=B.Default,o){if(null!==e){const i=function Hy(e){if("string"==typeof e)return e.charCodeAt(0)||0;const t=e.hasOwnProperty(Or)?e[Or]:void 0;return"number"==typeof t?t>=0?255&t:Ly:t}(n);if("function"==typeof i){if(!td(t,e,r))return r&B.Host?hd(o,n,r):pd(t,n,r,o);try{const s=i(r);if(null!=s||r&B.Optional)return s;Po(n)}finally{id()}}else if("number"==typeof i){let s=null,a=oa(e,t),l=-1,u=r&B.Host?t[16][6]:null;for((-1===a||r&B.SkipSelf)&&(l=-1===a?ei(e,t):t[a+8],-1!==l&&vd(r,!1)?(s=t[1],a=Wn(l),t=Qn(l,t)):a=-1);-1!==a;){const c=t[1];if(_d(i,a,c.data)){const d=By(a,t,n,s,r,u);if(d!==md)return d}l=t[a+8],-1!==l&&vd(r,t[1].data[a+8]===u)&&_d(i,a,t)?(s=c,a=Wn(l),t=Qn(l,t)):a=-1}}}return pd(t,n,r,o)}const md={};function Ly(){return new Zn(Me(),w())}function By(e,t,n,r,o,i){const s=t[1],a=s.data[e+8],c=function ni(e,t,n,r,o){const i=e.providerIndexes,s=t.data,a=1048575&i,l=e.directiveStart,c=i>>20,f=o?a+c:e.directiveEnd;for(let p=r?a:a+c;p<f;p++){const m=s[p];if(p<l&&n===m||p>=l&&m.type===n)return p}if(o){const p=s[l];if(p&&vt(p)&&p.type===n)return l}return null}(a,s,n,null==r?jo(a)&&na:r!=s&&0!=(3&a.type),o&B.Host&&i===a);return null!==c?jr(t,s,c,a):md}function jr(e,t,n,r){let o=e[n];const i=t.data;if(function xy(e){return e instanceof Lr}(o)){const s=o;s.resolving&&function Ov(e,t){const n=t?`. Dependency path: ${t.join(" > ")} > ${e}`:"";throw new Y(-200,`Circular dependency in DI detected for ${e}${n}`)}(Be(i[n]));const a=Xo(s.canSeeViewProviders);s.resolving=!0;const l=s.injectImpl?tn(s.injectImpl):null;td(e,r,B.Default);try{o=e[n]=s.factory(void 0,i,e,r),t.firstCreatePass&&n>=r.directiveStart&&function Ty(e,t,n){const{ngOnChanges:r,ngOnInit:o,ngDoCheck:i}=t.type.prototype;if(r){const s=zc(t);(n.preOrderHooks||(n.preOrderHooks=[])).push(e,s),(n.preOrderCheckHooks||(n.preOrderCheckHooks=[])).push(e,s)}o&&(n.preOrderHooks||(n.preOrderHooks=[])).push(0-e,o),i&&((n.preOrderHooks||(n.preOrderHooks=[])).push(e,i),(n.preOrderCheckHooks||(n.preOrderCheckHooks=[])).push(e,i))}(n,i[n],t)}finally{null!==l&&tn(l),Xo(a),s.resolving=!1,id()}}return o}function _d(e,t,n){return!!(n[t+(e>>5)]&1<<e)}function vd(e,t){return!(e&B.Self||e&B.Host&&t)}class Zn{constructor(t,n){this._tNode=t,this._lView=n}get(t,n,r){return gd(this._tNode,this._lView,t,r,n)}}function Oe(e){return nn(()=>{const t=e.prototype.constructor,n=t[qt]||ia(t),r=Object.prototype;let o=Object.getPrototypeOf(e.prototype).constructor;for(;o&&o!==r;){const i=o[qt]||ia(o);if(i&&i!==n)return i;o=Object.getPrototypeOf(o)}return i=>new i})}function ia(e){return Oc(e)?()=>{const t=ia(H(e));return t&&t()}:An(e)}const Kn="__parameters__";function Xn(e,t,n){return nn(()=>{const r=function aa(e){return function(...n){if(e){const r=e(...n);for(const o in r)this[o]=r[o]}}}(t);function o(...i){if(this instanceof o)return r.apply(this,i),this;const s=new o(...i);return a.annotation=s,a;function a(l,u,c){const d=l.hasOwnProperty(Kn)?l[Kn]:Object.defineProperty(l,Kn,{value:[]})[Kn];for(;d.length<=c;)d.push(null);return(d[c]=d[c]||[]).push(s),l}}return n&&(o.prototype=Object.create(n.prototype)),o.prototype.ngMetadataName=e,o.annotationCls=o,o})}class J{constructor(t,n){this._desc=t,this.ngMetadataName="InjectionToken",this.\u0275prov=void 0,"number"==typeof n?this.__NG_ELEMENT_ID__=n:void 0!==n&&(this.\u0275prov=de({token:this,providedIn:n.providedIn||"root",factory:n.factory}))}toString(){return`InjectionToken ${this._desc}`}}function Ft(e,t){e.forEach(n=>Array.isArray(n)?Ft(n,t):t(n))}function Cd(e,t,n){t>=e.length?e.push(n):e.splice(t,0,n)}function ri(e,t){return t>=e.length-1?e.pop():e.splice(t,1)[0]}function et(e,t,n){let r=er(e,t);return r>=0?e[1|r]=n:(r=~r,function zy(e,t,n,r){let o=e.length;if(o==t)e.push(n,r);else if(1===o)e.push(r,e[0]),e[0]=n;else{for(o--,e.push(e[o-1],e[o]);o>t;)e[o]=e[o-2],o--;e[t]=n,e[t+1]=r}}(e,r,t,n)),r}function ua(e,t){const n=er(e,t);if(n>=0)return e[1|n]}function er(e,t){return function bd(e,t,n){let r=0,o=e.length>>n;for(;o!==r;){const i=r+(o-r>>1),s=e[i<<n];if(t===s)return i<<n;s>t?o=i:r=i+1}return~(o<<n)}(e,t,1)}const Gr={},da="__NG_DI_FLAG__",ii="ngTempTokenPath",Ky=/\n/gm,Md="__source",Xy=ie({provide:String,useValue:ie});let qr;function Id(e){const t=qr;return qr=e,t}function eC(e,t=B.Default){if(void 0===qr)throw new Y(203,"");return null===qr?kc(e,void 0,t):qr.get(e,t&B.Optional?null:void 0,t)}function oe(e,t=B.Default){return(function Hv(){return Os}()||eC)(H(e),t)}const tC=oe;function fa(e){const t=[];for(let n=0;n<e.length;n++){const r=H(e[n]);if(Array.isArray(r)){if(0===r.length)throw new Y(900,"");let o,i=B.Default;for(let s=0;s<r.length;s++){const a=r[s],l=nC(a);"number"==typeof l?-1===l?o=a.token:i|=l:o=a}t.push(oe(o,i))}else t.push(oe(r))}return t}function Wr(e,t){return e[da]=t,e.prototype[da]=t,e}function nC(e){return e[da]}const si=Wr(Xn("Optional"),8),ai=Wr(Xn("SkipSelf"),4);class Pd{constructor(t){this.changingThisBreaksApplicationSecurity=t}toString(){return`SafeValue must use [property]=binding: ${this.changingThisBreaksApplicationSecurity} (see https://g.co/ng/security#xss)`}}function cn(e){return e instanceof Pd?e.changingThisBreaksApplicationSecurity:e}const EC=/^(?:(?:https?|mailto|ftp|tel|file|sms):|[^&:/?#]*(?:[/?#]|$))/gi,MC=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+\/]+=*$/i;var we=(()=>((we=we||{})[we.NONE=0]="NONE",we[we.HTML=1]="HTML",we[we.STYLE=2]="STYLE",we[we.SCRIPT=3]="SCRIPT",we[we.URL=4]="URL",we[we.RESOURCE_URL=5]="RESOURCE_URL",we))();function rr(e){const t=function Kr(){const e=w();return e&&e[12]}();return t?t.sanitize(we.URL,e)||"":function Zr(e,t){const n=function CC(e){return e instanceof Pd&&e.getTypeName()||null}(e);if(null!=n&&n!==t){if("ResourceURL"===n&&"URL"===t)return!0;throw new Error(`Required a safe ${t}, got a ${n} (see https://g.co/ng/security#xss)`)}return n===t}(e,"URL")?cn(e):function di(e){return(e=String(e)).match(EC)||e.match(MC)?e:"unsafe:"+e}(V(e))}const Gd="__ngContext__";function Re(e,t){e[Gd]=t}function wa(e){const t=function Jr(e){return e[Gd]||null}(e);return t?Array.isArray(t)?t:t.lView:null}function Ea(e){return e.ngOriginalError}function QC(e,...t){e.error(...t)}class Xr{constructor(){this._console=console}handleError(t){const n=this._findOriginalError(t),r=function WC(e){return e&&e.ngErrorLogger||QC}(t);r(this._console,"ERROR",t),n&&r(this._console,"ORIGINAL ERROR",n)}_findOriginalError(t){let n=t&&Ea(t);for(;n&&Ea(n);)n=Ea(n);return n||null}}const oD=(()=>("undefined"!=typeof requestAnimationFrame&&requestAnimationFrame||setTimeout).bind(re))();function Ma(e){return e.ownerDocument.defaultView}function Rt(e){return e instanceof Function?e():e}var tt=(()=>((tt=tt||{})[tt.Important=1]="Important",tt[tt.DashCase=2]="DashCase",tt))();function Aa(e,t){return undefined(e,t)}function eo(e){const t=e[3];return _t(t)?t[3]:t}function Ta(e){return ef(e[13])}function Sa(e){return ef(e[4])}function ef(e){for(;null!==e&&!_t(e);)e=e[4];return e}function ir(e,t,n,r,o){if(null!=r){let i,s=!1;_t(r)?i=r:xt(r)&&(s=!0,r=r[0]);const a=De(r);0===e&&null!==n?null==o?af(t,n,a):Tn(t,n,a,o||null,!0):1===e&&null!==n?Tn(t,n,a,o||null,!0):2===e?function pf(e,t,n){const r=hi(e,t);r&&function _D(e,t,n,r){me(e)?e.removeChild(t,n,r):t.removeChild(n)}(e,r,t,n)}(t,a,s):3===e&&t.destroyNode(a),null!=i&&function CD(e,t,n,r,o){const i=n[7];i!==De(n)&&ir(t,e,r,i,o);for(let a=10;a<n.length;a++){const l=n[a];to(l[1],l,e,t,r,i)}}(t,e,i,n,o)}}function Na(e,t,n){if(me(e))return e.createElement(t,n);{const r=null!==n?function sy(e){const t=e.toLowerCase();return"svg"===t?"http://www.w3.org/2000/svg":"math"===t?"http://www.w3.org/1998/MathML/":null}(n):null;return null===r?e.createElement(t):e.createElementNS(r,t)}}function nf(e,t){const n=e[9],r=n.indexOf(t),o=t[3];1024&t[2]&&(t[2]&=-1025,Ws(o,-1)),n.splice(r,1)}function Fa(e,t){if(e.length<=10)return;const n=10+t,r=e[n];if(r){const o=r[17];null!==o&&o!==e&&nf(o,r),t>0&&(e[n-1][4]=r[4]);const i=ri(e,10+t);!function uD(e,t){to(e,t,t[j],2,null,null),t[0]=null,t[6]=null}(r[1],r);const s=i[19];null!==s&&s.detachView(i[1]),r[3]=null,r[4]=null,r[2]&=-129}return r}function rf(e,t){if(!(256&t[2])){const n=t[j];me(n)&&n.destroyNode&&to(e,t,n,3,null,null),function fD(e){let t=e[13];if(!t)return Oa(e[1],e);for(;t;){let n=null;if(xt(t))n=t[13];else{const r=t[10];r&&(n=r)}if(!n){for(;t&&!t[4]&&t!==e;)xt(t)&&Oa(t[1],t),t=t[3];null===t&&(t=e),xt(t)&&Oa(t[1],t),n=t&&t[4]}t=n}}(t)}}function Oa(e,t){if(!(256&t[2])){t[2]&=-129,t[2]|=256,function mD(e,t){let n;if(null!=e&&null!=(n=e.destroyHooks))for(let r=0;r<n.length;r+=2){const o=t[n[r]];if(!(o instanceof Lr)){const i=n[r+1];if(Array.isArray(i))for(let s=0;s<i.length;s+=2){const a=o[i[s]],l=i[s+1];try{l.call(a)}finally{}}else try{i.call(o)}finally{}}}}(e,t),function gD(e,t){const n=e.cleanup,r=t[7];let o=-1;if(null!==n)for(let i=0;i<n.length-1;i+=2)if("string"==typeof n[i]){const s=n[i+1],a="function"==typeof s?s(t):De(t[s]),l=r[o=n[i+2]],u=n[i+3];"boolean"==typeof u?a.removeEventListener(n[i],l,u):u>=0?r[o=u]():r[o=-u].unsubscribe(),i+=2}else{const s=r[o=n[i+1]];n[i].call(s)}if(null!==r){for(let i=o+1;i<r.length;i++)r[i]();t[7]=null}}(e,t),1===t[1].type&&me(t[j])&&t[j].destroy();const n=t[17];if(null!==n&&_t(t[3])){n!==t[3]&&nf(n,t);const r=t[19];null!==r&&r.detachView(e)}}}function of(e,t,n){return function sf(e,t,n){let r=t;for(;null!==r&&40&r.type;)r=(t=r).parent;if(null===r)return n[0];if(2&r.flags){const o=e.data[r.directiveStart].encapsulation;if(o===St.None||o===St.Emulated)return null}return lt(r,n)}(e,t.parent,n)}function Tn(e,t,n,r,o){me(e)?e.insertBefore(t,n,r,o):t.insertBefore(n,r,o)}function af(e,t,n){me(e)?e.appendChild(t,n):t.appendChild(n)}function lf(e,t,n,r,o){null!==r?Tn(e,t,n,r,o):af(e,t,n)}function hi(e,t){return me(e)?e.parentNode(t):t.parentNode}let df=function cf(e,t,n){return 40&e.type?lt(e,n):null};function pi(e,t,n,r){const o=of(e,r,t),i=t[j],a=function uf(e,t,n){return df(e,t,n)}(r.parent||t[6],r,t);if(null!=o)if(Array.isArray(n))for(let l=0;l<n.length;l++)lf(i,o,n[l],a,!1);else lf(i,o,n,a,!1)}function gi(e,t){if(null!==t){const n=t.type;if(3&n)return lt(t,e);if(4&n)return Pa(-1,e[t.index]);if(8&n){const r=t.child;if(null!==r)return gi(e,r);{const o=e[t.index];return _t(o)?Pa(-1,o):De(o)}}if(32&n)return Aa(t,e)()||De(e[t.index]);{const r=hf(e,t);return null!==r?Array.isArray(r)?r[0]:gi(eo(e[16]),r):gi(e,t.next)}}return null}function hf(e,t){return null!==t?e[16][6].projection[t.projection]:null}function Pa(e,t){const n=10+e+1;if(n<t.length){const r=t[n],o=r[1].firstChild;if(null!==o)return gi(r,o)}return t[7]}function Va(e,t,n,r,o,i,s){for(;null!=n;){const a=r[n.index],l=n.type;if(s&&0===t&&(a&&Re(De(a),r),n.flags|=4),64!=(64&n.flags))if(8&l)Va(e,t,n.child,r,o,i,!1),ir(t,e,o,a,i);else if(32&l){const u=Aa(n,r);let c;for(;c=u();)ir(t,e,o,c,i);ir(t,e,o,a,i)}else 16&l?gf(e,t,r,n,o,i):ir(t,e,o,a,i);n=s?n.projectionNext:n.next}}function to(e,t,n,r,o,i){Va(n,r,e.firstChild,t,o,i,!1)}function gf(e,t,n,r,o,i){const s=n[16],l=s[6].projection[r.projection];if(Array.isArray(l))for(let u=0;u<l.length;u++)ir(t,e,o,l[u],i);else Va(e,t,l,s[3],o,i,!0)}function mf(e,t,n){me(e)?e.setAttribute(t,"style",n):t.style.cssText=n}function ka(e,t,n){me(e)?""===n?e.removeAttribute(t,"class"):e.setAttribute(t,"class",n):t.className=n}function _f(e,t,n){let r=e.length;for(;;){const o=e.indexOf(t,n);if(-1===o)return o;if(0===o||e.charCodeAt(o-1)<=32){const i=t.length;if(o+i===r||e.charCodeAt(o+i)<=32)return o}n=o+1}}const vf="ng-template";function wD(e,t,n){let r=0;for(;r<e.length;){let o=e[r++];if(n&&"class"===o){if(o=e[r],-1!==_f(o.toLowerCase(),t,0))return!0}else if(1===o){for(;r<e.length&&"string"==typeof(o=e[r++]);)if(o.toLowerCase()===t)return!0;return!1}}return!1}function yf(e){return 4===e.type&&e.value!==vf}function bD(e,t,n){return t===(4!==e.type||n?e.value:vf)}function ED(e,t,n){let r=4;const o=e.attrs||[],i=function AD(e){for(let t=0;t<e.length;t++)if(ld(e[t]))return t;return e.length}(o);let s=!1;for(let a=0;a<t.length;a++){const l=t[a];if("number"!=typeof l){if(!s)if(4&r){if(r=2|1&r,""!==l&&!bD(e,l,n)||""===l&&1===t.length){if(yt(r))return!1;s=!0}}else{const u=8&r?l:t[++a];if(8&r&&null!==e.attrs){if(!wD(e.attrs,u,n)){if(yt(r))return!1;s=!0}continue}const d=MD(8&r?"class":l,o,yf(e),n);if(-1===d){if(yt(r))return!1;s=!0;continue}if(""!==u){let f;f=d>i?"":o[d+1].toLowerCase();const p=8&r?f:null;if(p&&-1!==_f(p,u,0)||2&r&&u!==f){if(yt(r))return!1;s=!0}}}}else{if(!s&&!yt(r)&&!yt(l))return!1;if(s&&yt(l))continue;s=!1,r=l|1&r}}return yt(r)||s}function yt(e){return 0==(1&e)}function MD(e,t,n,r){if(null===t)return-1;let o=0;if(r||!n){let i=!1;for(;o<t.length;){const s=t[o];if(s===e)return o;if(3===s||6===s)i=!0;else{if(1===s||2===s){let a=t[++o];for(;"string"==typeof a;)a=t[++o];continue}if(4===s)break;if(0===s){o+=4;continue}}o+=i?1:2}return-1}return function TD(e,t){let n=e.indexOf(4);if(n>-1)for(n++;n<e.length;){const r=e[n];if("number"==typeof r)return-1;if(r===t)return n;n++}return-1}(t,e)}function Cf(e,t,n=!1){for(let r=0;r<t.length;r++)if(ED(e,t[r],n))return!0;return!1}function Df(e,t){return e?":not("+t.trim()+")":t}function xD(e){let t=e[0],n=1,r=2,o="",i=!1;for(;n<e.length;){let s=e[n];if("string"==typeof s)if(2&r){const a=e[++n];o+="["+s+(a.length>0?'="'+a+'"':"")+"]"}else 8&r?o+="."+s:4&r&&(o+=" "+s);else""!==o&&!yt(s)&&(t+=Df(i,o),o=""),r=s,i=i||!yt(r);n++}return""!==o&&(t+=Df(i,o)),t}const L={};function h(e){wf(K(),w(),je()+e,zo())}function wf(e,t,n,r){if(!r)if(3==(3&t[2])){const i=e.preOrderCheckHooks;null!==i&&Zo(t,i,n)}else{const i=e.preOrderHooks;null!==i&&Yo(t,i,0,n)}ln(n)}function mi(e,t){return e<<17|t<<2}function Ct(e){return e>>17&32767}function La(e){return 2|e}function Yt(e){return(131068&e)>>2}function Ba(e,t){return-131069&e|t<<2}function Ha(e){return 1|e}function Of(e,t){const n=e.contentQueries;if(null!==n)for(let r=0;r<n.length;r+=2){const o=n[r],i=n[r+1];if(-1!==i){const s=e.data[i];Js(o),s.contentQueries(2,t[i],i)}}}function no(e,t,n,r,o,i,s,a,l,u){const c=t.blueprint.slice();return c[0]=o,c[2]=140|r,Zc(c),c[3]=c[15]=e,c[8]=n,c[10]=s||e&&e[10],c[j]=a||e&&e[j],c[12]=l||e&&e[12]||null,c[9]=u||e&&e[9]||null,c[6]=i,c[16]=2==t.type?e[16]:c,c}function sr(e,t,n,r,o){let i=e.data[t];if(null===i)i=function Za(e,t,n,r,o){const i=Kc(),s=Qs(),l=e.data[t]=function QD(e,t,n,r,o,i){return{type:n,index:r,insertBeforeIndex:null,injectorIndex:t?t.injectorIndex:-1,directiveStart:-1,directiveEnd:-1,directiveStylingLast:-1,propertyBindings:null,flags:0,providerIndexes:0,value:o,attrs:i,mergedAttrs:null,localNames:null,initialInputs:void 0,inputs:null,outputs:null,tViews:null,next:null,projectionNext:null,child:null,parent:t,projection:null,styles:null,stylesWithoutHost:null,residualStyles:void 0,classes:null,classesWithoutHost:null,residualClasses:void 0,classBindings:0,styleBindings:0}}(0,s?i:i&&i.parent,n,t,r,o);return null===e.firstChild&&(e.firstChild=l),null!==i&&(s?null==i.child&&null!==l.parent&&(i.child=l):null===i.next&&(i.next=l)),l}(e,t,n,r,o),function vy(){return P.lFrame.inI18n}()&&(i.flags|=64);else if(64&i.type){i.type=n,i.value=r,i.attrs=o;const s=function kr(){const e=P.lFrame,t=e.currentTNode;return e.isParent?t:t.parent}();i.injectorIndex=null===s?-1:s.injectorIndex}return Nt(i,!0),i}function ar(e,t,n,r){if(0===n)return-1;const o=t.length;for(let i=0;i<n;i++)t.push(r),e.blueprint.push(r),e.data.push(null);return o}function ro(e,t,n){qo(t);try{const r=e.viewQuery;null!==r&&ol(1,r,n);const o=e.template;null!==o&&Rf(e,t,o,1,n),e.firstCreatePass&&(e.firstCreatePass=!1),e.staticContentQueries&&Of(e,t),e.staticViewQueries&&ol(2,e.viewQuery,n);const i=e.components;null!==i&&function GD(e,t){for(let n=0;n<t.length;n++)fw(e,t[n])}(t,i)}catch(r){throw e.firstCreatePass&&(e.incompleteFirstPass=!0,e.firstCreatePass=!1),r}finally{t[2]&=-5,Wo()}}function lr(e,t,n,r){const o=t[2];if(256==(256&o))return;qo(t);const i=zo();try{Zc(t),function Jc(e){return P.lFrame.bindingIndex=e}(e.bindingStartIndex),null!==n&&Rf(e,t,n,2,r);const s=3==(3&o);if(!i)if(s){const u=e.preOrderCheckHooks;null!==u&&Zo(t,u,null)}else{const u=e.preOrderHooks;null!==u&&Yo(t,u,0,null),Xs(t,0)}if(function cw(e){for(let t=Ta(e);null!==t;t=Sa(t)){if(!t[2])continue;const n=t[9];for(let r=0;r<n.length;r++){const o=n[r],i=o[3];0==(1024&o[2])&&Ws(i,1),o[2]|=1024}}}(t),function uw(e){for(let t=Ta(e);null!==t;t=Sa(t))for(let n=10;n<t.length;n++){const r=t[n],o=r[1];qs(r)&&lr(o,r,o.template,r[8])}}(t),null!==e.contentQueries&&Of(e,t),!i)if(s){const u=e.contentCheckHooks;null!==u&&Zo(t,u)}else{const u=e.contentHooks;null!==u&&Yo(t,u,1),Xs(t,1)}!function UD(e,t){const n=e.hostBindingOpCodes;if(null!==n)try{for(let r=0;r<n.length;r++){const o=n[r];if(o<0)ln(~o);else{const i=o,s=n[++r],a=n[++r];yy(s,i),a(2,t[i])}}}finally{ln(-1)}}(e,t);const a=e.components;null!==a&&function zD(e,t){for(let n=0;n<t.length;n++)dw(e,t[n])}(t,a);const l=e.viewQuery;if(null!==l&&ol(2,l,r),!i)if(s){const u=e.viewCheckHooks;null!==u&&Zo(t,u)}else{const u=e.viewHooks;null!==u&&Yo(t,u,2),Xs(t,2)}!0===e.firstUpdatePass&&(e.firstUpdatePass=!1),i||(t[2]&=-73),1024&t[2]&&(t[2]&=-1025,Ws(t[3],-1))}finally{Wo()}}function qD(e,t,n,r){const o=t[10],i=!zo(),s=function Qc(e){return 4==(4&e[2])}(t);try{i&&!s&&o.begin&&o.begin(),s&&ro(e,t,r),lr(e,t,n,r)}finally{i&&!s&&o.end&&o.end()}}function Rf(e,t,n,r,o){const i=je(),s=2&r;try{ln(-1),s&&t.length>20&&wf(e,t,20,zo()),n(r,o)}finally{ln(i)}}function Pf(e,t,n){if(Ls(t)){const o=t.directiveEnd;for(let i=t.directiveStart;i<o;i++){const s=e.data[i];s.contentQueries&&s.contentQueries(1,n[i],i)}}}function Ya(e,t,n){!Yc()||(function tw(e,t,n,r){const o=n.directiveStart,i=n.directiveEnd;e.firstCreatePass||Hr(n,t),Re(r,t);const s=n.initialInputs;for(let a=o;a<i;a++){const l=e.data[a],u=vt(l);u&&sw(t,n,l);const c=jr(t,e,a,n);Re(c,t),null!==s&&aw(0,a-o,c,l,0,s),u&&(Xe(n.index,t)[8]=c)}}(e,t,n,lt(n,t)),128==(128&n.flags)&&function nw(e,t,n){const r=n.directiveStart,o=n.directiveEnd,s=n.index,a=function Cy(){return P.lFrame.currentDirectiveIndex}();try{ln(s);for(let l=r;l<o;l++){const u=e.data[l],c=t[l];Ys(l),(null!==u.hostBindings||0!==u.hostVars||null!==u.hostAttrs)&&Uf(u,c)}}finally{ln(-1),Ys(a)}}(e,t,n))}function Ka(e,t,n=lt){const r=t.localNames;if(null!==r){let o=t.index+1;for(let i=0;i<r.length;i+=2){const s=r[i+1],a=-1===s?n(t,e):e[s];e[o++]=a}}}function Vf(e){const t=e.tView;return null===t||t.incompleteFirstPass?e.tView=yi(1,null,e.template,e.decls,e.vars,e.directiveDefs,e.pipeDefs,e.viewQuery,e.schemas,e.consts):t}function yi(e,t,n,r,o,i,s,a,l,u){const c=20+r,d=c+o,f=function WD(e,t){const n=[];for(let r=0;r<t;r++)n.push(r<e?null:L);return n}(c,d),p="function"==typeof u?u():u;return f[1]={type:e,blueprint:f,template:n,queries:null,viewQuery:a,declTNode:t,data:f.slice().fill(null,c),bindingStartIndex:c,expandoStartIndex:d,hostBindingOpCodes:null,firstCreatePass:!0,firstUpdatePass:!0,staticViewQueries:!1,staticContentQueries:!1,preOrderHooks:null,preOrderCheckHooks:null,contentHooks:null,contentCheckHooks:null,viewHooks:null,viewCheckHooks:null,destroyHooks:null,cleanup:null,contentQueries:null,components:null,directiveRegistry:"function"==typeof i?i():i,pipeRegistry:"function"==typeof s?s():s,firstChild:null,schemas:l,consts:p,incompleteFirstPass:!1}}function Hf(e,t,n){for(let r in e)if(e.hasOwnProperty(r)){const o=e[r];(n=null===n?{}:n).hasOwnProperty(r)?n[r].push(t,o):n[r]=[t,o]}return n}function nt(e,t,n,r,o,i,s,a){const l=lt(t,n);let c,u=t.inputs;!a&&null!=u&&(c=u[r])?(Xf(e,n,c,r,o),jo(t)&&function KD(e,t){const n=Xe(t,e);16&n[2]||(n[2]|=64)}(n,t.index)):3&t.type&&(r=function YD(e){return"class"===e?"className":"for"===e?"htmlFor":"formaction"===e?"formAction":"innerHtml"===e?"innerHTML":"readonly"===e?"readOnly":"tabindex"===e?"tabIndex":e}(r),o=null!=s?s(o,t.value||"",r):o,me(i)?i.setProperty(l,r,o):ta(r)||(l.setProperty?l.setProperty(r,o):l[r]=o))}function Ja(e,t,n,r){let o=!1;if(Yc()){const i=function rw(e,t,n){const r=e.directiveRegistry;let o=null;if(r)for(let i=0;i<r.length;i++){const s=r[i];Cf(n,s.selectors,!1)&&(o||(o=[]),ti(Hr(n,t),e,s.type),vt(s)?(zf(e,n),o.unshift(s)):o.push(s))}return o}(e,t,n),s=null===r?null:{"":-1};if(null!==i){o=!0,Gf(n,e.data.length,i.length);for(let c=0;c<i.length;c++){const d=i[c];d.providersResolver&&d.providersResolver(d)}let a=!1,l=!1,u=ar(e,t,i.length,null);for(let c=0;c<i.length;c++){const d=i[c];n.mergedAttrs=Jo(n.mergedAttrs,d.hostAttrs),qf(e,n,t,u,d),iw(u,d,s),null!==d.contentQueries&&(n.flags|=8),(null!==d.hostBindings||null!==d.hostAttrs||0!==d.hostVars)&&(n.flags|=128);const f=d.type.prototype;!a&&(f.ngOnChanges||f.ngOnInit||f.ngDoCheck)&&((e.preOrderHooks||(e.preOrderHooks=[])).push(n.index),a=!0),!l&&(f.ngOnChanges||f.ngDoCheck)&&((e.preOrderCheckHooks||(e.preOrderCheckHooks=[])).push(n.index),l=!0),u++}!function ZD(e,t){const r=t.directiveEnd,o=e.data,i=t.attrs,s=[];let a=null,l=null;for(let u=t.directiveStart;u<r;u++){const c=o[u],d=c.inputs,f=null===i||yf(t)?null:lw(d,i);s.push(f),a=Hf(d,u,a),l=Hf(c.outputs,u,l)}null!==a&&(a.hasOwnProperty("class")&&(t.flags|=16),a.hasOwnProperty("style")&&(t.flags|=32)),t.initialInputs=s,t.inputs=a,t.outputs=l}(e,n)}s&&function ow(e,t,n){if(t){const r=e.localNames=[];for(let o=0;o<t.length;o+=2){const i=n[t[o+1]];if(null==i)throw new Y(-301,!1);r.push(t[o],i)}}}(n,r,s)}return n.mergedAttrs=Jo(n.mergedAttrs,n.attrs),o}function $f(e,t,n,r,o,i){const s=i.hostBindings;if(s){let a=e.hostBindingOpCodes;null===a&&(a=e.hostBindingOpCodes=[]);const l=~t.index;(function ew(e){let t=e.length;for(;t>0;){const n=e[--t];if("number"==typeof n&&n<0)return n}return 0})(a)!=l&&a.push(l),a.push(r,o,s)}}function Uf(e,t){null!==e.hostBindings&&e.hostBindings(1,t)}function zf(e,t){t.flags|=2,(e.components||(e.components=[])).push(t.index)}function iw(e,t,n){if(n){if(t.exportAs)for(let r=0;r<t.exportAs.length;r++)n[t.exportAs[r]]=e;vt(t)&&(n[""]=e)}}function Gf(e,t,n){e.flags|=1,e.directiveStart=t,e.directiveEnd=t+n,e.providerIndexes=t}function qf(e,t,n,r,o){e.data[r]=o;const i=o.factory||(o.factory=An(o.type)),s=new Lr(i,vt(o),null);e.blueprint[r]=s,n[r]=s,$f(e,t,0,r,ar(e,n,o.hostVars,L),o)}function sw(e,t,n){const r=lt(t,e),o=Vf(n),i=e[10],s=Ci(e,no(e,o,null,n.onPush?64:16,r,t,i,i.createRenderer(r,n),null,null));e[t.index]=s}function Pt(e,t,n,r,o,i){const s=lt(e,t);!function Xa(e,t,n,r,o,i,s){if(null==i)me(e)?e.removeAttribute(t,o,n):t.removeAttribute(o);else{const a=null==s?V(i):s(i,r||"",o);me(e)?e.setAttribute(t,o,a,n):n?t.setAttributeNS(n,o,a):t.setAttribute(o,a)}}(t[j],s,i,e.value,n,r,o)}function aw(e,t,n,r,o,i){const s=i[t];if(null!==s){const a=r.setInput;for(let l=0;l<s.length;){const u=s[l++],c=s[l++],d=s[l++];null!==a?r.setInput(n,d,u,c):n[c]=d}}}function lw(e,t){let n=null,r=0;for(;r<t.length;){const o=t[r];if(0!==o)if(5!==o){if("number"==typeof o)break;e.hasOwnProperty(o)&&(null===n&&(n=[]),n.push(o,e[o],t[r+1])),r+=2}else r+=2;else r+=4}return n}function Wf(e,t,n,r){return new Array(e,!0,!1,t,null,0,r,n,null,null)}function dw(e,t){const n=Xe(t,e);if(qs(n)){const r=n[1];80&n[2]?lr(r,n,r.template,n[8]):n[5]>0&&el(n)}}function el(e){for(let r=Ta(e);null!==r;r=Sa(r))for(let o=10;o<r.length;o++){const i=r[o];if(1024&i[2]){const s=i[1];lr(s,i,s.template,i[8])}else i[5]>0&&el(i)}const n=e[1].components;if(null!==n)for(let r=0;r<n.length;r++){const o=Xe(n[r],e);qs(o)&&o[5]>0&&el(o)}}function fw(e,t){const n=Xe(t,e),r=n[1];(function hw(e,t){for(let n=t.length;n<e.blueprint.length;n++)t.push(e.blueprint[n])})(r,n),ro(r,n,n[8])}function Ci(e,t){return e[13]?e[14][4]=t:e[13]=t,e[14]=t,t}function tl(e){for(;e;){e[2]|=64;const t=eo(e);if(Yv(e)&&!t)return e;e=t}return null}function rl(e,t,n){const r=t[10];r.begin&&r.begin();try{lr(e,t,e.template,n)}catch(o){throw Jf(t,o),o}finally{r.end&&r.end()}}function Qf(e){!function nl(e){for(let t=0;t<e.components.length;t++){const n=e.components[t],r=wa(n),o=r[1];qD(o,r,o.template,n)}}(e[8])}function ol(e,t,n){Js(0),t(e,n)}const _w=(()=>Promise.resolve(null))();function Zf(e){return e[7]||(e[7]=[])}function Yf(e){return e.cleanup||(e.cleanup=[])}function Jf(e,t){const n=e[9],r=n?n.get(Xr,null):null;r&&r.handleError(t)}function Xf(e,t,n,r,o){for(let i=0;i<n.length;){const s=n[i++],a=n[i++],l=t[s],u=e.data[s];null!==u.setInput?u.setInput(l,o,r,a):l[a]=o}}function Kt(e,t,n){const r=Uo(t,e);!function tf(e,t,n){me(e)?e.setValue(t,n):t.textContent=n}(e[j],r,n)}function Di(e,t,n){let r=n?e.styles:null,o=n?e.classes:null,i=0;if(null!==t)for(let s=0;s<t.length;s++){const a=t[s];"number"==typeof a?i=a:1==i?o=Ss(o,a):2==i&&(r=Ss(r,a+": "+t[++s]+";"))}n?e.styles=r:e.stylesWithoutHost=r,n?e.classes=o:e.classesWithoutHost=o}const il=new J("INJECTOR",-1);class eh{get(t,n=Gr){if(n===Gr){const r=new Error(`NullInjectorError: No provider for ${te(t)}!`);throw r.name="NullInjectorError",r}return n}}const sl=new J("Set Injector scope."),oo={},Cw={};let al;function th(){return void 0===al&&(al=new eh),al}function nh(e,t=null,n=null,r){const o=rh(e,t,n,r);return o._resolveInjectorDefTypes(),o}function rh(e,t=null,n=null,r){return new Dw(e,n,t||th(),r)}class Dw{constructor(t,n,r,o=null){this.parent=r,this.records=new Map,this.injectorDefTypes=new Set,this.onDestroy=new Set,this._destroyed=!1;const i=[];n&&Ft(n,a=>this.processProvider(a,t,n)),Ft([t],a=>this.processInjectorType(a,[],i)),this.records.set(il,ur(void 0,this));const s=this.records.get(sl);this.scope=null!=s?s.value:null,this.source=o||("object"==typeof t?null:te(t))}get destroyed(){return this._destroyed}destroy(){this.assertNotDestroyed(),this._destroyed=!0;try{this.onDestroy.forEach(t=>t.ngOnDestroy())}finally{this.records.clear(),this.onDestroy.clear(),this.injectorDefTypes.clear()}}get(t,n=Gr,r=B.Default){this.assertNotDestroyed();const o=Id(this),i=tn(void 0);try{if(!(r&B.SkipSelf)){let a=this.records.get(t);if(void 0===a){const l=function Sw(e){return"function"==typeof e||"object"==typeof e&&e instanceof J}(t)&&Ns(t);a=l&&this.injectableDefInScope(l)?ur(ll(t),oo):null,this.records.set(t,a)}if(null!=a)return this.hydrate(t,a)}return(r&B.Self?th():this.parent).get(t,n=r&B.Optional&&n===Gr?null:n)}catch(s){if("NullInjectorError"===s.name){if((s[ii]=s[ii]||[]).unshift(te(t)),o)throw s;return function rC(e,t,n,r){const o=e[ii];throw t[Md]&&o.unshift(t[Md]),e.message=function oC(e,t,n,r=null){e=e&&"\n"===e.charAt(0)&&"\u0275"==e.charAt(1)?e.substr(2):e;let o=te(t);if(Array.isArray(t))o=t.map(te).join(" -> ");else if("object"==typeof t){let i=[];for(let s in t)if(t.hasOwnProperty(s)){let a=t[s];i.push(s+":"+("string"==typeof a?JSON.stringify(a):te(a)))}o=`{${i.join(", ")}}`}return`${n}${r?"("+r+")":""}[${o}]: ${e.replace(Ky,"\n  ")}`}("\n"+e.message,o,n,r),e.ngTokenPath=o,e[ii]=null,e}(s,t,"R3InjectorError",this.source)}throw s}finally{tn(i),Id(o)}}_resolveInjectorDefTypes(){this.injectorDefTypes.forEach(t=>this.get(t))}toString(){const t=[];return this.records.forEach((r,o)=>t.push(te(o))),`R3Injector[${t.join(", ")}]`}assertNotDestroyed(){if(this._destroyed)throw new Y(205,!1)}processInjectorType(t,n,r){if(!(t=H(t)))return!1;let o=Pc(t);const i=null==o&&t.ngModule||void 0,s=void 0===i?t:i,a=-1!==r.indexOf(s);if(void 0!==i&&(o=Pc(i)),null==o)return!1;if(null!=o.imports&&!a){let c;r.push(s);try{Ft(o.imports,d=>{this.processInjectorType(d,n,r)&&(void 0===c&&(c=[]),c.push(d))})}finally{}if(void 0!==c)for(let d=0;d<c.length;d++){const{ngModule:f,providers:p}=c[d];Ft(p,m=>this.processProvider(m,f,p||se))}}this.injectorDefTypes.add(s);const l=An(s)||(()=>new s);this.records.set(s,ur(l,oo));const u=o.providers;if(null!=u&&!a){const c=t;Ft(u,d=>this.processProvider(d,c,u))}return void 0!==i&&void 0!==t.providers}processProvider(t,n,r){let o=cr(t=H(t))?t:H(t&&t.provide);const i=function bw(e,t,n){return ih(e)?ur(void 0,e.useValue):ur(oh(e),oo)}(t);if(cr(t)||!0!==t.multi)this.records.get(o);else{let s=this.records.get(o);s||(s=ur(void 0,oo,!0),s.factory=()=>fa(s.multi),this.records.set(o,s)),o=t,s.multi.push(t)}this.records.set(o,i)}hydrate(t,n){return n.value===oo&&(n.value=Cw,n.value=n.factory()),"object"==typeof n.value&&n.value&&function Tw(e){return null!==e&&"object"==typeof e&&"function"==typeof e.ngOnDestroy}(n.value)&&this.onDestroy.add(n.value),n.value}injectableDefInScope(t){if(!t.providedIn)return!1;const n=H(t.providedIn);return"string"==typeof n?"any"===n||n===this.scope:this.injectorDefTypes.has(n)}}function ll(e){const t=Ns(e),n=null!==t?t.factory:An(e);if(null!==n)return n;if(e instanceof J)throw new Y(204,!1);if(e instanceof Function)return function ww(e){const t=e.length;if(t>0)throw function zr(e,t){const n=[];for(let r=0;r<e;r++)n.push(t);return n}(t,"?"),new Y(204,!1);const n=function kv(e){const t=e&&(e[Vo]||e[Vc]);if(t){const n=function Lv(e){if(e.hasOwnProperty("name"))return e.name;const t=(""+e).match(/^function\s*([^\s(]+)/);return null===t?"":t[1]}(e);return console.warn(`DEPRECATED: DI is instantiating a token "${n}" that inherits its @Injectable decorator but does not provide one itself.\nThis will become an error in a future version of Angular. Please add @Injectable() to the "${n}" class.`),t}return null}(e);return null!==n?()=>n.factory(e):()=>new e}(e);throw new Y(204,!1)}function oh(e,t,n){let r;if(cr(e)){const o=H(e);return An(o)||ll(o)}if(ih(e))r=()=>H(e.useValue);else if(function Mw(e){return!(!e||!e.useFactory)}(e))r=()=>e.useFactory(...fa(e.deps||[]));else if(function Ew(e){return!(!e||!e.useExisting)}(e))r=()=>oe(H(e.useExisting));else{const o=H(e&&(e.useClass||e.provide));if(!function Aw(e){return!!e.deps}(e))return An(o)||ll(o);r=()=>new o(...fa(e.deps))}return r}function ur(e,t,n=!1){return{factory:e,value:t,multi:n?[]:void 0}}function ih(e){return null!==e&&"object"==typeof e&&Xy in e}function cr(e){return"function"==typeof e}let ct=(()=>{class e{static create(n,r){var o;if(Array.isArray(n))return nh({name:""},r,n,"");{const i=null!==(o=n.name)&&void 0!==o?o:"";return nh({name:i},n.parent,n.providers,i)}}}return e.THROW_IF_NOT_FOUND=Gr,e.NULL=new eh,e.\u0275prov=de({token:e,providedIn:"any",factory:()=>oe(il)}),e.__NG_ELEMENT_ID__=-1,e})();function kw(e,t){Qo(wa(e)[1],Me())}function ne(e){let t=function _h(e){return Object.getPrototypeOf(e.prototype).constructor}(e.type),n=!0;const r=[e];for(;t;){let o;if(vt(e))o=t.\u0275cmp||t.\u0275dir;else{if(t.\u0275cmp)throw new Y(903,"");o=t.\u0275dir}if(o){if(n){r.push(o);const s=e;s.inputs=dl(e.inputs),s.declaredInputs=dl(e.declaredInputs),s.outputs=dl(e.outputs);const a=o.hostBindings;a&&jw(e,a);const l=o.viewQuery,u=o.contentQueries;if(l&&Bw(e,l),u&&Hw(e,u),Ts(e.inputs,o.inputs),Ts(e.declaredInputs,o.declaredInputs),Ts(e.outputs,o.outputs),vt(o)&&o.data.animation){const c=e.data;c.animation=(c.animation||[]).concat(o.data.animation)}}const i=o.features;if(i)for(let s=0;s<i.length;s++){const a=i[s];a&&a.ngInherit&&a(e),a===ne&&(n=!1)}}t=Object.getPrototypeOf(t)}!function Lw(e){let t=0,n=null;for(let r=e.length-1;r>=0;r--){const o=e[r];o.hostVars=t+=o.hostVars,o.hostAttrs=Jo(o.hostAttrs,n=Jo(n,o.hostAttrs))}}(r)}function dl(e){return e===Hn?{}:e===se?[]:e}function Bw(e,t){const n=e.viewQuery;e.viewQuery=n?(r,o)=>{t(r,o),n(r,o)}:t}function Hw(e,t){const n=e.contentQueries;e.contentQueries=n?(r,o,i)=>{t(r,o,i),n(r,o,i)}:t}function jw(e,t){const n=e.hostBindings;e.hostBindings=n?(r,o)=>{t(r,o),n(r,o)}:t}let wi=null;function dr(){if(!wi){const e=re.Symbol;if(e&&e.iterator)wi=e.iterator;else{const t=Object.getOwnPropertyNames(Map.prototype);for(let n=0;n<t.length;++n){const r=t[n];"entries"!==r&&"size"!==r&&Map.prototype[r]===Map.prototype.entries&&(wi=r)}}}return wi}function io(e){return!!fl(e)&&(Array.isArray(e)||!(e instanceof Map)&&dr()in e)}function fl(e){return null!==e&&("function"==typeof e||"object"==typeof e)}function Vt(e,t,n){return e[t]=n}function Pe(e,t,n){return!Object.is(e[t],n)&&(e[t]=n,!0)}function Sn(e,t,n,r){const o=Pe(e,t,n);return Pe(e,t+1,r)||o}function kt(e,t,n,r){const o=w();return Pe(o,qn(),t)&&(K(),Pt(_e(),o,e,t,n,r)),kt}function hr(e,t,n,r){return Pe(e,qn(),n)?t+V(n)+r:L}function E(e,t,n,r,o,i,s,a){const l=w(),u=K(),c=e+20,d=u.firstCreatePass?function Qw(e,t,n,r,o,i,s,a,l){const u=t.consts,c=sr(t,e,4,s||null,an(u,a));Ja(t,n,c,an(u,l)),Qo(t,c);const d=c.tViews=yi(2,c,r,o,i,t.directiveRegistry,t.pipeRegistry,null,t.schemas,u);return null!==t.queries&&(t.queries.template(t,c),d.queries=t.queries.embeddedTView(c)),c}(c,u,l,t,n,r,o,i,s):u.data[c];Nt(d,!1);const f=l[j].createComment("");pi(u,l,f,d),Re(f,l),Ci(l,l[c]=Wf(f,l,f,d)),$o(d)&&Ya(u,l,d),null!=s&&Ka(l,d,a)}function A(e,t=B.Default){const n=w();return null===n?oe(e,t):gd(Me(),n,H(e),t)}function g(e,t,n){const r=w();return Pe(r,qn(),t)&&nt(K(),_e(),r,e,t,r[j],n,!1),g}function _l(e,t,n,r,o){const s=o?"class":"style";Xf(e,n,t.inputs[s],s,r)}function y(e,t,n,r){const o=w(),i=K(),s=20+e,a=o[j],l=o[s]=Na(a,t,function Ay(){return P.lFrame.currentNamespace}()),u=i.firstCreatePass?function _b(e,t,n,r,o,i,s){const a=t.consts,u=sr(t,e,2,o,an(a,i));return Ja(t,n,u,an(a,s)),null!==u.attrs&&Di(u,u.attrs,!1),null!==u.mergedAttrs&&Di(u,u.mergedAttrs,!0),null!==t.queries&&t.queries.elementStart(t,u),u}(s,i,o,0,t,n,r):i.data[s];Nt(u,!0);const c=u.mergedAttrs;null!==c&&Ko(a,l,c);const d=u.classes;null!==d&&ka(a,l,d);const f=u.styles;return null!==f&&mf(a,l,f),64!=(64&u.flags)&&pi(i,o,l,u),0===function fy(){return P.lFrame.elementDepthCount}()&&Re(l,o),function hy(){P.lFrame.elementDepthCount++}(),$o(u)&&(Ya(i,o,u),Pf(i,u,o)),null!==r&&Ka(o,u),y}function v(){let e=Me();Qs()?Zs():(e=e.parent,Nt(e,!1));const t=e;!function py(){P.lFrame.elementDepthCount--}();const n=K();return n.firstCreatePass&&(Qo(n,e),Ls(e)&&n.queries.elementEnd(e)),null!=t.classesWithoutHost&&function Fy(e){return 0!=(16&e.flags)}(t)&&_l(n,t,w(),t.classesWithoutHost,!0),null!=t.stylesWithoutHost&&function Oy(e){return 0!=(32&e.flags)}(t)&&_l(n,t,w(),t.stylesWithoutHost,!1),v}function F(e,t,n,r){return y(e,t,n,r),v(),F}function Q(e,t,n){const r=w(),o=K(),i=e+20,s=o.firstCreatePass?function vb(e,t,n,r,o){const i=t.consts,s=an(i,r),a=sr(t,e,8,"ng-container",s);return null!==s&&Di(a,s,!0),Ja(t,n,a,an(i,o)),null!==t.queries&&t.queries.elementStart(t,a),a}(i,o,r,t,n):o.data[i];Nt(s,!0);const a=r[i]=r[j].createComment("");return pi(o,r,a,s),Re(a,r),$o(s)&&(Ya(o,r,s),Pf(o,s,r)),null!=n&&Ka(r,s),Q}function Z(){let e=Me();const t=K();return Qs()?Zs():(e=e.parent,Nt(e,!1)),t.firstCreatePass&&(Qo(t,e),Ls(e)&&t.queries.elementEnd(e)),Z}function rt(){return w()}function Mi(e){return!!e&&"function"==typeof e.then}const Bh=function Lh(e){return!!e&&"function"==typeof e.subscribe};function z(e,t,n,r){const o=w(),i=K(),s=Me();return function jh(e,t,n,r,o,i,s,a){const l=$o(r),c=e.firstCreatePass&&Yf(e),d=t[8],f=Zf(t);let p=!0;if(3&r.type||a){const M=lt(r,t),I=a?a(M):M,_=f.length,N=a?U=>a(De(U[r.index])):r.index;if(me(n)){let U=null;if(!a&&l&&(U=function yb(e,t,n,r){const o=e.cleanup;if(null!=o)for(let i=0;i<o.length-1;i+=2){const s=o[i];if(s===n&&o[i+1]===r){const a=t[7],l=o[i+2];return a.length>l?a[l]:null}"string"==typeof s&&(i+=2)}return null}(e,t,o,r.index)),null!==U)(U.__ngLastListenerFn__||U).__ngNextListenerFn__=i,U.__ngLastListenerFn__=i,p=!1;else{i=vl(r,t,d,i,!1);const X=n.listen(I,o,i);f.push(i,X),c&&c.push(o,N,_,_+1)}}else i=vl(r,t,d,i,!0),I.addEventListener(o,i,s),f.push(i),c&&c.push(o,N,_,s)}else i=vl(r,t,d,i,!1);const m=r.outputs;let D;if(p&&null!==m&&(D=m[o])){const M=D.length;if(M)for(let I=0;I<M;I+=2){const ot=t[D[I]][D[I+1]].subscribe(i),kn=f.length;f.push(i,ot),c&&c.push(o,r.index,kn,-(kn+1))}}}(i,o,o[j],s,e,t,!!n,r),z}function $h(e,t,n,r){try{return!1!==n(r)}catch(o){return Jf(e,o),!1}}function vl(e,t,n,r,o){return function i(s){if(s===Function)return r;const a=2&e.flags?Xe(e.index,t):t;0==(32&t[2])&&tl(a);let l=$h(t,0,r,s),u=i.__ngNextListenerFn__;for(;u;)l=$h(t,0,u,s)&&l,u=u.__ngNextListenerFn__;return o&&!1===l&&(s.preventDefault(),s.returnValue=!1),l}}function C(e=1){return function wy(e){return(P.lFrame.contextLView=function by(e,t){for(;e>0;)t=t[15],e--;return t}(e,P.lFrame.contextLView))[8]}(e)}function wr(e,t,n){return yl(e,"",t,"",n),wr}function yl(e,t,n,r,o){const i=w(),s=hr(i,t,n,r);return s!==L&&nt(K(),_e(),i,e,s,i[j],o,!1),yl}function Kh(e,t,n,r,o){const i=e[n+1],s=null===t;let a=r?Ct(i):Yt(i),l=!1;for(;0!==a&&(!1===l||s);){const c=e[a+1];Mb(e[a],t)&&(l=!0,e[a+1]=r?Ha(c):La(c)),a=r?Ct(c):Yt(c)}l&&(e[n+1]=r?La(i):Ha(i))}function Mb(e,t){return null===e||null==t||(Array.isArray(e)?e[1]:e)===t||!(!Array.isArray(e)||"string"!=typeof t)&&er(e,t)>=0}const Ae={textEnd:0,key:0,keyEnd:0,value:0,valueEnd:0};function Jh(e){return e.substring(Ae.key,Ae.keyEnd)}function Xh(e,t){const n=Ae.textEnd;return n===t?-1:(t=Ae.keyEnd=function Sb(e,t,n){for(;t<n&&e.charCodeAt(t)>32;)t++;return t}(e,Ae.key=t,n),br(e,t,n))}function br(e,t,n){for(;t<n&&e.charCodeAt(t)<=32;)t++;return t}function Ii(e,t){return function wt(e,t,n,r){const o=w(),i=K(),s=Zt(2);i.firstUpdatePass&&sp(i,e,s,r),t!==L&&Pe(o,s,t)&&lp(i,i.data[je()],o,o[j],e,o[s+1]=function Hb(e,t){return null==e||("string"==typeof t?e+=t:"object"==typeof e&&(e=te(cn(e)))),e}(t,n),r,s)}(e,t,null,!0),Ii}function Bt(e,t){for(let n=function Ab(e){return function tp(e){Ae.key=0,Ae.keyEnd=0,Ae.value=0,Ae.valueEnd=0,Ae.textEnd=e.length}(e),Xh(e,br(e,0,Ae.textEnd))}(t);n>=0;n=Xh(t,n))et(e,Jh(t),!0)}function ip(e,t){return t>=e.expandoStartIndex}function sp(e,t,n,r){const o=e.data;if(null===o[n+1]){const i=o[je()],s=ip(e,n);cp(i,r)&&null===t&&!s&&(t=!1),t=function Rb(e,t,n,r){const o=function Ks(e){const t=P.lFrame.currentDirectiveIndex;return-1===t?null:e[t]}(e);let i=r?t.residualClasses:t.residualStyles;if(null===o)0===(r?t.classBindings:t.styleBindings)&&(n=ao(n=Cl(null,e,t,n,r),t.attrs,r),i=null);else{const s=t.directiveStylingLast;if(-1===s||e[s]!==o)if(n=Cl(o,e,t,n,r),null===i){let l=function Pb(e,t,n){const r=n?t.classBindings:t.styleBindings;if(0!==Yt(r))return e[Ct(r)]}(e,t,r);void 0!==l&&Array.isArray(l)&&(l=Cl(null,e,t,l[1],r),l=ao(l,t.attrs,r),function Vb(e,t,n,r){e[Ct(n?t.classBindings:t.styleBindings)]=r}(e,t,r,l))}else i=function kb(e,t,n){let r;const o=t.directiveEnd;for(let i=1+t.directiveStylingLast;i<o;i++)r=ao(r,e[i].hostAttrs,n);return ao(r,t.attrs,n)}(e,t,r)}return void 0!==i&&(r?t.residualClasses=i:t.residualStyles=i),n}(o,i,t,r),function bb(e,t,n,r,o,i){let s=i?t.classBindings:t.styleBindings,a=Ct(s),l=Yt(s);e[r]=n;let c,u=!1;if(Array.isArray(n)){const d=n;c=d[1],(null===c||er(d,c)>0)&&(u=!0)}else c=n;if(o)if(0!==l){const f=Ct(e[a+1]);e[r+1]=mi(f,a),0!==f&&(e[f+1]=Ba(e[f+1],r)),e[a+1]=function OD(e,t){return 131071&e|t<<17}(e[a+1],r)}else e[r+1]=mi(a,0),0!==a&&(e[a+1]=Ba(e[a+1],r)),a=r;else e[r+1]=mi(l,0),0===a?a=r:e[l+1]=Ba(e[l+1],r),l=r;u&&(e[r+1]=La(e[r+1])),Kh(e,c,r,!0),Kh(e,c,r,!1),function Eb(e,t,n,r,o){const i=o?e.residualClasses:e.residualStyles;null!=i&&"string"==typeof t&&er(i,t)>=0&&(n[r+1]=Ha(n[r+1]))}(t,c,e,r,i),s=mi(a,l),i?t.classBindings=s:t.styleBindings=s}(o,i,t,n,s,r)}}function Cl(e,t,n,r,o){let i=null;const s=n.directiveEnd;let a=n.directiveStylingLast;for(-1===a?a=n.directiveStart:a++;a<s&&(i=t[a],r=ao(r,i.hostAttrs,o),i!==e);)a++;return null!==e&&(n.directiveStylingLast=a),r}function ao(e,t,n){const r=n?1:2;let o=-1;if(null!==t)for(let i=0;i<t.length;i++){const s=t[i];"number"==typeof s?o=s:o===r&&(Array.isArray(e)||(e=void 0===e?[]:["",e]),et(e,s,!!n||t[++i]))}return void 0===e?null:e}function lp(e,t,n,r,o,i,s,a){if(!(3&t.type))return;const l=e.data,u=l[a+1];Ai(function Mf(e){return 1==(1&e)}(u)?up(l,t,n,o,Yt(u),s):void 0)||(Ai(i)||function Ef(e){return 2==(2&e)}(u)&&(i=up(l,null,n,o,a,s)),function DD(e,t,n,r,o){const i=me(e);if(t)o?i?e.addClass(n,r):n.classList.add(r):i?e.removeClass(n,r):n.classList.remove(r);else{let s=-1===r.indexOf("-")?void 0:tt.DashCase;if(null==o)i?e.removeStyle(n,r,s):n.style.removeProperty(r);else{const a="string"==typeof o&&o.endsWith("!important");a&&(o=o.slice(0,-10),s|=tt.Important),i?e.setStyle(n,r,o,s):n.style.setProperty(r,o,a?"important":"")}}}(r,s,Uo(je(),n),o,i))}function up(e,t,n,r,o,i){const s=null===t;let a;for(;o>0;){const l=e[o],u=Array.isArray(l),c=u?l[1]:l,d=null===c;let f=n[o+1];f===L&&(f=d?se:void 0);let p=d?ua(f,r):c===r?f:void 0;if(u&&!Ai(p)&&(p=ua(l,r)),Ai(p)&&(a=p,s))return a;const m=e[o+1];o=s?Ct(m):Yt(m)}if(null!==t){let l=i?t.residualClasses:t.residualStyles;null!=l&&(a=ua(l,r))}return a}function Ai(e){return void 0!==e}function cp(e,t){return 0!=(e.flags&(t?16:32))}function b(e,t=""){const n=w(),r=K(),o=e+20,i=r.firstCreatePass?sr(r,o,1,t,null):r.data[o],s=n[o]=function xa(e,t){return me(e)?e.createText(t):e.createTextNode(t)}(n[j],t);pi(r,n,s,i),Nt(i,!1)}function x(e){return q("",e,""),x}function q(e,t,n){const r=w(),o=hr(r,e,t,n);return o!==L&&Kt(r,je(),o),q}function Ht(e,t,n){!function bt(e,t,n,r){const o=K(),i=Zt(2);o.firstUpdatePass&&sp(o,null,i,r);const s=w();if(n!==L&&Pe(s,i,n)){const a=o.data[je()];if(cp(a,r)&&!ip(o,i)){let l=r?a.classesWithoutHost:a.stylesWithoutHost;null!==l&&(n=Ss(l,n||"")),_l(o,a,s,n,r)}else!function Bb(e,t,n,r,o,i,s,a){o===L&&(o=se);let l=0,u=0,c=0<o.length?o[0]:null,d=0<i.length?i[0]:null;for(;null!==c||null!==d;){const f=l<o.length?o[l+1]:void 0,p=u<i.length?i[u+1]:void 0;let D,m=null;c===d?(l+=2,u+=2,f!==p&&(m=d,D=p)):null===d||null!==c&&c<d?(l+=2,m=c):(u+=2,m=d,D=p),null!==m&&lp(e,t,n,r,m,D,s,a),c=l<o.length?o[l]:null,d=u<i.length?i[u]:null}}(o,a,s,s[j],s[i+1],s[i+1]=function Lb(e,t,n){if(null==n||""===n)return se;const r=[],o=cn(n);if(Array.isArray(o))for(let i=0;i<o.length;i++)e(r,o[i],!0);else if("object"==typeof o)for(const i in o)o.hasOwnProperty(i)&&e(r,i,o[i]);else"string"==typeof o&&t(r,o);return r}(e,t,n),r,i)}}(et,Bt,hr(w(),e,t,n),!0)}const Ti="en-US";let Fp=Ti;function bl(e,t,n,r,o){if(e=H(e),Array.isArray(e))for(let i=0;i<e.length;i++)bl(e[i],t,n,r,o);else{const i=K(),s=w();let a=cr(e)?e:H(e.provide),l=oh(e);const u=Me(),c=1048575&u.providerIndexes,d=u.directiveStart,f=u.providerIndexes>>20;if(cr(e)||!e.multi){const p=new Lr(l,o,A),m=Ml(a,t,o?c:c+f,d);-1===m?(ti(Hr(u,s),i,a),El(i,e,t.length),t.push(a),u.directiveStart++,u.directiveEnd++,o&&(u.providerIndexes+=1048576),n.push(p),s.push(p)):(n[m]=p,s[m]=p)}else{const p=Ml(a,t,c+f,d),m=Ml(a,t,c,c+f),D=p>=0&&n[p],M=m>=0&&n[m];if(o&&!M||!o&&!D){ti(Hr(u,s),i,a);const I=function iE(e,t,n,r,o){const i=new Lr(e,n,A);return i.multi=[],i.index=t,i.componentProviders=0,ng(i,o,r&&!n),i}(o?oE:rE,n.length,o,r,l);!o&&M&&(n[m].providerFactory=I),El(i,e,t.length,0),t.push(a),u.directiveStart++,u.directiveEnd++,o&&(u.providerIndexes+=1048576),n.push(I),s.push(I)}else El(i,e,p>-1?p:m,ng(n[o?m:p],l,!o&&r));!o&&r&&M&&n[m].componentProviders++}}}function El(e,t,n,r){const o=cr(t),i=function Iw(e){return!!e.useClass}(t);if(o||i){const l=(i?H(t.useClass):t).prototype.ngOnDestroy;if(l){const u=e.destroyHooks||(e.destroyHooks=[]);if(!o&&t.multi){const c=u.indexOf(n);-1===c?u.push(n,[r,l]):u[c+1].push(r,l)}else u.push(n,l)}}}function ng(e,t,n){return n&&e.componentProviders++,e.multi.push(t)-1}function Ml(e,t,n,r){for(let o=n;o<r;o++)if(t[o]===e)return o;return-1}function rE(e,t,n,r){return Il(this.multi,[])}function oE(e,t,n,r){const o=this.multi;let i;if(this.providerFactory){const s=this.providerFactory.componentProviders,a=jr(n,n[1],this.providerFactory.index,r);i=a.slice(0,s),Il(o,i);for(let l=s;l<a.length;l++)i.push(a[l])}else i=[],Il(o,i);return i}function Il(e,t){for(let n=0;n<e.length;n++)t.push((0,e[n])());return t}function he(e,t=[]){return n=>{n.providersResolver=(r,o)=>function nE(e,t,n){const r=K();if(r.firstCreatePass){const o=vt(e);bl(n,r.data,r.blueprint,o,!0),bl(t,r.data,r.blueprint,o,!1)}}(r,o?o(e):e,t)}}class rg{}class lE{resolveComponentFactory(t){throw function aE(e){const t=Error(`No component factory found for ${te(e)}. Did you add it to @NgModule.entryComponents?`);return t.ngComponent=e,t}(t)}}let Oi=(()=>{class e{}return e.NULL=new lE,e})();function uE(){return Ir(Me(),w())}function Ir(e,t){return new Et(lt(e,t))}let Et=(()=>{class e{constructor(n){this.nativeElement=n}}return e.__NG_ELEMENT_ID__=uE,e})();class ig{}let Nn=(()=>{class e{}return e.__NG_ELEMENT_ID__=()=>function fE(){const e=w(),n=Xe(Me().index,e);return function dE(e){return e[j]}(xt(n)?n:e)}(),e})(),hE=(()=>{class e{}return e.\u0275prov=de({token:e,providedIn:"root",factory:()=>null}),e})();class Ri{constructor(t){this.full=t,this.major=t.split(".")[0],this.minor=t.split(".")[1],this.patch=t.split(".").slice(2).join(".")}}const pE=new Ri("13.3.0"),Al={};function Pi(e,t,n,r,o=!1){for(;null!==n;){const i=t[n.index];if(null!==i&&r.push(De(i)),_t(i))for(let a=10;a<i.length;a++){const l=i[a],u=l[1].firstChild;null!==u&&Pi(l[1],l,u,r)}const s=n.type;if(8&s)Pi(e,t,n.child,r);else if(32&s){const a=Aa(n,t);let l;for(;l=a();)r.push(l)}else if(16&s){const a=hf(t,n);if(Array.isArray(a))r.push(...a);else{const l=eo(t[16]);Pi(l[1],l,a,r,!0)}}n=o?n.projectionNext:n.next}return r}class ho{constructor(t,n){this._lView=t,this._cdRefInjectingView=n,this._appRef=null,this._attachedToViewContainer=!1}get rootNodes(){const t=this._lView,n=t[1];return Pi(n,t,n.firstChild,[])}get context(){return this._lView[8]}set context(t){this._lView[8]=t}get destroyed(){return 256==(256&this._lView[2])}destroy(){if(this._appRef)this._appRef.detachView(this);else if(this._attachedToViewContainer){const t=this._lView[3];if(_t(t)){const n=t[8],r=n?n.indexOf(this):-1;r>-1&&(Fa(t,r),ri(n,r))}this._attachedToViewContainer=!1}rf(this._lView[1],this._lView)}onDestroy(t){!function Bf(e,t,n,r){const o=Zf(t);null===n?o.push(r):(o.push(n),e.firstCreatePass&&Yf(e).push(r,o.length-1))}(this._lView[1],this._lView,null,t)}markForCheck(){tl(this._cdRefInjectingView||this._lView)}detach(){this._lView[2]&=-129}reattach(){this._lView[2]|=128}detectChanges(){rl(this._lView[1],this._lView,this.context)}checkNoChanges(){!function gw(e,t,n){Go(!0);try{rl(e,t,n)}finally{Go(!1)}}(this._lView[1],this._lView,this.context)}attachToViewContainerRef(){if(this._appRef)throw new Y(902,"");this._attachedToViewContainer=!0}detachFromAppRef(){this._appRef=null,function dD(e,t){to(e,t,t[j],2,null,null)}(this._lView[1],this._lView)}attachToAppRef(t){if(this._attachedToViewContainer)throw new Y(902,"");this._appRef=t}}class gE extends ho{constructor(t){super(t),this._view=t}detectChanges(){Qf(this._view)}checkNoChanges(){!function mw(e){Go(!0);try{Qf(e)}finally{Go(!1)}}(this._view)}get context(){return null}}class sg extends Oi{constructor(t){super(),this.ngModule=t}resolveComponentFactory(t){const n=Ne(t);return new Tl(n,this.ngModule)}}function ag(e){const t=[];for(let n in e)e.hasOwnProperty(n)&&t.push({propName:e[n],templateName:n});return t}class Tl extends rg{constructor(t,n){super(),this.componentDef=t,this.ngModule=n,this.componentType=t.type,this.selector=function ND(e){return e.map(xD).join(",")}(t.selectors),this.ngContentSelectors=t.ngContentSelectors?t.ngContentSelectors:[],this.isBoundToModule=!!n}get inputs(){return ag(this.componentDef.inputs)}get outputs(){return ag(this.componentDef.outputs)}create(t,n,r,o){const i=(o=o||this.ngModule)?function _E(e,t){return{get:(n,r,o)=>{const i=e.get(n,Al,o);return i!==Al||r===Al?i:t.get(n,r,o)}}}(t,o.injector):t,s=i.get(ig,Wc),a=i.get(hE,null),l=s.createRenderer(null,this.componentDef),u=this.componentDef.selectors[0][0]||"div",c=r?function Lf(e,t,n){if(me(e))return e.selectRootElement(t,n===St.ShadowDom);let r="string"==typeof t?e.querySelector(t):t;return r.textContent="",r}(l,r,this.componentDef.encapsulation):Na(s.createRenderer(null,this.componentDef),u,function mE(e){const t=e.toLowerCase();return"svg"===t?"svg":"math"===t?"math":null}(u)),d=this.componentDef.onPush?576:528,f=function mh(e,t){return{components:[],scheduler:e||oD,clean:_w,playerHandler:t||null,flags:0}}(),p=yi(0,null,null,1,0,null,null,null,null,null),m=no(null,p,f,d,null,null,s,l,a,i);let D,M;qo(m);try{const I=function ph(e,t,n,r,o,i){const s=n[1];n[20]=e;const l=sr(s,20,2,"#host",null),u=l.mergedAttrs=t.hostAttrs;null!==u&&(Di(l,u,!0),null!==e&&(Ko(o,e,u),null!==l.classes&&ka(o,e,l.classes),null!==l.styles&&mf(o,e,l.styles)));const c=r.createRenderer(e,t),d=no(n,Vf(t),null,t.onPush?64:16,n[20],l,r,c,i||null,null);return s.firstCreatePass&&(ti(Hr(l,n),s,t.type),zf(s,l),Gf(l,n.length,1)),Ci(n,d),n[20]=d}(c,this.componentDef,m,s,l);if(c)if(r)Ko(l,c,["ng-version",pE.full]);else{const{attrs:_,classes:N}=function FD(e){const t=[],n=[];let r=1,o=2;for(;r<e.length;){let i=e[r];if("string"==typeof i)2===o?""!==i&&t.push(i,e[++r]):8===o&&n.push(i);else{if(!yt(o))break;o=i}r++}return{attrs:t,classes:n}}(this.componentDef.selectors[0]);_&&Ko(l,c,_),N&&N.length>0&&ka(l,c,N.join(" "))}if(M=Gs(p,20),void 0!==n){const _=M.projection=[];for(let N=0;N<this.ngContentSelectors.length;N++){const U=n[N];_.push(null!=U?Array.from(U):null)}}D=function gh(e,t,n,r,o){const i=n[1],s=function XD(e,t,n){const r=Me();e.firstCreatePass&&(n.providersResolver&&n.providersResolver(n),qf(e,r,t,ar(e,t,1,null),n));const o=jr(t,e,r.directiveStart,r);Re(o,t);const i=lt(r,t);return i&&Re(i,t),o}(i,n,t);if(r.components.push(s),e[8]=s,o&&o.forEach(l=>l(s,t)),t.contentQueries){const l=Me();t.contentQueries(1,s,l.directiveStart)}const a=Me();return!i.firstCreatePass||null===t.hostBindings&&null===t.hostAttrs||(ln(a.index),$f(n[1],a,0,a.directiveStart,a.directiveEnd,t),Uf(t,s)),s}(I,this.componentDef,m,f,[kw]),ro(p,m,null)}finally{Wo()}return new yE(this.componentType,D,Ir(M,m),m,M)}}class yE extends class sE{}{constructor(t,n,r,o,i){super(),this.location=r,this._rootLView=o,this._tNode=i,this.instance=n,this.hostView=this.changeDetectorRef=new gE(o),this.componentType=t}get injector(){return new Zn(this._tNode,this._rootLView)}destroy(){this.hostView.destroy()}onDestroy(t){this.hostView.onDestroy(t)}}class Ar{}const Tr=new Map;class cg extends Ar{constructor(t,n){super(),this._parent=n,this._bootstrapComponents=[],this.injector=this,this.destroyCbs=[],this.componentFactoryResolver=new sg(this);const r=it(t);this._bootstrapComponents=Rt(r.bootstrap),this._r3Injector=rh(t,n,[{provide:Ar,useValue:this},{provide:Oi,useValue:this.componentFactoryResolver}],te(t)),this._r3Injector._resolveInjectorDefTypes(),this.instance=this.get(t)}get(t,n=ct.THROW_IF_NOT_FOUND,r=B.Default){return t===ct||t===Ar||t===il?this:this._r3Injector.get(t,n,r)}destroy(){const t=this._r3Injector;!t.destroyed&&t.destroy(),this.destroyCbs.forEach(n=>n()),this.destroyCbs=null}onDestroy(t){this.destroyCbs.push(t)}}class Sl extends class DE{}{constructor(t){super(),this.moduleType=t,null!==it(t)&&function wE(e){const t=new Set;!function n(r){const o=it(r,!0),i=o.id;null!==i&&(function lg(e,t,n){if(t&&t!==n)throw new Error(`Duplicate module registered for ${e} - ${te(t)} vs ${te(t.name)}`)}(i,Tr.get(i),r),Tr.set(i,r));const s=Rt(o.imports);for(const a of s)t.has(a)||(t.add(a),n(a))}(e)}(t)}create(t){return new cg(this.moduleType,t)}}function Vi(e,t,n,r){return function dg(e,t,n,r,o,i){const s=t+n;return Pe(e,s,o)?Vt(e,s+1,i?r.call(i,o):r(o)):po(e,s+1)}(w(),He(),e,t,n,r)}function xl(e,t,n,r,o){return function fg(e,t,n,r,o,i,s){const a=t+n;return Sn(e,a,o,i)?Vt(e,a+2,s?r.call(s,o,i):r(o,i)):po(e,a+2)}(w(),He(),e,t,n,r,o)}function xe(e,t,n,r,o,i){return hg(w(),He(),e,t,n,r,o,i)}function po(e,t){const n=e[t];return n===L?void 0:n}function hg(e,t,n,r,o,i,s,a){const l=t+n;return function bi(e,t,n,r,o){const i=Sn(e,t,n,r);return Pe(e,t+2,o)||i}(e,l,o,i,s)?Vt(e,l+3,a?r.call(a,o,i,s):r(o,i,s)):po(e,l+3)}function Nl(e){return t=>{setTimeout(e,void 0,t)}}const Ve=class PE extends Ds{constructor(t=!1){super(),this.__isAsync=t}emit(t){super.next(t)}subscribe(t,n,r){var o,i,s;let a=t,l=n||(()=>null),u=r;if(t&&"object"==typeof t){const d=t;a=null===(o=d.next)||void 0===o?void 0:o.bind(d),l=null===(i=d.error)||void 0===i?void 0:i.bind(d),u=null===(s=d.complete)||void 0===s?void 0:s.bind(d)}this.__isAsync&&(l=Nl(l),a&&(a=Nl(a)),u&&(u=Nl(u)));const c=super.subscribe({next:a,error:l,complete:u});return t instanceof Tt&&t.add(c),c}};Symbol;let Jt=(()=>{class e{}return e.__NG_ELEMENT_ID__=BE,e})();const kE=Jt,LE=class extends kE{constructor(t,n,r){super(),this._declarationLView=t,this._declarationTContainer=n,this.elementRef=r}createEmbeddedView(t){const n=this._declarationTContainer.tViews,r=no(this._declarationLView,n,t,16,null,n.declTNode,null,null,null,null);r[17]=this._declarationLView[this._declarationTContainer.index];const i=this._declarationLView[19];return null!==i&&(r[19]=i.createEmbeddedView(n)),ro(n,r,t),new ho(r)}};function BE(){return function ki(e,t){return 4&e.type?new LE(t,e,Ir(e,t)):null}(Me(),w())}let jt=(()=>{class e{}return e.__NG_ELEMENT_ID__=HE,e})();function HE(){return function Cg(e,t){let n;const r=t[e.index];if(_t(r))n=r;else{let o;if(8&e.type)o=De(r);else{const i=t[j];o=i.createComment("");const s=lt(e,t);Tn(i,hi(i,s),o,function vD(e,t){return me(e)?e.nextSibling(t):t.nextSibling}(i,s),!1)}t[e.index]=n=Wf(r,t,o,e),Ci(t,n)}return new vg(n,e,t)}(Me(),w())}const jE=jt,vg=class extends jE{constructor(t,n,r){super(),this._lContainer=t,this._hostTNode=n,this._hostLView=r}get element(){return Ir(this._hostTNode,this._hostLView)}get injector(){return new Zn(this._hostTNode,this._hostLView)}get parentInjector(){const t=ei(this._hostTNode,this._hostLView);if(cd(t)){const n=Qn(t,this._hostLView),r=Wn(t);return new Zn(n[1].data[r+8],n)}return new Zn(null,this._hostLView)}clear(){for(;this.length>0;)this.remove(this.length-1)}get(t){const n=yg(this._lContainer);return null!==n&&n[t]||null}get length(){return this._lContainer.length-10}createEmbeddedView(t,n,r){const o=t.createEmbeddedView(n||{});return this.insert(o,r),o}createComponent(t,n,r,o,i){const s=t&&!function Ur(e){return"function"==typeof e}(t);let a;if(s)a=n;else{const d=n||{};a=d.index,r=d.injector,o=d.projectableNodes,i=d.ngModuleRef}const l=s?t:new Tl(Ne(t)),u=r||this.parentInjector;if(!i&&null==l.ngModule){const f=(s?u:this.parentInjector).get(Ar,null);f&&(i=f)}const c=l.create(u,o,void 0,i);return this.insert(c.hostView,a),c}insert(t,n){const r=t._lView,o=r[1];if(function dy(e){return _t(e[3])}(r)){const c=this.indexOf(t);if(-1!==c)this.detach(c);else{const d=r[3],f=new vg(d,d[6],d[3]);f.detach(f.indexOf(t))}}const i=this._adjustIndex(n),s=this._lContainer;!function hD(e,t,n,r){const o=10+r,i=n.length;r>0&&(n[o-1][4]=t),r<i-10?(t[4]=n[o],Cd(n,10+r,t)):(n.push(t),t[4]=null),t[3]=n;const s=t[17];null!==s&&n!==s&&function pD(e,t){const n=e[9];t[16]!==t[3][3][16]&&(e[2]=!0),null===n?e[9]=[t]:n.push(t)}(s,t);const a=t[19];null!==a&&a.insertView(e),t[2]|=128}(o,r,s,i);const a=Pa(i,s),l=r[j],u=hi(l,s[7]);return null!==u&&function cD(e,t,n,r,o,i){r[0]=o,r[6]=t,to(e,r,n,1,o,i)}(o,s[6],l,r,u,a),t.attachToViewContainerRef(),Cd(Ol(s),i,t),t}move(t,n){return this.insert(t,n)}indexOf(t){const n=yg(this._lContainer);return null!==n?n.indexOf(t):-1}remove(t){const n=this._adjustIndex(t,-1),r=Fa(this._lContainer,n);r&&(ri(Ol(this._lContainer),n),rf(r[1],r))}detach(t){const n=this._adjustIndex(t,-1),r=Fa(this._lContainer,n);return r&&null!=ri(Ol(this._lContainer),n)?new ho(r):null}_adjustIndex(t,n=0){return null==t?this.length+n:t}};function yg(e){return e[8]}function Ol(e){return e[8]||(e[8]=[])}function Hi(...e){}const $g=new J("Application Initializer");let zl=(()=>{class e{constructor(n){this.appInits=n,this.resolve=Hi,this.reject=Hi,this.initialized=!1,this.done=!1,this.donePromise=new Promise((r,o)=>{this.resolve=r,this.reject=o})}runInitializers(){if(this.initialized)return;const n=[],r=()=>{this.done=!0,this.resolve()};if(this.appInits)for(let o=0;o<this.appInits.length;o++){const i=this.appInits[o]();if(Mi(i))n.push(i);else if(Bh(i)){const s=new Promise((a,l)=>{i.subscribe({complete:a,error:l})});n.push(s)}}Promise.all(n).then(()=>{r()}).catch(o=>{this.reject(o)}),0===n.length&&r(),this.initialized=!0}}return e.\u0275fac=function(n){return new(n||e)(oe($g,8))},e.\u0275prov=de({token:e,factory:e.\u0275fac,providedIn:"root"}),e})();const _o=new J("AppId",{providedIn:"root",factory:function Ug(){return`${Gl()}${Gl()}${Gl()}`}});function Gl(){return String.fromCharCode(97+Math.floor(25*Math.random()))}const zg=new J("Platform Initializer"),ql=new J("Platform ID"),_1=new J("appBootstrapListener");let v1=(()=>{class e{log(n){console.log(n)}warn(n){console.warn(n)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const hn=new J("LocaleId",{providedIn:"root",factory:()=>tC(hn,B.Optional|B.SkipSelf)||function y1(){return"undefined"!=typeof $localize&&$localize.locale||Ti}()}),b1=(()=>Promise.resolve(0))();function Wl(e){"undefined"==typeof Zone?b1.then(()=>{e&&e.apply(null,null)}):Zone.current.scheduleMicroTask("scheduleMicrotask",e)}class Qe{constructor({enableLongStackTrace:t=!1,shouldCoalesceEventChangeDetection:n=!1,shouldCoalesceRunChangeDetection:r=!1}){if(this.hasPendingMacrotasks=!1,this.hasPendingMicrotasks=!1,this.isStable=!0,this.onUnstable=new Ve(!1),this.onMicrotaskEmpty=new Ve(!1),this.onStable=new Ve(!1),this.onError=new Ve(!1),"undefined"==typeof Zone)throw new Error("In this configuration Angular requires Zone.js");Zone.assertZonePatched();const o=this;o._nesting=0,o._outer=o._inner=Zone.current,Zone.TaskTrackingZoneSpec&&(o._inner=o._inner.fork(new Zone.TaskTrackingZoneSpec)),t&&Zone.longStackTraceZoneSpec&&(o._inner=o._inner.fork(Zone.longStackTraceZoneSpec)),o.shouldCoalesceEventChangeDetection=!r&&n,o.shouldCoalesceRunChangeDetection=r,o.lastRequestAnimationFrameId=-1,o.nativeRequestAnimationFrame=function E1(){let e=re.requestAnimationFrame,t=re.cancelAnimationFrame;if("undefined"!=typeof Zone&&e&&t){const n=e[Zone.__symbol__("OriginalDelegate")];n&&(e=n);const r=t[Zone.__symbol__("OriginalDelegate")];r&&(t=r)}return{nativeRequestAnimationFrame:e,nativeCancelAnimationFrame:t}}().nativeRequestAnimationFrame,function A1(e){const t=()=>{!function I1(e){e.isCheckStableRunning||-1!==e.lastRequestAnimationFrameId||(e.lastRequestAnimationFrameId=e.nativeRequestAnimationFrame.call(re,()=>{e.fakeTopEventTask||(e.fakeTopEventTask=Zone.root.scheduleEventTask("fakeTopEventTask",()=>{e.lastRequestAnimationFrameId=-1,Zl(e),e.isCheckStableRunning=!0,Ql(e),e.isCheckStableRunning=!1},void 0,()=>{},()=>{})),e.fakeTopEventTask.invoke()}),Zl(e))}(e)};e._inner=e._inner.fork({name:"angular",properties:{isAngularZone:!0},onInvokeTask:(n,r,o,i,s,a)=>{try{return Gg(e),n.invokeTask(o,i,s,a)}finally{(e.shouldCoalesceEventChangeDetection&&"eventTask"===i.type||e.shouldCoalesceRunChangeDetection)&&t(),qg(e)}},onInvoke:(n,r,o,i,s,a,l)=>{try{return Gg(e),n.invoke(o,i,s,a,l)}finally{e.shouldCoalesceRunChangeDetection&&t(),qg(e)}},onHasTask:(n,r,o,i)=>{n.hasTask(o,i),r===o&&("microTask"==i.change?(e._hasPendingMicrotasks=i.microTask,Zl(e),Ql(e)):"macroTask"==i.change&&(e.hasPendingMacrotasks=i.macroTask))},onHandleError:(n,r,o,i)=>(n.handleError(o,i),e.runOutsideAngular(()=>e.onError.emit(i)),!1)})}(o)}static isInAngularZone(){return"undefined"!=typeof Zone&&!0===Zone.current.get("isAngularZone")}static assertInAngularZone(){if(!Qe.isInAngularZone())throw new Error("Expected to be in Angular Zone, but it is not!")}static assertNotInAngularZone(){if(Qe.isInAngularZone())throw new Error("Expected to not be in Angular Zone, but it is!")}run(t,n,r){return this._inner.run(t,n,r)}runTask(t,n,r,o){const i=this._inner,s=i.scheduleEventTask("NgZoneEvent: "+o,t,M1,Hi,Hi);try{return i.runTask(s,n,r)}finally{i.cancelTask(s)}}runGuarded(t,n,r){return this._inner.runGuarded(t,n,r)}runOutsideAngular(t){return this._outer.run(t)}}const M1={};function Ql(e){if(0==e._nesting&&!e.hasPendingMicrotasks&&!e.isStable)try{e._nesting++,e.onMicrotaskEmpty.emit(null)}finally{if(e._nesting--,!e.hasPendingMicrotasks)try{e.runOutsideAngular(()=>e.onStable.emit(null))}finally{e.isStable=!0}}}function Zl(e){e.hasPendingMicrotasks=!!(e._hasPendingMicrotasks||(e.shouldCoalesceEventChangeDetection||e.shouldCoalesceRunChangeDetection)&&-1!==e.lastRequestAnimationFrameId)}function Gg(e){e._nesting++,e.isStable&&(e.isStable=!1,e.onUnstable.emit(null))}function qg(e){e._nesting--,Ql(e)}class T1{constructor(){this.hasPendingMicrotasks=!1,this.hasPendingMacrotasks=!1,this.isStable=!0,this.onUnstable=new Ve,this.onMicrotaskEmpty=new Ve,this.onStable=new Ve,this.onError=new Ve}run(t,n,r){return t.apply(n,r)}runGuarded(t,n,r){return t.apply(n,r)}runOutsideAngular(t){return t()}runTask(t,n,r,o){return t.apply(n,r)}}let Yl=(()=>{class e{constructor(n){this._ngZone=n,this._pendingCount=0,this._isZoneStable=!0,this._didWork=!1,this._callbacks=[],this.taskTrackingZone=null,this._watchAngularEvents(),n.run(()=>{this.taskTrackingZone="undefined"==typeof Zone?null:Zone.current.get("TaskTrackingZone")})}_watchAngularEvents(){this._ngZone.onUnstable.subscribe({next:()=>{this._didWork=!0,this._isZoneStable=!1}}),this._ngZone.runOutsideAngular(()=>{this._ngZone.onStable.subscribe({next:()=>{Qe.assertNotInAngularZone(),Wl(()=>{this._isZoneStable=!0,this._runCallbacksIfReady()})}})})}increasePendingRequestCount(){return this._pendingCount+=1,this._didWork=!0,this._pendingCount}decreasePendingRequestCount(){if(this._pendingCount-=1,this._pendingCount<0)throw new Error("pending async requests below zero");return this._runCallbacksIfReady(),this._pendingCount}isStable(){return this._isZoneStable&&0===this._pendingCount&&!this._ngZone.hasPendingMacrotasks}_runCallbacksIfReady(){if(this.isStable())Wl(()=>{for(;0!==this._callbacks.length;){let n=this._callbacks.pop();clearTimeout(n.timeoutId),n.doneCb(this._didWork)}this._didWork=!1});else{let n=this.getPendingTasks();this._callbacks=this._callbacks.filter(r=>!r.updateCb||!r.updateCb(n)||(clearTimeout(r.timeoutId),!1)),this._didWork=!0}}getPendingTasks(){return this.taskTrackingZone?this.taskTrackingZone.macroTasks.map(n=>({source:n.source,creationLocation:n.creationLocation,data:n.data})):[]}addCallback(n,r,o){let i=-1;r&&r>0&&(i=setTimeout(()=>{this._callbacks=this._callbacks.filter(s=>s.timeoutId!==i),n(this._didWork,this.getPendingTasks())},r)),this._callbacks.push({doneCb:n,timeoutId:i,updateCb:o})}whenStable(n,r,o){if(o&&!this.taskTrackingZone)throw new Error('Task tracking zone is required when passing an update callback to whenStable(). Is "zone.js/plugins/task-tracking" loaded?');this.addCallback(n,r,o),this._runCallbacksIfReady()}getPendingRequestCount(){return this._pendingCount}findProviders(n,r,o){return[]}}return e.\u0275fac=function(n){return new(n||e)(oe(Qe))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})(),Wg=(()=>{class e{constructor(){this._applications=new Map,Kl.addToWindow(this)}registerApplication(n,r){this._applications.set(n,r)}unregisterApplication(n){this._applications.delete(n)}unregisterAllApplications(){this._applications.clear()}getTestability(n){return this._applications.get(n)||null}getAllTestabilities(){return Array.from(this._applications.values())}getAllRootElements(){return Array.from(this._applications.keys())}findTestabilityInTree(n,r=!0){return Kl.findTestabilityInTree(this,n,r)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class S1{addToWindow(t){}findTestabilityInTree(t,n,r){return null}}let Mt,Kl=new S1;const Qg=new J("AllowMultipleToken");function Zg(e,t,n=[]){const r=`Platform: ${t}`,o=new J(r);return(i=[])=>{let s=Yg();if(!s||s.injector.get(Qg,!1))if(e)e(n.concat(i).concat({provide:o,useValue:!0}));else{const a=n.concat(i).concat({provide:o,useValue:!0},{provide:sl,useValue:"platform"});!function O1(e){if(Mt&&!Mt.destroyed&&!Mt.injector.get(Qg,!1))throw new Y(400,"");Mt=e.get(Kg);const t=e.get(zg,null);t&&t.forEach(n=>n())}(ct.create({providers:a,name:r}))}return function R1(e){const t=Yg();if(!t)throw new Y(401,"");return t}()}}function Yg(){return Mt&&!Mt.destroyed?Mt:null}let Kg=(()=>{class e{constructor(n){this._injector=n,this._modules=[],this._destroyListeners=[],this._destroyed=!1}bootstrapModuleFactory(n,r){const a=function P1(e,t){let n;return n="noop"===e?new T1:("zone.js"===e?void 0:e)||new Qe({enableLongStackTrace:!1,shouldCoalesceEventChangeDetection:!!(null==t?void 0:t.ngZoneEventCoalescing),shouldCoalesceRunChangeDetection:!!(null==t?void 0:t.ngZoneRunCoalescing)}),n}(r?r.ngZone:void 0,{ngZoneEventCoalescing:r&&r.ngZoneEventCoalescing||!1,ngZoneRunCoalescing:r&&r.ngZoneRunCoalescing||!1}),l=[{provide:Qe,useValue:a}];return a.run(()=>{const u=ct.create({providers:l,parent:this.injector,name:n.moduleType.name}),c=n.create(u),d=c.injector.get(Xr,null);if(!d)throw new Y(402,"");return a.runOutsideAngular(()=>{const f=a.onError.subscribe({next:p=>{d.handleError(p)}});c.onDestroy(()=>{Jl(this._modules,c),f.unsubscribe()})}),function V1(e,t,n){try{const r=n();return Mi(r)?r.catch(o=>{throw t.runOutsideAngular(()=>e.handleError(o)),o}):r}catch(r){throw t.runOutsideAngular(()=>e.handleError(r)),r}}(d,a,()=>{const f=c.injector.get(zl);return f.runInitializers(),f.donePromise.then(()=>(function d0(e){Ke(e,"Expected localeId to be defined"),"string"==typeof e&&(Fp=e.toLowerCase().replace(/_/g,"-"))}(c.injector.get(hn,Ti)||Ti),this._moduleDoBootstrap(c),c))})})}bootstrapModule(n,r=[]){const o=Jg({},r);return function N1(e,t,n){const r=new Sl(n);return Promise.resolve(r)}(0,0,n).then(i=>this.bootstrapModuleFactory(i,o))}_moduleDoBootstrap(n){const r=n.injector.get(Xg);if(n._bootstrapComponents.length>0)n._bootstrapComponents.forEach(o=>r.bootstrap(o));else{if(!n.instance.ngDoBootstrap)throw new Y(403,"");n.instance.ngDoBootstrap(r)}this._modules.push(n)}onDestroy(n){this._destroyListeners.push(n)}get injector(){return this._injector}destroy(){if(this._destroyed)throw new Y(404,"");this._modules.slice().forEach(n=>n.destroy()),this._destroyListeners.forEach(n=>n()),this._destroyed=!0}get destroyed(){return this._destroyed}}return e.\u0275fac=function(n){return new(n||e)(oe(ct))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function Jg(e,t){return Array.isArray(t)?t.reduce(Jg,e):Object.assign(Object.assign({},e),t)}let Xg=(()=>{class e{constructor(n,r,o,i,s){this._zone=n,this._injector=r,this._exceptionHandler=o,this._componentFactoryResolver=i,this._initStatus=s,this._bootstrapListeners=[],this._views=[],this._runningTick=!1,this._stable=!0,this.componentTypes=[],this.components=[],this._onMicrotaskEmptySubscription=this._zone.onMicrotaskEmpty.subscribe({next:()=>{this._zone.run(()=>{this.tick()})}});const a=new Le(u=>{this._stable=this._zone.isStable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks,this._zone.runOutsideAngular(()=>{u.next(this._stable),u.complete()})}),l=new Le(u=>{let c;this._zone.runOutsideAngular(()=>{c=this._zone.onStable.subscribe(()=>{Qe.assertNotInAngularZone(),Wl(()=>{!this._stable&&!this._zone.hasPendingMacrotasks&&!this._zone.hasPendingMicrotasks&&(this._stable=!0,u.next(!0))})})});const d=this._zone.onUnstable.subscribe(()=>{Qe.assertInAngularZone(),this._stable&&(this._stable=!1,this._zone.runOutsideAngular(()=>{u.next(!1)}))});return()=>{c.unsubscribe(),d.unsubscribe()}});this.isStable=Sv(a,l.pipe(function Nv(e={}){const{connector:t=(()=>new Ds),resetOnError:n=!0,resetOnComplete:r=!0,resetOnRefCountZero:o=!0}=e;return i=>{let s=null,a=null,l=null,u=0,c=!1,d=!1;const f=()=>{null==a||a.unsubscribe(),a=null},p=()=>{f(),s=l=null,c=d=!1},m=()=>{const D=s;p(),null==D||D.unsubscribe()};return Ln((D,M)=>{u++,!d&&!c&&f();const I=l=null!=l?l:t();M.add(()=>{u--,0===u&&!d&&!c&&(a=As(m,o))}),I.subscribe(M),s||(s=new _s({next:_=>I.next(_),error:_=>{d=!0,f(),a=As(p,n,_),I.error(_)},complete:()=>{c=!0,f(),a=As(p,r),I.complete()}}),Is(D).subscribe(s))})(i)}}()))}bootstrap(n,r){if(!this._initStatus.done)throw new Y(405,"");let o;o=n instanceof rg?n:this._componentFactoryResolver.resolveComponentFactory(n),this.componentTypes.push(o.componentType);const i=function F1(e){return e.isBoundToModule}(o)?void 0:this._injector.get(Ar),a=o.create(ct.NULL,[],r||o.selector,i),l=a.location.nativeElement,u=a.injector.get(Yl,null),c=u&&a.injector.get(Wg);return u&&c&&c.registerApplication(l,u),a.onDestroy(()=>{this.detachView(a.hostView),Jl(this.components,a),c&&c.unregisterApplication(l)}),this._loadComponent(a),a}tick(){if(this._runningTick)throw new Y(101,"");try{this._runningTick=!0;for(let n of this._views)n.detectChanges()}catch(n){this._zone.runOutsideAngular(()=>this._exceptionHandler.handleError(n))}finally{this._runningTick=!1}}attachView(n){const r=n;this._views.push(r),r.attachToAppRef(this)}detachView(n){const r=n;Jl(this._views,r),r.detachFromAppRef()}_loadComponent(n){this.attachView(n.hostView),this.tick(),this.components.push(n),this._injector.get(_1,[]).concat(this._bootstrapListeners).forEach(o=>o(n))}ngOnDestroy(){this._views.slice().forEach(n=>n.destroy()),this._onMicrotaskEmptySubscription.unsubscribe()}get viewCount(){return this._views.length}}return e.\u0275fac=function(n){return new(n||e)(oe(Qe),oe(ct),oe(Xr),oe(Oi),oe(zl))},e.\u0275prov=de({token:e,factory:e.\u0275fac,providedIn:"root"}),e})();function Jl(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}let tm=!0,om=(()=>{class e{}return e.__NG_ELEMENT_ID__=B1,e})();function B1(e){return function H1(e,t,n){if(jo(e)&&!n){const r=Xe(e.index,t);return new ho(r,r)}return 47&e.type?new ho(t[16],t):null}(Me(),w(),16==(16&e))}class am{constructor(){}supports(t){return io(t)}create(t){return new q1(t)}}const G1=(e,t)=>t;class q1{constructor(t){this.length=0,this._linkedRecords=null,this._unlinkedRecords=null,this._previousItHead=null,this._itHead=null,this._itTail=null,this._additionsHead=null,this._additionsTail=null,this._movesHead=null,this._movesTail=null,this._removalsHead=null,this._removalsTail=null,this._identityChangesHead=null,this._identityChangesTail=null,this._trackByFn=t||G1}forEachItem(t){let n;for(n=this._itHead;null!==n;n=n._next)t(n)}forEachOperation(t){let n=this._itHead,r=this._removalsHead,o=0,i=null;for(;n||r;){const s=!r||n&&n.currentIndex<um(r,o,i)?n:r,a=um(s,o,i),l=s.currentIndex;if(s===r)o--,r=r._nextRemoved;else if(n=n._next,null==s.previousIndex)o++;else{i||(i=[]);const u=a-o,c=l-o;if(u!=c){for(let f=0;f<u;f++){const p=f<i.length?i[f]:i[f]=0,m=p+f;c<=m&&m<u&&(i[f]=p+1)}i[s.previousIndex]=c-u}}a!==l&&t(s,a,l)}}forEachPreviousItem(t){let n;for(n=this._previousItHead;null!==n;n=n._nextPrevious)t(n)}forEachAddedItem(t){let n;for(n=this._additionsHead;null!==n;n=n._nextAdded)t(n)}forEachMovedItem(t){let n;for(n=this._movesHead;null!==n;n=n._nextMoved)t(n)}forEachRemovedItem(t){let n;for(n=this._removalsHead;null!==n;n=n._nextRemoved)t(n)}forEachIdentityChange(t){let n;for(n=this._identityChangesHead;null!==n;n=n._nextIdentityChange)t(n)}diff(t){if(null==t&&(t=[]),!io(t))throw new Y(900,"");return this.check(t)?this:null}onDestroy(){}check(t){this._reset();let o,i,s,n=this._itHead,r=!1;if(Array.isArray(t)){this.length=t.length;for(let a=0;a<this.length;a++)i=t[a],s=this._trackByFn(a,i),null!==n&&Object.is(n.trackById,s)?(r&&(n=this._verifyReinsertion(n,i,s,a)),Object.is(n.item,i)||this._addIdentityChange(n,i)):(n=this._mismatch(n,i,s,a),r=!0),n=n._next}else o=0,function Ww(e,t){if(Array.isArray(e))for(let n=0;n<e.length;n++)t(e[n]);else{const n=e[dr()]();let r;for(;!(r=n.next()).done;)t(r.value)}}(t,a=>{s=this._trackByFn(o,a),null!==n&&Object.is(n.trackById,s)?(r&&(n=this._verifyReinsertion(n,a,s,o)),Object.is(n.item,a)||this._addIdentityChange(n,a)):(n=this._mismatch(n,a,s,o),r=!0),n=n._next,o++}),this.length=o;return this._truncate(n),this.collection=t,this.isDirty}get isDirty(){return null!==this._additionsHead||null!==this._movesHead||null!==this._removalsHead||null!==this._identityChangesHead}_reset(){if(this.isDirty){let t;for(t=this._previousItHead=this._itHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._additionsHead;null!==t;t=t._nextAdded)t.previousIndex=t.currentIndex;for(this._additionsHead=this._additionsTail=null,t=this._movesHead;null!==t;t=t._nextMoved)t.previousIndex=t.currentIndex;this._movesHead=this._movesTail=null,this._removalsHead=this._removalsTail=null,this._identityChangesHead=this._identityChangesTail=null}}_mismatch(t,n,r,o){let i;return null===t?i=this._itTail:(i=t._prev,this._remove(t)),null!==(t=null===this._unlinkedRecords?null:this._unlinkedRecords.get(r,null))?(Object.is(t.item,n)||this._addIdentityChange(t,n),this._reinsertAfter(t,i,o)):null!==(t=null===this._linkedRecords?null:this._linkedRecords.get(r,o))?(Object.is(t.item,n)||this._addIdentityChange(t,n),this._moveAfter(t,i,o)):t=this._addAfter(new W1(n,r),i,o),t}_verifyReinsertion(t,n,r,o){let i=null===this._unlinkedRecords?null:this._unlinkedRecords.get(r,null);return null!==i?t=this._reinsertAfter(i,t._prev,o):t.currentIndex!=o&&(t.currentIndex=o,this._addToMoves(t,o)),t}_truncate(t){for(;null!==t;){const n=t._next;this._addToRemovals(this._unlink(t)),t=n}null!==this._unlinkedRecords&&this._unlinkedRecords.clear(),null!==this._additionsTail&&(this._additionsTail._nextAdded=null),null!==this._movesTail&&(this._movesTail._nextMoved=null),null!==this._itTail&&(this._itTail._next=null),null!==this._removalsTail&&(this._removalsTail._nextRemoved=null),null!==this._identityChangesTail&&(this._identityChangesTail._nextIdentityChange=null)}_reinsertAfter(t,n,r){null!==this._unlinkedRecords&&this._unlinkedRecords.remove(t);const o=t._prevRemoved,i=t._nextRemoved;return null===o?this._removalsHead=i:o._nextRemoved=i,null===i?this._removalsTail=o:i._prevRemoved=o,this._insertAfter(t,n,r),this._addToMoves(t,r),t}_moveAfter(t,n,r){return this._unlink(t),this._insertAfter(t,n,r),this._addToMoves(t,r),t}_addAfter(t,n,r){return this._insertAfter(t,n,r),this._additionsTail=null===this._additionsTail?this._additionsHead=t:this._additionsTail._nextAdded=t,t}_insertAfter(t,n,r){const o=null===n?this._itHead:n._next;return t._next=o,t._prev=n,null===o?this._itTail=t:o._prev=t,null===n?this._itHead=t:n._next=t,null===this._linkedRecords&&(this._linkedRecords=new lm),this._linkedRecords.put(t),t.currentIndex=r,t}_remove(t){return this._addToRemovals(this._unlink(t))}_unlink(t){null!==this._linkedRecords&&this._linkedRecords.remove(t);const n=t._prev,r=t._next;return null===n?this._itHead=r:n._next=r,null===r?this._itTail=n:r._prev=n,t}_addToMoves(t,n){return t.previousIndex===n||(this._movesTail=null===this._movesTail?this._movesHead=t:this._movesTail._nextMoved=t),t}_addToRemovals(t){return null===this._unlinkedRecords&&(this._unlinkedRecords=new lm),this._unlinkedRecords.put(t),t.currentIndex=null,t._nextRemoved=null,null===this._removalsTail?(this._removalsTail=this._removalsHead=t,t._prevRemoved=null):(t._prevRemoved=this._removalsTail,this._removalsTail=this._removalsTail._nextRemoved=t),t}_addIdentityChange(t,n){return t.item=n,this._identityChangesTail=null===this._identityChangesTail?this._identityChangesHead=t:this._identityChangesTail._nextIdentityChange=t,t}}class W1{constructor(t,n){this.item=t,this.trackById=n,this.currentIndex=null,this.previousIndex=null,this._nextPrevious=null,this._prev=null,this._next=null,this._prevDup=null,this._nextDup=null,this._prevRemoved=null,this._nextRemoved=null,this._nextAdded=null,this._nextMoved=null,this._nextIdentityChange=null}}class Q1{constructor(){this._head=null,this._tail=null}add(t){null===this._head?(this._head=this._tail=t,t._nextDup=null,t._prevDup=null):(this._tail._nextDup=t,t._prevDup=this._tail,t._nextDup=null,this._tail=t)}get(t,n){let r;for(r=this._head;null!==r;r=r._nextDup)if((null===n||n<=r.currentIndex)&&Object.is(r.trackById,t))return r;return null}remove(t){const n=t._prevDup,r=t._nextDup;return null===n?this._head=r:n._nextDup=r,null===r?this._tail=n:r._prevDup=n,null===this._head}}class lm{constructor(){this.map=new Map}put(t){const n=t.trackById;let r=this.map.get(n);r||(r=new Q1,this.map.set(n,r)),r.add(t)}get(t,n){const o=this.map.get(t);return o?o.get(t,n):null}remove(t){const n=t.trackById;return this.map.get(n).remove(t)&&this.map.delete(n),t}get isEmpty(){return 0===this.map.size}clear(){this.map.clear()}}function um(e,t,n){const r=e.previousIndex;if(null===r)return r;let o=0;return n&&r<n.length&&(o=n[r]),r+t+o}class cm{constructor(){}supports(t){return t instanceof Map||fl(t)}create(){return new Z1}}class Z1{constructor(){this._records=new Map,this._mapHead=null,this._appendAfter=null,this._previousMapHead=null,this._changesHead=null,this._changesTail=null,this._additionsHead=null,this._additionsTail=null,this._removalsHead=null,this._removalsTail=null}get isDirty(){return null!==this._additionsHead||null!==this._changesHead||null!==this._removalsHead}forEachItem(t){let n;for(n=this._mapHead;null!==n;n=n._next)t(n)}forEachPreviousItem(t){let n;for(n=this._previousMapHead;null!==n;n=n._nextPrevious)t(n)}forEachChangedItem(t){let n;for(n=this._changesHead;null!==n;n=n._nextChanged)t(n)}forEachAddedItem(t){let n;for(n=this._additionsHead;null!==n;n=n._nextAdded)t(n)}forEachRemovedItem(t){let n;for(n=this._removalsHead;null!==n;n=n._nextRemoved)t(n)}diff(t){if(t){if(!(t instanceof Map||fl(t)))throw new Y(900,"")}else t=new Map;return this.check(t)?this:null}onDestroy(){}check(t){this._reset();let n=this._mapHead;if(this._appendAfter=null,this._forEach(t,(r,o)=>{if(n&&n.key===o)this._maybeAddToChanges(n,r),this._appendAfter=n,n=n._next;else{const i=this._getOrCreateRecordForKey(o,r);n=this._insertBeforeOrAppend(n,i)}}),n){n._prev&&(n._prev._next=null),this._removalsHead=n;for(let r=n;null!==r;r=r._nextRemoved)r===this._mapHead&&(this._mapHead=null),this._records.delete(r.key),r._nextRemoved=r._next,r.previousValue=r.currentValue,r.currentValue=null,r._prev=null,r._next=null}return this._changesTail&&(this._changesTail._nextChanged=null),this._additionsTail&&(this._additionsTail._nextAdded=null),this.isDirty}_insertBeforeOrAppend(t,n){if(t){const r=t._prev;return n._next=t,n._prev=r,t._prev=n,r&&(r._next=n),t===this._mapHead&&(this._mapHead=n),this._appendAfter=t,t}return this._appendAfter?(this._appendAfter._next=n,n._prev=this._appendAfter):this._mapHead=n,this._appendAfter=n,null}_getOrCreateRecordForKey(t,n){if(this._records.has(t)){const o=this._records.get(t);this._maybeAddToChanges(o,n);const i=o._prev,s=o._next;return i&&(i._next=s),s&&(s._prev=i),o._next=null,o._prev=null,o}const r=new Y1(t);return this._records.set(t,r),r.currentValue=n,this._addToAdditions(r),r}_reset(){if(this.isDirty){let t;for(this._previousMapHead=this._mapHead,t=this._previousMapHead;null!==t;t=t._next)t._nextPrevious=t._next;for(t=this._changesHead;null!==t;t=t._nextChanged)t.previousValue=t.currentValue;for(t=this._additionsHead;null!=t;t=t._nextAdded)t.previousValue=t.currentValue;this._changesHead=this._changesTail=null,this._additionsHead=this._additionsTail=null,this._removalsHead=null}}_maybeAddToChanges(t,n){Object.is(n,t.currentValue)||(t.previousValue=t.currentValue,t.currentValue=n,this._addToChanges(t))}_addToAdditions(t){null===this._additionsHead?this._additionsHead=this._additionsTail=t:(this._additionsTail._nextAdded=t,this._additionsTail=t)}_addToChanges(t){null===this._changesHead?this._changesHead=this._changesTail=t:(this._changesTail._nextChanged=t,this._changesTail=t)}_forEach(t,n){t instanceof Map?t.forEach(n):Object.keys(t).forEach(r=>n(t[r],r))}}class Y1{constructor(t){this.key=t,this.previousValue=null,this.currentValue=null,this._nextPrevious=null,this._next=null,this._prev=null,this._nextAdded=null,this._nextRemoved=null,this._nextChanged=null}}function dm(){return new Ui([new am])}let Ui=(()=>{class e{constructor(n){this.factories=n}static create(n,r){if(null!=r){const o=r.factories.slice();n=n.concat(o)}return new e(n)}static extend(n){return{provide:e,useFactory:r=>e.create(n,r||dm()),deps:[[e,new ai,new si]]}}find(n){const r=this.factories.find(o=>o.supports(n));if(null!=r)return r;throw new Y(901,"")}}return e.\u0275prov=de({token:e,providedIn:"root",factory:dm}),e})();function fm(){return new vo([new cm])}let vo=(()=>{class e{constructor(n){this.factories=n}static create(n,r){if(r){const o=r.factories.slice();n=n.concat(o)}return new e(n)}static extend(n){return{provide:e,useFactory:r=>e.create(n,r||fm()),deps:[[e,new ai,new si]]}}find(n){const r=this.factories.find(i=>i.supports(n));if(r)return r;throw new Y(901,"")}}return e.\u0275prov=de({token:e,providedIn:"root",factory:fm}),e})();const X1=Zg(null,"core",[{provide:ql,useValue:"unknown"},{provide:Kg,deps:[ct]},{provide:Wg,deps:[]},{provide:v1,deps:[]}]);let eM=(()=>{class e{constructor(n){}}return e.\u0275fac=function(n){return new(n||e)(oe(Xg))},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})(),zi=null;function On(){return zi}const $t=new J("DocumentToken");let Do=(()=>{class e{constructor(n,r,o,i){this._iterableDiffers=n,this._keyValueDiffers=r,this._ngEl=o,this._renderer=i,this._iterableDiffer=null,this._keyValueDiffer=null,this._initialClasses=[],this._rawClass=null}set klass(n){this._removeClasses(this._initialClasses),this._initialClasses="string"==typeof n?n.split(/\s+/):[],this._applyClasses(this._initialClasses),this._applyClasses(this._rawClass)}set ngClass(n){this._removeClasses(this._rawClass),this._applyClasses(this._initialClasses),this._iterableDiffer=null,this._keyValueDiffer=null,this._rawClass="string"==typeof n?n.split(/\s+/):n,this._rawClass&&(io(this._rawClass)?this._iterableDiffer=this._iterableDiffers.find(this._rawClass).create():this._keyValueDiffer=this._keyValueDiffers.find(this._rawClass).create())}ngDoCheck(){if(this._iterableDiffer){const n=this._iterableDiffer.diff(this._rawClass);n&&this._applyIterableChanges(n)}else if(this._keyValueDiffer){const n=this._keyValueDiffer.diff(this._rawClass);n&&this._applyKeyValueChanges(n)}}_applyKeyValueChanges(n){n.forEachAddedItem(r=>this._toggleClass(r.key,r.currentValue)),n.forEachChangedItem(r=>this._toggleClass(r.key,r.currentValue)),n.forEachRemovedItem(r=>{r.previousValue&&this._toggleClass(r.key,!1)})}_applyIterableChanges(n){n.forEachAddedItem(r=>{if("string"!=typeof r.item)throw new Error(`NgClass can only toggle CSS classes expressed as strings, got ${te(r.item)}`);this._toggleClass(r.item,!0)}),n.forEachRemovedItem(r=>this._toggleClass(r.item,!1))}_applyClasses(n){n&&(Array.isArray(n)||n instanceof Set?n.forEach(r=>this._toggleClass(r,!0)):Object.keys(n).forEach(r=>this._toggleClass(r,!!n[r])))}_removeClasses(n){n&&(Array.isArray(n)||n instanceof Set?n.forEach(r=>this._toggleClass(r,!1)):Object.keys(n).forEach(r=>this._toggleClass(r,!1)))}_toggleClass(n,r){(n=n.trim())&&n.split(/\s+/g).forEach(o=>{r?this._renderer.addClass(this._ngEl.nativeElement,o):this._renderer.removeClass(this._ngEl.nativeElement,o)})}}return e.\u0275fac=function(n){return new(n||e)(A(Ui),A(vo),A(Et),A(Nn))},e.\u0275dir=k({type:e,selectors:[["","ngClass",""]],inputs:{klass:["class","klass"],ngClass:"ngClass"}}),e})();class GM{constructor(t,n,r,o){this.$implicit=t,this.ngForOf=n,this.index=r,this.count=o}get first(){return 0===this.index}get last(){return this.index===this.count-1}get even(){return this.index%2==0}get odd(){return!this.even}}let fu=(()=>{class e{constructor(n,r,o){this._viewContainer=n,this._template=r,this._differs=o,this._ngForOf=null,this._ngForOfDirty=!0,this._differ=null}set ngForOf(n){this._ngForOf=n,this._ngForOfDirty=!0}set ngForTrackBy(n){this._trackByFn=n}get ngForTrackBy(){return this._trackByFn}set ngForTemplate(n){n&&(this._template=n)}ngDoCheck(){if(this._ngForOfDirty){this._ngForOfDirty=!1;const n=this._ngForOf;!this._differ&&n&&(this._differ=this._differs.find(n).create(this.ngForTrackBy))}if(this._differ){const n=this._differ.diff(this._ngForOf);n&&this._applyChanges(n)}}_applyChanges(n){const r=this._viewContainer;n.forEachOperation((o,i,s)=>{if(null==o.previousIndex)r.createEmbeddedView(this._template,new GM(o.item,this._ngForOf,-1,-1),null===s?void 0:s);else if(null==s)r.remove(null===i?void 0:i);else if(null!==i){const a=r.get(i);r.move(a,s),bm(a,o)}});for(let o=0,i=r.length;o<i;o++){const a=r.get(o).context;a.index=o,a.count=i,a.ngForOf=this._ngForOf}n.forEachIdentityChange(o=>{bm(r.get(o.currentIndex),o)})}static ngTemplateContextGuard(n,r){return!0}}return e.\u0275fac=function(n){return new(n||e)(A(jt),A(Jt),A(Ui))},e.\u0275dir=k({type:e,selectors:[["","ngFor","","ngForOf",""]],inputs:{ngForOf:"ngForOf",ngForTrackBy:"ngForTrackBy",ngForTemplate:"ngForTemplate"}}),e})();function bm(e,t){e.context.$implicit=t.item}let xr=(()=>{class e{constructor(n,r){this._viewContainer=n,this._context=new qM,this._thenTemplateRef=null,this._elseTemplateRef=null,this._thenViewRef=null,this._elseViewRef=null,this._thenTemplateRef=r}set ngIf(n){this._context.$implicit=this._context.ngIf=n,this._updateView()}set ngIfThen(n){Em("ngIfThen",n),this._thenTemplateRef=n,this._thenViewRef=null,this._updateView()}set ngIfElse(n){Em("ngIfElse",n),this._elseTemplateRef=n,this._elseViewRef=null,this._updateView()}_updateView(){this._context.$implicit?this._thenViewRef||(this._viewContainer.clear(),this._elseViewRef=null,this._thenTemplateRef&&(this._thenViewRef=this._viewContainer.createEmbeddedView(this._thenTemplateRef,this._context))):this._elseViewRef||(this._viewContainer.clear(),this._thenViewRef=null,this._elseTemplateRef&&(this._elseViewRef=this._viewContainer.createEmbeddedView(this._elseTemplateRef,this._context)))}static ngTemplateContextGuard(n,r){return!0}}return e.\u0275fac=function(n){return new(n||e)(A(jt),A(Jt))},e.\u0275dir=k({type:e,selectors:[["","ngIf",""]],inputs:{ngIf:"ngIf",ngIfThen:"ngIfThen",ngIfElse:"ngIfElse"}}),e})();class qM{constructor(){this.$implicit=null,this.ngIf=null}}function Em(e,t){if(t&&!t.createEmbeddedView)throw new Error(`${e} must be a TemplateRef, but received '${te(t)}'.`)}let Am=(()=>{class e{transform(n,r,o){if(null==n)return null;if(!this.supports(n))throw function At(e,t){return new Y(2100,"")}();return n.slice(r,o)}supports(n){return"string"==typeof n||Array.isArray(n)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275pipe=qe({name:"slice",type:e,pure:!1}),e})(),vI=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})();class _u extends class EI extends class rM{}{constructor(){super(...arguments),this.supportsDOMEvents=!0}}{static makeCurrent(){!function nM(e){zi||(zi=e)}(new _u)}onAndCancel(t,n,r){return t.addEventListener(n,r,!1),()=>{t.removeEventListener(n,r,!1)}}dispatchEvent(t,n){t.dispatchEvent(n)}remove(t){t.parentNode&&t.parentNode.removeChild(t)}createElement(t,n){return(n=n||this.getDefaultDocument()).createElement(t)}createHtmlDocument(){return document.implementation.createHTMLDocument("fakeTitle")}getDefaultDocument(){return document}isElementNode(t){return t.nodeType===Node.ELEMENT_NODE}isShadowRoot(t){return t instanceof DocumentFragment}getGlobalEventTarget(t,n){return"window"===n?window:"document"===n?t:"body"===n?t.body:null}getBaseHref(t){const n=function MI(){return wo=wo||document.querySelector("base"),wo?wo.getAttribute("href"):null}();return null==n?null:function II(e){es=es||document.createElement("a"),es.setAttribute("href",e);const t=es.pathname;return"/"===t.charAt(0)?t:`/${t}`}(n)}resetBaseElement(){wo=null}getUserAgent(){return window.navigator.userAgent}getCookie(t){return function UM(e,t){t=encodeURIComponent(t);for(const n of e.split(";")){const r=n.indexOf("="),[o,i]=-1==r?[n,""]:[n.slice(0,r),n.slice(r+1)];if(o.trim()===t)return decodeURIComponent(i)}return null}(document.cookie,t)}}let es,wo=null;const xm=new J("TRANSITION_ID"),TI=[{provide:$g,useFactory:function AI(e,t,n){return()=>{n.get(zl).donePromise.then(()=>{const r=On(),o=t.querySelectorAll(`style[ng-transition="${e}"]`);for(let i=0;i<o.length;i++)r.remove(o[i])})}},deps:[xm,$t,ct],multi:!0}];class vu{static init(){!function x1(e){Kl=e}(new vu)}addToWindow(t){re.getAngularTestability=(r,o=!0)=>{const i=t.findTestabilityInTree(r,o);if(null==i)throw new Error("Could not find testability for element.");return i},re.getAllAngularTestabilities=()=>t.getAllTestabilities(),re.getAllAngularRootElements=()=>t.getAllRootElements(),re.frameworkStabilizers||(re.frameworkStabilizers=[]),re.frameworkStabilizers.push(r=>{const o=re.getAllAngularTestabilities();let i=o.length,s=!1;const a=function(l){s=s||l,i--,0==i&&r(s)};o.forEach(function(l){l.whenStable(a)})})}findTestabilityInTree(t,n,r){if(null==n)return null;const o=t.getTestability(n);return null!=o?o:r?On().isShadowRoot(n)?this.findTestabilityInTree(t,n.host,!0):this.findTestabilityInTree(t,n.parentElement,!0):null}}let SI=(()=>{class e{build(){return new XMLHttpRequest}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const ts=new J("EventManagerPlugins");let ns=(()=>{class e{constructor(n,r){this._zone=r,this._eventNameToPlugin=new Map,n.forEach(o=>o.manager=this),this._plugins=n.slice().reverse()}addEventListener(n,r,o){return this._findPluginFor(r).addEventListener(n,r,o)}addGlobalEventListener(n,r,o){return this._findPluginFor(r).addGlobalEventListener(n,r,o)}getZone(){return this._zone}_findPluginFor(n){const r=this._eventNameToPlugin.get(n);if(r)return r;const o=this._plugins;for(let i=0;i<o.length;i++){const s=o[i];if(s.supports(n))return this._eventNameToPlugin.set(n,s),s}throw new Error(`No event manager plugin found for event ${n}`)}}return e.\u0275fac=function(n){return new(n||e)(oe(ts),oe(Qe))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class Nm{constructor(t){this._doc=t}addGlobalEventListener(t,n,r){const o=On().getGlobalEventTarget(this._doc,t);if(!o)throw new Error(`Unsupported event target ${o} for event ${n}`);return this.addEventListener(o,n,r)}}let Fm=(()=>{class e{constructor(){this._stylesSet=new Set}addStyles(n){const r=new Set;n.forEach(o=>{this._stylesSet.has(o)||(this._stylesSet.add(o),r.add(o))}),this.onStylesAdded(r)}onStylesAdded(n){}getAllStyles(){return Array.from(this._stylesSet)}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})(),bo=(()=>{class e extends Fm{constructor(n){super(),this._doc=n,this._hostNodes=new Map,this._hostNodes.set(n.head,[])}_addStylesToHost(n,r,o){n.forEach(i=>{const s=this._doc.createElement("style");s.textContent=i,o.push(r.appendChild(s))})}addHost(n){const r=[];this._addStylesToHost(this._stylesSet,n,r),this._hostNodes.set(n,r)}removeHost(n){const r=this._hostNodes.get(n);r&&r.forEach(Om),this._hostNodes.delete(n)}onStylesAdded(n){this._hostNodes.forEach((r,o)=>{this._addStylesToHost(n,o,r)})}ngOnDestroy(){this._hostNodes.forEach(n=>n.forEach(Om))}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function Om(e){On().remove(e)}const yu={svg:"http://www.w3.org/2000/svg",xhtml:"http://www.w3.org/1999/xhtml",xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/",math:"http://www.w3.org/1998/MathML/"},Cu=/%COMP%/g;function rs(e,t,n){for(let r=0;r<t.length;r++){let o=t[r];Array.isArray(o)?rs(e,o,n):(o=o.replace(Cu,e),n.push(o))}return n}function Vm(e){return t=>{if("__ngUnwrap__"===t)return e;!1===e(t)&&(t.preventDefault(),t.returnValue=!1)}}let Du=(()=>{class e{constructor(n,r,o){this.eventManager=n,this.sharedStylesHost=r,this.appId=o,this.rendererByCompId=new Map,this.defaultRenderer=new wu(n)}createRenderer(n,r){if(!n||!r)return this.defaultRenderer;switch(r.encapsulation){case St.Emulated:{let o=this.rendererByCompId.get(r.id);return o||(o=new PI(this.eventManager,this.sharedStylesHost,r,this.appId),this.rendererByCompId.set(r.id,o)),o.applyToHost(n),o}case 1:case St.ShadowDom:return new VI(this.eventManager,this.sharedStylesHost,n,r);default:if(!this.rendererByCompId.has(r.id)){const o=rs(r.id,r.styles,[]);this.sharedStylesHost.addStyles(o),this.rendererByCompId.set(r.id,this.defaultRenderer)}return this.defaultRenderer}}begin(){}end(){}}return e.\u0275fac=function(n){return new(n||e)(oe(ns),oe(bo),oe(_o))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();class wu{constructor(t){this.eventManager=t,this.data=Object.create(null),this.destroyNode=null}destroy(){}createElement(t,n){return n?document.createElementNS(yu[n]||n,t):document.createElement(t)}createComment(t){return document.createComment(t)}createText(t){return document.createTextNode(t)}appendChild(t,n){t.appendChild(n)}insertBefore(t,n,r){t&&t.insertBefore(n,r)}removeChild(t,n){t&&t.removeChild(n)}selectRootElement(t,n){let r="string"==typeof t?document.querySelector(t):t;if(!r)throw new Error(`The selector "${t}" did not match any elements`);return n||(r.textContent=""),r}parentNode(t){return t.parentNode}nextSibling(t){return t.nextSibling}setAttribute(t,n,r,o){if(o){n=o+":"+n;const i=yu[o];i?t.setAttributeNS(i,n,r):t.setAttribute(n,r)}else t.setAttribute(n,r)}removeAttribute(t,n,r){if(r){const o=yu[r];o?t.removeAttributeNS(o,n):t.removeAttribute(`${r}:${n}`)}else t.removeAttribute(n)}addClass(t,n){t.classList.add(n)}removeClass(t,n){t.classList.remove(n)}setStyle(t,n,r,o){o&(tt.DashCase|tt.Important)?t.style.setProperty(n,r,o&tt.Important?"important":""):t.style[n]=r}removeStyle(t,n,r){r&tt.DashCase?t.style.removeProperty(n):t.style[n]=""}setProperty(t,n,r){t[n]=r}setValue(t,n){t.nodeValue=n}listen(t,n,r){return"string"==typeof t?this.eventManager.addGlobalEventListener(t,n,Vm(r)):this.eventManager.addEventListener(t,n,Vm(r))}}class PI extends wu{constructor(t,n,r,o){super(t),this.component=r;const i=rs(o+"-"+r.id,r.styles,[]);n.addStyles(i),this.contentAttr=function FI(e){return"_ngcontent-%COMP%".replace(Cu,e)}(o+"-"+r.id),this.hostAttr=function OI(e){return"_nghost-%COMP%".replace(Cu,e)}(o+"-"+r.id)}applyToHost(t){super.setAttribute(t,this.hostAttr,"")}createElement(t,n){const r=super.createElement(t,n);return super.setAttribute(r,this.contentAttr,""),r}}class VI extends wu{constructor(t,n,r,o){super(t),this.sharedStylesHost=n,this.hostEl=r,this.shadowRoot=r.attachShadow({mode:"open"}),this.sharedStylesHost.addHost(this.shadowRoot);const i=rs(o.id,o.styles,[]);for(let s=0;s<i.length;s++){const a=document.createElement("style");a.textContent=i[s],this.shadowRoot.appendChild(a)}}nodeOrShadowRoot(t){return t===this.hostEl?this.shadowRoot:t}destroy(){this.sharedStylesHost.removeHost(this.shadowRoot)}appendChild(t,n){return super.appendChild(this.nodeOrShadowRoot(t),n)}insertBefore(t,n,r){return super.insertBefore(this.nodeOrShadowRoot(t),n,r)}removeChild(t,n){return super.removeChild(this.nodeOrShadowRoot(t),n)}parentNode(t){return this.nodeOrShadowRoot(super.parentNode(this.nodeOrShadowRoot(t)))}}let kI=(()=>{class e extends Nm{constructor(n){super(n)}supports(n){return!0}addEventListener(n,r,o){return n.addEventListener(r,o,!1),()=>this.removeEventListener(n,r,o)}removeEventListener(n,r,o){return n.removeEventListener(r,o)}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const Lm=["alt","control","meta","shift"],BI={"\b":"Backspace","\t":"Tab","\x7f":"Delete","\x1b":"Escape",Del:"Delete",Esc:"Escape",Left:"ArrowLeft",Right:"ArrowRight",Up:"ArrowUp",Down:"ArrowDown",Menu:"ContextMenu",Scroll:"ScrollLock",Win:"OS"},Bm={A:"1",B:"2",C:"3",D:"4",E:"5",F:"6",G:"7",H:"8",I:"9",J:"*",K:"+",M:"-",N:".",O:"/","`":"0","\x90":"NumLock"},HI={alt:e=>e.altKey,control:e=>e.ctrlKey,meta:e=>e.metaKey,shift:e=>e.shiftKey};let jI=(()=>{class e extends Nm{constructor(n){super(n)}supports(n){return null!=e.parseEventName(n)}addEventListener(n,r,o){const i=e.parseEventName(r),s=e.eventCallback(i.fullKey,o,this.manager.getZone());return this.manager.getZone().runOutsideAngular(()=>On().onAndCancel(n,i.domEventName,s))}static parseEventName(n){const r=n.toLowerCase().split("."),o=r.shift();if(0===r.length||"keydown"!==o&&"keyup"!==o)return null;const i=e._normalizeKey(r.pop());let s="";if(Lm.forEach(l=>{const u=r.indexOf(l);u>-1&&(r.splice(u,1),s+=l+".")}),s+=i,0!=r.length||0===i.length)return null;const a={};return a.domEventName=o,a.fullKey=s,a}static getEventFullKey(n){let r="",o=function $I(e){let t=e.key;if(null==t){if(t=e.keyIdentifier,null==t)return"Unidentified";t.startsWith("U+")&&(t=String.fromCharCode(parseInt(t.substring(2),16)),3===e.location&&Bm.hasOwnProperty(t)&&(t=Bm[t]))}return BI[t]||t}(n);return o=o.toLowerCase()," "===o?o="space":"."===o&&(o="dot"),Lm.forEach(i=>{i!=o&&HI[i](n)&&(r+=i+".")}),r+=o,r}static eventCallback(n,r,o){return i=>{e.getEventFullKey(i)===n&&o.runGuarded(()=>r(i))}}static _normalizeKey(n){return"esc"===n?"escape":n}}return e.\u0275fac=function(n){return new(n||e)(oe($t))},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();const qI=Zg(X1,"browser",[{provide:ql,useValue:"browser"},{provide:zg,useValue:function UI(){_u.makeCurrent(),vu.init()},multi:!0},{provide:$t,useFactory:function GI(){return function ay(e){Us=e}(document),document},deps:[]}]),WI=[{provide:sl,useValue:"root"},{provide:Xr,useFactory:function zI(){return new Xr},deps:[]},{provide:ts,useClass:kI,multi:!0,deps:[$t,Qe,ql]},{provide:ts,useClass:jI,multi:!0,deps:[$t]},{provide:Du,useClass:Du,deps:[ns,bo,_o]},{provide:ig,useExisting:Du},{provide:Fm,useExisting:bo},{provide:bo,useClass:bo,deps:[$t]},{provide:Yl,useClass:Yl,deps:[Qe]},{provide:ns,useClass:ns,deps:[ts,Qe]},{provide:class bI{},useClass:SI,deps:[]}];let QI=(()=>{class e{constructor(n){if(n)throw new Error("BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.")}static withServerTransition(n){return{ngModule:e,providers:[{provide:_o,useValue:n.appId},{provide:xm,useExisting:_o},TI]}}}return e.\u0275fac=function(n){return new(n||e)(oe(e,12))},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({providers:WI,imports:[vI,eM]}),e})();"undefined"!=typeof window&&window;const{isArray:iA}=Array,{getPrototypeOf:sA,prototype:aA,keys:lA}=Object;const{isArray:dA}=Array;function pA(e,t){return e.reduce((n,r,o)=>(n[r]=t[o],n),{})}function gA(...e){const t=function Cv(e){return pe(Ms(e))?e.pop():void 0}(e),{args:n,keys:r}=function uA(e){if(1===e.length){const t=e[0];if(iA(t))return{args:t,keys:null};if(function cA(e){return e&&"object"==typeof e&&sA(e)===aA}(t)){const n=lA(t);return{args:n.map(r=>t[r]),keys:n}}}return{args:e,keys:null}}(e),o=new Le(i=>{const{length:s}=n;if(!s)return void i.complete();const a=new Array(s);let l=s,u=s;for(let c=0;c<s;c++){let d=!1;wn(n[c]).subscribe(new Bn(i,f=>{d||(d=!0,u--),a[c]=f},()=>l--,void 0,()=>{(!l||!d)&&(u||i.next(r?pA(r,a):a),i.complete())}))}});return t?o.pipe(function hA(e){return ws(t=>function fA(e,t){return dA(t)?e(...t):e(t)}(e,t))}(t)):o}let $m=(()=>{class e{constructor(n,r){this._renderer=n,this._elementRef=r,this.onChange=o=>{},this.onTouched=()=>{}}setProperty(n,r){this._renderer.setProperty(this._elementRef.nativeElement,n,r)}registerOnTouched(n){this.onTouched=n}registerOnChange(n){this.onChange=n}setDisabledState(n){this.setProperty("disabled",n)}}return e.\u0275fac=function(n){return new(n||e)(A(Nn),A(Et))},e.\u0275dir=k({type:e}),e})(),Rn=(()=>{class e extends $m{}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,features:[ne]}),e})();const Ut=new J("NgValueAccessor"),_A={provide:Ut,useExisting:ae(()=>Eo),multi:!0},yA=new J("CompositionEventMode");let Eo=(()=>{class e extends $m{constructor(n,r,o){super(n,r),this._compositionMode=o,this._composing=!1,null==this._compositionMode&&(this._compositionMode=!function vA(){const e=On()?On().getUserAgent():"";return/android (\d+)/.test(e.toLowerCase())}())}writeValue(n){this.setProperty("value",null==n?"":n)}_handleInput(n){(!this._compositionMode||this._compositionMode&&!this._composing)&&this.onChange(n)}_compositionStart(){this._composing=!0}_compositionEnd(n){this._composing=!1,this._compositionMode&&this.onChange(n)}}return e.\u0275fac=function(n){return new(n||e)(A(Nn),A(Et),A(yA,8))},e.\u0275dir=k({type:e,selectors:[["input","formControlName","",3,"type","checkbox"],["textarea","formControlName",""],["input","formControl","",3,"type","checkbox"],["textarea","formControl",""],["input","ngModel","",3,"type","checkbox"],["textarea","ngModel",""],["","ngDefaultControl",""]],hostBindings:function(n,r){1&n&&z("input",function(i){return r._handleInput(i.target.value)})("blur",function(){return r.onTouched()})("compositionstart",function(){return r._compositionStart()})("compositionend",function(i){return r._compositionEnd(i.target.value)})},features:[he([_A]),ne]}),e})();const ke=new J("NgValidators"),mn=new J("NgAsyncValidators");function Xm(e){return null!=e}function e_(e){const t=Mi(e)?Is(e):e;return Bh(t),t}function t_(e){let t={};return e.forEach(n=>{t=null!=n?Object.assign(Object.assign({},t),n):t}),0===Object.keys(t).length?null:t}function n_(e,t){return t.map(n=>n(e))}function r_(e){return e.map(t=>function DA(e){return!e.validate}(t)?t:n=>t.validate(n))}function Eu(e){return null!=e?function o_(e){if(!e)return null;const t=e.filter(Xm);return 0==t.length?null:function(n){return t_(n_(n,t))}}(r_(e)):null}function Mu(e){return null!=e?function i_(e){if(!e)return null;const t=e.filter(Xm);return 0==t.length?null:function(n){return gA(n_(n,t).map(e_)).pipe(ws(t_))}}(r_(e)):null}function s_(e,t){return null===e?[t]:Array.isArray(e)?[...e,t]:[e,t]}function Iu(e){return e?Array.isArray(e)?e:[e]:[]}function is(e,t){return Array.isArray(e)?e.includes(t):e===t}function u_(e,t){const n=Iu(t);return Iu(e).forEach(o=>{is(n,o)||n.push(o)}),n}function c_(e,t){return Iu(t).filter(n=>!is(e,n))}class d_{constructor(){this._rawValidators=[],this._rawAsyncValidators=[],this._onDestroyCallbacks=[]}get value(){return this.control?this.control.value:null}get valid(){return this.control?this.control.valid:null}get invalid(){return this.control?this.control.invalid:null}get pending(){return this.control?this.control.pending:null}get disabled(){return this.control?this.control.disabled:null}get enabled(){return this.control?this.control.enabled:null}get errors(){return this.control?this.control.errors:null}get pristine(){return this.control?this.control.pristine:null}get dirty(){return this.control?this.control.dirty:null}get touched(){return this.control?this.control.touched:null}get status(){return this.control?this.control.status:null}get untouched(){return this.control?this.control.untouched:null}get statusChanges(){return this.control?this.control.statusChanges:null}get valueChanges(){return this.control?this.control.valueChanges:null}get path(){return null}_setValidators(t){this._rawValidators=t||[],this._composedValidatorFn=Eu(this._rawValidators)}_setAsyncValidators(t){this._rawAsyncValidators=t||[],this._composedAsyncValidatorFn=Mu(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn||null}get asyncValidator(){return this._composedAsyncValidatorFn||null}_registerOnDestroy(t){this._onDestroyCallbacks.push(t)}_invokeOnDestroyCallbacks(){this._onDestroyCallbacks.forEach(t=>t()),this._onDestroyCallbacks=[]}reset(t){this.control&&this.control.reset(t)}hasError(t,n){return!!this.control&&this.control.hasError(t,n)}getError(t,n){return this.control?this.control.getError(t,n):null}}class _n extends d_{constructor(){super(...arguments),this._parent=null,this.name=null,this.valueAccessor=null}}class Ge extends d_{get formDirective(){return null}get path(){return null}}let Au=(()=>{class e extends class f_{constructor(t){this._cd=t}is(t){var n,r,o;return"submitted"===t?!!(null===(n=this._cd)||void 0===n?void 0:n.submitted):!!(null===(o=null===(r=this._cd)||void 0===r?void 0:r.control)||void 0===o?void 0:o[t])}}{constructor(n){super(n)}}return e.\u0275fac=function(n){return new(n||e)(A(_n,2))},e.\u0275dir=k({type:e,selectors:[["","formControlName",""],["","ngModel",""],["","formControl",""]],hostVars:14,hostBindings:function(n,r){2&n&&Ii("ng-untouched",r.is("untouched"))("ng-touched",r.is("touched"))("ng-pristine",r.is("pristine"))("ng-dirty",r.is("dirty"))("ng-valid",r.is("valid"))("ng-invalid",r.is("invalid"))("ng-pending",r.is("pending"))},features:[ne]}),e})();function Mo(e,t){(function xu(e,t){const n=function a_(e){return e._rawValidators}(e);null!==t.validator?e.setValidators(s_(n,t.validator)):"function"==typeof n&&e.setValidators([n]);const r=function l_(e){return e._rawAsyncValidators}(e);null!==t.asyncValidator?e.setAsyncValidators(s_(r,t.asyncValidator)):"function"==typeof r&&e.setAsyncValidators([r]);const o=()=>e.updateValueAndValidity();us(t._rawValidators,o),us(t._rawAsyncValidators,o)})(e,t),t.valueAccessor.writeValue(e.value),function xA(e,t){t.valueAccessor.registerOnChange(n=>{e._pendingValue=n,e._pendingChange=!0,e._pendingDirty=!0,"change"===e.updateOn&&p_(e,t)})}(e,t),function FA(e,t){const n=(r,o)=>{t.valueAccessor.writeValue(r),o&&t.viewToModelUpdate(r)};e.registerOnChange(n),t._registerOnDestroy(()=>{e._unregisterOnChange(n)})}(e,t),function NA(e,t){t.valueAccessor.registerOnTouched(()=>{e._pendingTouched=!0,"blur"===e.updateOn&&e._pendingChange&&p_(e,t),"submit"!==e.updateOn&&e.markAsTouched()})}(e,t),function SA(e,t){if(t.valueAccessor.setDisabledState){const n=r=>{t.valueAccessor.setDisabledState(r)};e.registerOnDisabledChange(n),t._registerOnDestroy(()=>{e._unregisterOnDisabledChange(n)})}}(e,t)}function us(e,t){e.forEach(n=>{n.registerOnValidatorChange&&n.registerOnValidatorChange(t)})}function p_(e,t){e._pendingDirty&&e.markAsDirty(),e.setValue(e._pendingValue,{emitModelToViewChange:!1}),t.viewToModelUpdate(e._pendingValue),e._pendingChange=!1}function Ou(e,t){const n=e.indexOf(t);n>-1&&e.splice(n,1)}const Io="VALID",ds="INVALID",Nr="PENDING",Ao="DISABLED";function Pu(e){return(fs(e)?e.validators:e)||null}function v_(e){return Array.isArray(e)?Eu(e):e||null}function Vu(e,t){return(fs(t)?t.asyncValidators:e)||null}function y_(e){return Array.isArray(e)?Mu(e):e||null}function fs(e){return null!=e&&!Array.isArray(e)&&"object"==typeof e}const ku=e=>e instanceof Bu;function D_(e){return(e=>e instanceof E_)(e)?e.value:e.getRawValue()}function w_(e,t){const n=ku(e),r=e.controls;if(!(n?Object.keys(r):r).length)throw new Y(1e3,"");if(!r[t])throw new Y(1001,"")}function b_(e,t){ku(e),e._forEachChild((r,o)=>{if(void 0===t[o])throw new Y(1002,"")})}class Lu{constructor(t,n){this._pendingDirty=!1,this._hasOwnPendingAsyncValidator=!1,this._pendingTouched=!1,this._onCollectionChange=()=>{},this._parent=null,this.pristine=!0,this.touched=!1,this._onDisabledChange=[],this._rawValidators=t,this._rawAsyncValidators=n,this._composedValidatorFn=v_(this._rawValidators),this._composedAsyncValidatorFn=y_(this._rawAsyncValidators)}get validator(){return this._composedValidatorFn}set validator(t){this._rawValidators=this._composedValidatorFn=t}get asyncValidator(){return this._composedAsyncValidatorFn}set asyncValidator(t){this._rawAsyncValidators=this._composedAsyncValidatorFn=t}get parent(){return this._parent}get valid(){return this.status===Io}get invalid(){return this.status===ds}get pending(){return this.status==Nr}get disabled(){return this.status===Ao}get enabled(){return this.status!==Ao}get dirty(){return!this.pristine}get untouched(){return!this.touched}get updateOn(){return this._updateOn?this._updateOn:this.parent?this.parent.updateOn:"change"}setValidators(t){this._rawValidators=t,this._composedValidatorFn=v_(t)}setAsyncValidators(t){this._rawAsyncValidators=t,this._composedAsyncValidatorFn=y_(t)}addValidators(t){this.setValidators(u_(t,this._rawValidators))}addAsyncValidators(t){this.setAsyncValidators(u_(t,this._rawAsyncValidators))}removeValidators(t){this.setValidators(c_(t,this._rawValidators))}removeAsyncValidators(t){this.setAsyncValidators(c_(t,this._rawAsyncValidators))}hasValidator(t){return is(this._rawValidators,t)}hasAsyncValidator(t){return is(this._rawAsyncValidators,t)}clearValidators(){this.validator=null}clearAsyncValidators(){this.asyncValidator=null}markAsTouched(t={}){this.touched=!0,this._parent&&!t.onlySelf&&this._parent.markAsTouched(t)}markAllAsTouched(){this.markAsTouched({onlySelf:!0}),this._forEachChild(t=>t.markAllAsTouched())}markAsUntouched(t={}){this.touched=!1,this._pendingTouched=!1,this._forEachChild(n=>{n.markAsUntouched({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)}markAsDirty(t={}){this.pristine=!1,this._parent&&!t.onlySelf&&this._parent.markAsDirty(t)}markAsPristine(t={}){this.pristine=!0,this._pendingDirty=!1,this._forEachChild(n=>{n.markAsPristine({onlySelf:!0})}),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)}markAsPending(t={}){this.status=Nr,!1!==t.emitEvent&&this.statusChanges.emit(this.status),this._parent&&!t.onlySelf&&this._parent.markAsPending(t)}disable(t={}){const n=this._parentMarkedDirty(t.onlySelf);this.status=Ao,this.errors=null,this._forEachChild(r=>{r.disable(Object.assign(Object.assign({},t),{onlySelf:!0}))}),this._updateValue(),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._updateAncestors(Object.assign(Object.assign({},t),{skipPristineCheck:n})),this._onDisabledChange.forEach(r=>r(!0))}enable(t={}){const n=this._parentMarkedDirty(t.onlySelf);this.status=Io,this._forEachChild(r=>{r.enable(Object.assign(Object.assign({},t),{onlySelf:!0}))}),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent}),this._updateAncestors(Object.assign(Object.assign({},t),{skipPristineCheck:n})),this._onDisabledChange.forEach(r=>r(!1))}_updateAncestors(t){this._parent&&!t.onlySelf&&(this._parent.updateValueAndValidity(t),t.skipPristineCheck||this._parent._updatePristine(),this._parent._updateTouched())}setParent(t){this._parent=t}updateValueAndValidity(t={}){this._setInitialStatus(),this._updateValue(),this.enabled&&(this._cancelExistingSubscription(),this.errors=this._runValidator(),this.status=this._calculateStatus(),(this.status===Io||this.status===Nr)&&this._runAsyncValidator(t.emitEvent)),!1!==t.emitEvent&&(this.valueChanges.emit(this.value),this.statusChanges.emit(this.status)),this._parent&&!t.onlySelf&&this._parent.updateValueAndValidity(t)}_updateTreeValidity(t={emitEvent:!0}){this._forEachChild(n=>n._updateTreeValidity(t)),this.updateValueAndValidity({onlySelf:!0,emitEvent:t.emitEvent})}_setInitialStatus(){this.status=this._allControlsDisabled()?Ao:Io}_runValidator(){return this.validator?this.validator(this):null}_runAsyncValidator(t){if(this.asyncValidator){this.status=Nr,this._hasOwnPendingAsyncValidator=!0;const n=e_(this.asyncValidator(this));this._asyncValidationSubscription=n.subscribe(r=>{this._hasOwnPendingAsyncValidator=!1,this.setErrors(r,{emitEvent:t})})}}_cancelExistingSubscription(){this._asyncValidationSubscription&&(this._asyncValidationSubscription.unsubscribe(),this._hasOwnPendingAsyncValidator=!1)}setErrors(t,n={}){this.errors=t,this._updateControlsErrors(!1!==n.emitEvent)}get(t){return function VA(e,t,n){if(null==t||(Array.isArray(t)||(t=t.split(n)),Array.isArray(t)&&0===t.length))return null;let r=e;return t.forEach(o=>{r=ku(r)?r.controls.hasOwnProperty(o)?r.controls[o]:null:(e=>e instanceof LA)(r)&&r.at(o)||null}),r}(this,t,".")}getError(t,n){const r=n?this.get(n):this;return r&&r.errors?r.errors[t]:null}hasError(t,n){return!!this.getError(t,n)}get root(){let t=this;for(;t._parent;)t=t._parent;return t}_updateControlsErrors(t){this.status=this._calculateStatus(),t&&this.statusChanges.emit(this.status),this._parent&&this._parent._updateControlsErrors(t)}_initObservables(){this.valueChanges=new Ve,this.statusChanges=new Ve}_calculateStatus(){return this._allControlsDisabled()?Ao:this.errors?ds:this._hasOwnPendingAsyncValidator||this._anyControlsHaveStatus(Nr)?Nr:this._anyControlsHaveStatus(ds)?ds:Io}_anyControlsHaveStatus(t){return this._anyControls(n=>n.status===t)}_anyControlsDirty(){return this._anyControls(t=>t.dirty)}_anyControlsTouched(){return this._anyControls(t=>t.touched)}_updatePristine(t={}){this.pristine=!this._anyControlsDirty(),this._parent&&!t.onlySelf&&this._parent._updatePristine(t)}_updateTouched(t={}){this.touched=this._anyControlsTouched(),this._parent&&!t.onlySelf&&this._parent._updateTouched(t)}_isBoxedValue(t){return"object"==typeof t&&null!==t&&2===Object.keys(t).length&&"value"in t&&"disabled"in t}_registerOnCollectionChange(t){this._onCollectionChange=t}_setUpdateStrategy(t){fs(t)&&null!=t.updateOn&&(this._updateOn=t.updateOn)}_parentMarkedDirty(t){return!t&&!(!this._parent||!this._parent.dirty)&&!this._parent._anyControlsDirty()}}class E_ extends Lu{constructor(t=null,n,r){super(Pu(n),Vu(r,n)),this.defaultValue=null,this._onChange=[],this._pendingChange=!1,this._applyFormState(t),this._setUpdateStrategy(n),this._initObservables(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator}),fs(n)&&n.initialValueIsDefault&&(this.defaultValue=this._isBoxedValue(t)?t.value:t)}setValue(t,n={}){this.value=this._pendingValue=t,this._onChange.length&&!1!==n.emitModelToViewChange&&this._onChange.forEach(r=>r(this.value,!1!==n.emitViewToModelChange)),this.updateValueAndValidity(n)}patchValue(t,n={}){this.setValue(t,n)}reset(t=this.defaultValue,n={}){this._applyFormState(t),this.markAsPristine(n),this.markAsUntouched(n),this.setValue(this.value,n),this._pendingChange=!1}_updateValue(){}_anyControls(t){return!1}_allControlsDisabled(){return this.disabled}registerOnChange(t){this._onChange.push(t)}_unregisterOnChange(t){Ou(this._onChange,t)}registerOnDisabledChange(t){this._onDisabledChange.push(t)}_unregisterOnDisabledChange(t){Ou(this._onDisabledChange,t)}_forEachChild(t){}_syncPendingControls(){return!("submit"!==this.updateOn||(this._pendingDirty&&this.markAsDirty(),this._pendingTouched&&this.markAsTouched(),!this._pendingChange)||(this.setValue(this._pendingValue,{onlySelf:!0,emitModelToViewChange:!1}),0))}_applyFormState(t){this._isBoxedValue(t)?(this.value=this._pendingValue=t.value,t.disabled?this.disable({onlySelf:!0,emitEvent:!1}):this.enable({onlySelf:!0,emitEvent:!1})):this.value=this._pendingValue=t}}class Bu extends Lu{constructor(t,n,r){super(Pu(n),Vu(r,n)),this.controls=t,this._initObservables(),this._setUpdateStrategy(n),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}registerControl(t,n){return this.controls[t]?this.controls[t]:(this.controls[t]=n,n.setParent(this),n._registerOnCollectionChange(this._onCollectionChange),n)}addControl(t,n,r={}){this.registerControl(t,n),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}removeControl(t,n={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),delete this.controls[t],this.updateValueAndValidity({emitEvent:n.emitEvent}),this._onCollectionChange()}setControl(t,n,r={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),delete this.controls[t],n&&this.registerControl(t,n),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}contains(t){return this.controls.hasOwnProperty(t)&&this.controls[t].enabled}setValue(t,n={}){b_(this,t),Object.keys(t).forEach(r=>{w_(this,r),this.controls[r].setValue(t[r],{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n)}patchValue(t,n={}){null!=t&&(Object.keys(t).forEach(r=>{this.controls[r]&&this.controls[r].patchValue(t[r],{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n))}reset(t={},n={}){this._forEachChild((r,o)=>{r.reset(t[o],{onlySelf:!0,emitEvent:n.emitEvent})}),this._updatePristine(n),this._updateTouched(n),this.updateValueAndValidity(n)}getRawValue(){return this._reduceChildren({},(t,n,r)=>(t[r]=D_(n),t))}_syncPendingControls(){let t=this._reduceChildren(!1,(n,r)=>!!r._syncPendingControls()||n);return t&&this.updateValueAndValidity({onlySelf:!0}),t}_forEachChild(t){Object.keys(this.controls).forEach(n=>{const r=this.controls[n];r&&t(r,n)})}_setUpControls(){this._forEachChild(t=>{t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange)})}_updateValue(){this.value=this._reduceValue()}_anyControls(t){for(const n of Object.keys(this.controls)){const r=this.controls[n];if(this.contains(n)&&t(r))return!0}return!1}_reduceValue(){return this._reduceChildren({},(t,n,r)=>((n.enabled||this.disabled)&&(t[r]=n.value),t))}_reduceChildren(t,n){let r=t;return this._forEachChild((o,i)=>{r=n(r,o,i)}),r}_allControlsDisabled(){for(const t of Object.keys(this.controls))if(this.controls[t].enabled)return!1;return Object.keys(this.controls).length>0||this.disabled}}class LA extends Lu{constructor(t,n,r){super(Pu(n),Vu(r,n)),this.controls=t,this._initObservables(),this._setUpdateStrategy(n),this._setUpControls(),this.updateValueAndValidity({onlySelf:!0,emitEvent:!!this.asyncValidator})}at(t){return this.controls[t]}push(t,n={}){this.controls.push(t),this._registerControl(t),this.updateValueAndValidity({emitEvent:n.emitEvent}),this._onCollectionChange()}insert(t,n,r={}){this.controls.splice(t,0,n),this._registerControl(n),this.updateValueAndValidity({emitEvent:r.emitEvent})}removeAt(t,n={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),this.controls.splice(t,1),this.updateValueAndValidity({emitEvent:n.emitEvent})}setControl(t,n,r={}){this.controls[t]&&this.controls[t]._registerOnCollectionChange(()=>{}),this.controls.splice(t,1),n&&(this.controls.splice(t,0,n),this._registerControl(n)),this.updateValueAndValidity({emitEvent:r.emitEvent}),this._onCollectionChange()}get length(){return this.controls.length}setValue(t,n={}){b_(this,t),t.forEach((r,o)=>{w_(this,o),this.at(o).setValue(r,{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n)}patchValue(t,n={}){null!=t&&(t.forEach((r,o)=>{this.at(o)&&this.at(o).patchValue(r,{onlySelf:!0,emitEvent:n.emitEvent})}),this.updateValueAndValidity(n))}reset(t=[],n={}){this._forEachChild((r,o)=>{r.reset(t[o],{onlySelf:!0,emitEvent:n.emitEvent})}),this._updatePristine(n),this._updateTouched(n),this.updateValueAndValidity(n)}getRawValue(){return this.controls.map(t=>D_(t))}clear(t={}){this.controls.length<1||(this._forEachChild(n=>n._registerOnCollectionChange(()=>{})),this.controls.splice(0),this.updateValueAndValidity({emitEvent:t.emitEvent}))}_syncPendingControls(){let t=this.controls.reduce((n,r)=>!!r._syncPendingControls()||n,!1);return t&&this.updateValueAndValidity({onlySelf:!0}),t}_forEachChild(t){this.controls.forEach((n,r)=>{t(n,r)})}_updateValue(){this.value=this.controls.filter(t=>t.enabled||this.disabled).map(t=>t.value)}_anyControls(t){return this.controls.some(n=>n.enabled&&t(n))}_setUpControls(){this._forEachChild(t=>this._registerControl(t))}_allControlsDisabled(){for(const t of this.controls)if(t.enabled)return!1;return this.controls.length>0||this.disabled}_registerControl(t){t.setParent(this),t._registerOnCollectionChange(this._onCollectionChange)}}const jA={provide:_n,useExisting:ae(()=>hs)},A_=(()=>Promise.resolve(null))();let hs=(()=>{class e extends _n{constructor(n,r,o,i,s){super(),this._changeDetectorRef=s,this.control=new E_,this._registered=!1,this.update=new Ve,this._parent=n,this._setValidators(r),this._setAsyncValidators(o),this.valueAccessor=function Fu(e,t){if(!t)return null;let n,r,o;return Array.isArray(t),t.forEach(i=>{i.constructor===Eo?n=i:function PA(e){return Object.getPrototypeOf(e.constructor)===Rn}(i)?r=i:o=i}),o||r||n||null}(0,i)}ngOnChanges(n){if(this._checkForErrors(),!this._registered||"name"in n){if(this._registered&&(this._checkName(),this.formDirective)){const r=n.name.previousValue;this.formDirective.removeControl({name:r,path:this._getPath(r)})}this._setUpControl()}"isDisabled"in n&&this._updateDisabled(n),function Nu(e,t){if(!e.hasOwnProperty("model"))return!1;const n=e.model;return!!n.isFirstChange()||!Object.is(t,n.currentValue)}(n,this.viewModel)&&(this._updateValue(this.model),this.viewModel=this.model)}ngOnDestroy(){this.formDirective&&this.formDirective.removeControl(this)}get path(){return this._getPath(this.name)}get formDirective(){return this._parent?this._parent.formDirective:null}viewToModelUpdate(n){this.viewModel=n,this.update.emit(n)}_setUpControl(){this._setUpdateStrategy(),this._isStandalone()?this._setUpStandalone():this.formDirective.addControl(this),this._registered=!0}_setUpdateStrategy(){this.options&&null!=this.options.updateOn&&(this.control._updateOn=this.options.updateOn)}_isStandalone(){return!this._parent||!(!this.options||!this.options.standalone)}_setUpStandalone(){Mo(this.control,this),this.control.updateValueAndValidity({emitEvent:!1})}_checkForErrors(){this._isStandalone()||this._checkParentType(),this._checkName()}_checkParentType(){}_checkName(){this.options&&this.options.name&&(this.name=this.options.name),this._isStandalone()}_updateValue(n){A_.then(()=>{var r;this.control.setValue(n,{emitViewToModelChange:!1}),null===(r=this._changeDetectorRef)||void 0===r||r.markForCheck()})}_updateDisabled(n){const r=n.isDisabled.currentValue,o=""===r||r&&"false"!==r;A_.then(()=>{var i;o&&!this.control.disabled?this.control.disable():!o&&this.control.disabled&&this.control.enable(),null===(i=this._changeDetectorRef)||void 0===i||i.markForCheck()})}_getPath(n){return this._parent?function as(e,t){return[...t.path,e]}(n,this._parent):[n]}}return e.\u0275fac=function(n){return new(n||e)(A(Ge,9),A(ke,10),A(mn,10),A(Ut,10),A(om,8))},e.\u0275dir=k({type:e,selectors:[["","ngModel","",3,"formControlName","",3,"formControl",""]],inputs:{name:"name",isDisabled:["disabled","isDisabled"],model:["ngModel","model"],options:["ngModelOptions","options"]},outputs:{update:"ngModelChange"},exportAs:["ngModel"],features:[he([jA]),ne,Wt]}),e})(),S_=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({}),e})();const qA={provide:Ut,useExisting:ae(()=>ju),multi:!0};let ju=(()=>{class e extends Rn{writeValue(n){this.setProperty("value",parseFloat(n))}registerOnChange(n){this.onChange=r=>{n(""==r?null:parseFloat(r))}}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["input","type","range","formControlName",""],["input","type","range","formControl",""],["input","type","range","ngModel",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target.value)})("input",function(i){return r.onChange(i.target.value)})("blur",function(){return r.onTouched()})},features:[he([qA]),ne]}),e})();const JA={provide:Ut,useExisting:ae(()=>So),multi:!0};function P_(e,t){return null==e?`${t}`:(t&&"object"==typeof t&&(t="Object"),`${e}: ${t}`.slice(0,50))}let So=(()=>{class e extends Rn{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(n){this._compareWith=n}writeValue(n){this.value=n;const o=P_(this._getOptionId(n),n);this.setProperty("value",o)}registerOnChange(n){this.onChange=r=>{this.value=this._getOptionValue(r),n(this.value)}}_registerOption(){return(this._idCounter++).toString()}_getOptionId(n){for(const r of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(r),n))return r;return null}_getOptionValue(n){const r=function XA(e){return e.split(":")[0]}(n);return this._optionMap.has(r)?this._optionMap.get(r):n}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["select","formControlName","",3,"multiple",""],["select","formControl","",3,"multiple",""],["select","ngModel","",3,"multiple",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target.value)})("blur",function(){return r.onTouched()})},inputs:{compareWith:"compareWith"},features:[he([JA]),ne]}),e})(),Gu=(()=>{class e{constructor(n,r,o){this._element=n,this._renderer=r,this._select=o,this._select&&(this.id=this._select._registerOption())}set ngValue(n){null!=this._select&&(this._select._optionMap.set(this.id,n),this._setElementValue(P_(this.id,n)),this._select.writeValue(this._select.value))}set value(n){this._setElementValue(n),this._select&&this._select.writeValue(this._select.value)}_setElementValue(n){this._renderer.setProperty(this._element.nativeElement,"value",n)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return e.\u0275fac=function(n){return new(n||e)(A(Et),A(Nn),A(So,9))},e.\u0275dir=k({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),e})();const eT={provide:Ut,useExisting:ae(()=>qu),multi:!0};function V_(e,t){return null==e?`${t}`:("string"==typeof t&&(t=`'${t}'`),t&&"object"==typeof t&&(t="Object"),`${e}: ${t}`.slice(0,50))}let qu=(()=>{class e extends Rn{constructor(){super(...arguments),this._optionMap=new Map,this._idCounter=0,this._compareWith=Object.is}set compareWith(n){this._compareWith=n}writeValue(n){let r;if(this.value=n,Array.isArray(n)){const o=n.map(i=>this._getOptionId(i));r=(i,s)=>{i._setSelected(o.indexOf(s.toString())>-1)}}else r=(o,i)=>{o._setSelected(!1)};this._optionMap.forEach(r)}registerOnChange(n){this.onChange=r=>{const o=[],i=r.selectedOptions;if(void 0!==i){const s=i;for(let a=0;a<s.length;a++){const u=this._getOptionValue(s[a].value);o.push(u)}}else{const s=r.options;for(let a=0;a<s.length;a++){const l=s[a];if(l.selected){const u=this._getOptionValue(l.value);o.push(u)}}}this.value=o,n(o)}}_registerOption(n){const r=(this._idCounter++).toString();return this._optionMap.set(r,n),r}_getOptionId(n){for(const r of Array.from(this._optionMap.keys()))if(this._compareWith(this._optionMap.get(r)._value,n))return r;return null}_getOptionValue(n){const r=function tT(e){return e.split(":")[0]}(n);return this._optionMap.has(r)?this._optionMap.get(r)._value:n}}return e.\u0275fac=function(){let t;return function(r){return(t||(t=Oe(e)))(r||e)}}(),e.\u0275dir=k({type:e,selectors:[["select","multiple","","formControlName",""],["select","multiple","","formControl",""],["select","multiple","","ngModel",""]],hostBindings:function(n,r){1&n&&z("change",function(i){return r.onChange(i.target)})("blur",function(){return r.onTouched()})},inputs:{compareWith:"compareWith"},features:[he([eT]),ne]}),e})(),Wu=(()=>{class e{constructor(n,r,o){this._element=n,this._renderer=r,this._select=o,this._select&&(this.id=this._select._registerOption(this))}set ngValue(n){null!=this._select&&(this._value=n,this._setElementValue(V_(this.id,n)),this._select.writeValue(this._select.value))}set value(n){this._select?(this._value=n,this._setElementValue(V_(this.id,n)),this._select.writeValue(this._select.value)):this._setElementValue(n)}_setElementValue(n){this._renderer.setProperty(this._element.nativeElement,"value",n)}_setSelected(n){this._renderer.setProperty(this._element.nativeElement,"selected",n)}ngOnDestroy(){this._select&&(this._select._optionMap.delete(this.id),this._select.writeValue(this._select.value))}}return e.\u0275fac=function(n){return new(n||e)(A(Et),A(Nn),A(qu,9))},e.\u0275dir=k({type:e,selectors:[["option"]],inputs:{ngValue:"ngValue",value:"value"}}),e})(),dT=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({imports:[[S_]]}),e})(),fT=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e}),e.\u0275inj=Gt({imports:[dT]}),e})();class q_{constructor(){this.riskHotspotsSettings=null,this.coverageInfoSettings=null}}class hT{constructor(){this.groupingMaximum=0,this.grouping=0,this.historyComparisionDate="",this.historyComparisionType="",this.filter="",this.sortBy="name",this.sortOrder="asc",this.collapseStates=[]}}class pT{constructor(t){this.et="",this.et=t.et,this.cl=t.cl,this.ucl=t.ucl,this.cal=t.cal,this.tl=t.tl,this.lcq=t.lcq,this.cb=t.cb,this.tb=t.tb,this.bcq=t.bcq,this.cm=t.cm,this.tm=t.tm,this.mcq=t.mcq}get coverageRatioText(){return 0===this.tl?"-":this.cl+"/"+this.cal}get branchCoverageRatioText(){return 0===this.tb?"-":this.cb+"/"+this.tb}get methodCoverageRatioText(){return 0===this.tm?"-":this.cm+"/"+this.tm}}class Vn{static roundNumber(t,n){return Math.floor(t*Math.pow(10,n))/Math.pow(10,n)}static getNthOrLastIndexOf(t,n,r){let o=0,i=-1,s=-1;for(;o<r&&(s=t.indexOf(n,i+1),-1!==s);)i=s,o++;return i}}class W_{constructor(){this.name="",this.coveredLines=0,this.uncoveredLines=0,this.coverableLines=0,this.totalLines=0,this.coveredBranches=0,this.totalBranches=0,this.coveredMethods=0,this.totalMethods=0}get coverage(){return 0===this.coverableLines?NaN:Vn.roundNumber(100*this.coveredLines/this.coverableLines,1)}get coveragePercentage(){return 0===this.coverableLines?"":this.coverage+"%"}get coverageRatioText(){return 0===this.coverableLines?"-":this.coveredLines+"/"+this.coverableLines}get branchCoverage(){return 0===this.totalBranches?NaN:Vn.roundNumber(100*this.coveredBranches/this.totalBranches,1)}get branchCoveragePercentage(){return 0===this.totalBranches?"":this.branchCoverage+"%"}get branchCoverageRatioText(){return 0===this.totalBranches?"-":this.coveredBranches+"/"+this.totalBranches}get methodCoverage(){return 0===this.totalMethods?NaN:Vn.roundNumber(100*this.coveredMethods/this.totalMethods,1)}get methodCoveragePercentage(){return 0===this.totalMethods?"":this.methodCoverage+"%"}get methodCoverageRatioText(){return 0===this.totalMethods?"-":this.coveredMethods+"/"+this.totalMethods}}class Zu extends W_{constructor(t,n){super(),this.reportPath="",this._coverageType="",this.coverageByMethod="",this.lineCoverageHistory=[],this.branchCoverageHistory=[],this.methodCoverageHistory=[],this.historicCoverages=[],this.currentHistoricCoverage=null,this.name=t.name,this.reportPath=t.rp?t.rp+n:t.rp,this.coveredLines=t.cl,this.uncoveredLines=t.ucl,this.coverableLines=t.cal,this.totalLines=t.tl,this._coverageType=t.ct,this.coverageByMethod=t.cbm,this.coveredBranches=t.cb,this.totalBranches=t.tb,this.coveredMethods=t.cm,this.totalMethods=t.tm,this.lineCoverageHistory=t.lch,this.branchCoverageHistory=t.bch,this.methodCoverageHistory=t.mch,t.hc.forEach(r=>{this.historicCoverages.push(new pT(r))})}get coverage(){return 0===this.coverableLines?"-"!==this.coverageByMethod?parseFloat(this.coverageByMethod):NaN:Vn.roundNumber(100*this.coveredLines/this.coverableLines,1)}get coverageType(){return 0===this.coverableLines?"-"!==this.coverageByMethod?this._coverageType:"":this._coverageType}visible(t,n){if(""!==t&&-1===this.name.toLowerCase().indexOf(t.toLowerCase()))return!1;if(""===n||null===this.currentHistoricCoverage)return!0;if("allChanges"===n){if(this.coveredLines===this.currentHistoricCoverage.cl&&this.uncoveredLines===this.currentHistoricCoverage.ucl&&this.coverableLines===this.currentHistoricCoverage.cal&&this.totalLines===this.currentHistoricCoverage.tl&&this.coveredBranches===this.currentHistoricCoverage.cb&&this.totalBranches===this.currentHistoricCoverage.tb&&this.coveredMethods===this.currentHistoricCoverage.cm&&this.totalMethods===this.currentHistoricCoverage.tm)return!1}else if("lineCoverageIncreaseOnly"===n){let r=this.coverage;if(isNaN(r)||r<=this.currentHistoricCoverage.lcq)return!1}else if("lineCoverageDecreaseOnly"===n){let r=this.coverage;if(isNaN(r)||r>=this.currentHistoricCoverage.lcq)return!1}else if("branchCoverageIncreaseOnly"===n){let r=this.branchCoverage;if(isNaN(r)||r<=this.currentHistoricCoverage.bcq)return!1}else if("branchCoverageDecreaseOnly"===n){let r=this.branchCoverage;if(isNaN(r)||r>=this.currentHistoricCoverage.bcq)return!1}else if("methodCoverageIncreaseOnly"===n){let r=this.methodCoverage;if(isNaN(r)||r<=this.currentHistoricCoverage.mcq)return!1}else if("methodCoverageDecreaseOnly"===n){let r=this.methodCoverage;if(isNaN(r)||r>=this.currentHistoricCoverage.mcq)return!1}return!0}updateCurrentHistoricCoverage(t){if(this.currentHistoricCoverage=null,""!==t)for(let n=0;n<this.historicCoverages.length;n++)if(this.historicCoverages[n].et===t){this.currentHistoricCoverage=this.historicCoverages[n];break}}}class vn extends W_{constructor(t,n){super(),this.subElements=[],this.classes=[],this.collapsed=!1,this.name=t,this.collapsed=t.indexOf("Test")>-1&&null===n}visible(t,n){if(""!==t&&this.name.toLowerCase().indexOf(t.toLowerCase())>-1)return!0;for(let r=0;r<this.subElements.length;r++)if(this.subElements[r].visible(t,n))return!0;for(let r=0;r<this.classes.length;r++)if(this.classes[r].visible(t,n))return!0;return!1}insertClass(t,n){if(this.coveredLines+=t.coveredLines,this.uncoveredLines+=t.uncoveredLines,this.coverableLines+=t.coverableLines,this.totalLines+=t.totalLines,this.coveredBranches+=t.coveredBranches,this.totalBranches+=t.totalBranches,this.coveredMethods+=t.coveredMethods,this.totalMethods+=t.totalMethods,null===n)return void this.classes.push(t);let r=Vn.getNthOrLastIndexOf(t.name,".",n),o=-1===r?"-":t.name.substr(0,r);for(let s=0;s<this.subElements.length;s++)if(this.subElements[s].name===o)return void this.subElements[s].insertClass(t,null);let i=new vn(o,this);this.subElements.push(i),i.insertClass(t,null)}collapse(){this.collapsed=!0;for(let t=0;t<this.subElements.length;t++)this.subElements[t].collapse()}expand(){this.collapsed=!1;for(let t=0;t<this.subElements.length;t++)this.subElements[t].expand()}toggleCollapse(t){t.preventDefault(),this.collapsed=!this.collapsed}updateCurrentHistoricCoverage(t){for(let n=0;n<this.subElements.length;n++)this.subElements[n].updateCurrentHistoricCoverage(t);for(let n=0;n<this.classes.length;n++)this.classes[n].updateCurrentHistoricCoverage(t)}static sortCodeElementViewModels(t,n,r){let o=r?-1:1,i=r?1:-1;"name"===n?t.sort(function(s,a){return s.name===a.name?0:s.name<a.name?o:i}):"covered"===n?t.sort(function(s,a){return s.coveredLines===a.coveredLines?0:s.coveredLines<a.coveredLines?o:i}):"uncovered"===n?t.sort(function(s,a){return s.uncoveredLines===a.uncoveredLines?0:s.uncoveredLines<a.uncoveredLines?o:i}):"coverable"===n?t.sort(function(s,a){return s.coverableLines===a.coverableLines?0:s.coverableLines<a.coverableLines?o:i}):"total"===n?t.sort(function(s,a){return s.totalLines===a.totalLines?0:s.totalLines<a.totalLines?o:i}):"coverage"===n?t.sort(function(s,a){return s.coverage===a.coverage?0:isNaN(s.coverage)?o:isNaN(a.coverage)?i:s.coverage<a.coverage?o:i}):"branchcoverage"===n?t.sort(function(s,a){return s.branchCoverage===a.branchCoverage?0:isNaN(s.branchCoverage)?o:isNaN(a.branchCoverage)?i:s.branchCoverage<a.branchCoverage?o:i}):"methodcoverage"===n&&t.sort(function(s,a){return s.methodCoverage===a.methodCoverage?0:isNaN(s.methodCoverage)?o:isNaN(a.methodCoverage)?i:s.methodCoverage<a.methodCoverage?o:i})}changeSorting(t,n){vn.sortCodeElementViewModels(this.subElements,t,n);let r=n?-1:1,o=n?1:-1;"name"===t?this.classes.sort(function(i,s){return i.name===s.name?0:i.name<s.name?r:o}):"covered"===t?this.classes.sort(function(i,s){return i.coveredLines===s.coveredLines?0:i.coveredLines<s.coveredLines?r:o}):"uncovered"===t?this.classes.sort(function(i,s){return i.uncoveredLines===s.uncoveredLines?0:i.uncoveredLines<s.uncoveredLines?r:o}):"coverable"===t?this.classes.sort(function(i,s){return i.coverableLines===s.coverableLines?0:i.coverableLines<s.coverableLines?r:o}):"total"===t?this.classes.sort(function(i,s){return i.totalLines===s.totalLines?0:i.totalLines<s.totalLines?r:o}):"coverage"===t?this.classes.sort(function(i,s){return i.coverage===s.coverage?0:isNaN(i.coverage)?r:isNaN(s.coverage)?o:i.coverage<s.coverage?r:o}):"covered_branches"===t?this.classes.sort(function(i,s){return i.coveredBranches===s.coveredBranches?0:i.coveredBranches<s.coveredBranches?r:o}):"total_branches"===t?this.classes.sort(function(i,s){return i.totalBranches===s.totalBranches?0:i.totalBranches<s.totalBranches?r:o}):"branchcoverage"===t?this.classes.sort(function(i,s){return i.branchCoverage===s.branchCoverage?0:isNaN(i.branchCoverage)?r:isNaN(s.branchCoverage)?o:i.branchCoverage<s.branchCoverage?r:o}):"covered_methods"===t?this.classes.sort(function(i,s){return i.coveredMethods===s.coveredMethods?0:i.coveredMethods<s.coveredMethods?r:o}):"total_methods"===t?this.classes.sort(function(i,s){return i.totalMethods===s.totalMethods?0:i.totalMethods<s.totalMethods?r:o}):"methodcoverage"===t&&this.classes.sort(function(i,s){return i.methodCoverage===s.methodCoverage?0:isNaN(i.methodCoverage)?r:isNaN(s.methodCoverage)?o:i.methodCoverage<s.methodCoverage?r:o});for(let i=0;i<this.subElements.length;i++)this.subElements[i].changeSorting(t,n)}}let Yu=(()=>{class e{get nativeWindow(){return function gT(){return window}()}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275prov=de({token:e,factory:e.\u0275fac}),e})();function mT(e,t){1&e&&F(0,"td",3)}function _T(e,t){1&e&&F(0,"td"),2&e&&Ht("green ",C().greenClass,"")}function vT(e,t){1&e&&F(0,"td"),2&e&&Ht("red ",C().redClass,"")}let Q_=(()=>{class e{constructor(){this.grayVisible=!0,this.greenVisible=!1,this.redVisible=!1,this.greenClass="",this.redClass="",this._percentage=NaN}get percentage(){return this._percentage}set percentage(n){this._percentage=n,this.grayVisible=isNaN(n),this.greenVisible=!isNaN(n)&&Math.round(n)>0,this.redVisible=!isNaN(n)&&100-Math.round(n)>0,this.greenClass="covered"+Math.round(n),this.redClass="covered"+(100-Math.round(n))}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["coverage-bar"]],inputs:{percentage:"percentage"},decls:4,vars:3,consts:[[1,"coverage"],["class","gray covered100",4,"ngIf"],[3,"class",4,"ngIf"],[1,"gray","covered100"]],template:function(n,r){1&n&&(y(0,"table",0),E(1,mT,1,0,"td",1),E(2,_T,1,3,"td",2),E(3,vT,1,3,"td",2),v()),2&n&&(h(1),g("ngIf",r.grayVisible),h(1),g("ngIf",r.greenVisible),h(1),g("ngIf",r.redVisible))},directives:[xr],encapsulation:2,changeDetection:0}),e})();const yT=["codeelement-row",""];function CT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.coveredBranches)}}function DT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.totalBranches)}}function wT(e,t){if(1&e&&(y(0,"th",3),b(1),v()),2&e){const n=C();g("title",n.element.branchCoverageRatioText),h(1),x(n.element.branchCoveragePercentage)}}function bT(e,t){if(1&e&&(y(0,"th",2),F(1,"coverage-bar",4),v()),2&e){const n=C();h(1),g("percentage",n.element.branchCoverage)}}function ET(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.coveredMethods)}}function MT(e,t){if(1&e&&(y(0,"th",2),b(1),v()),2&e){const n=C();h(1),x(n.element.totalMethods)}}function IT(e,t){if(1&e&&(y(0,"th",3),b(1),v()),2&e){const n=C();g("title",n.element.methodCoverageRatioText),h(1),x(n.element.methodCoveragePercentage)}}function AT(e,t){if(1&e&&(y(0,"th",2),F(1,"coverage-bar",4),v()),2&e){const n=C();h(1),g("percentage",n.element.methodCoverage)}}const TT=function(e,t){return{"icon-plus":e,"icon-minus":t}};let ST=(()=>{class e{constructor(){this.collapsed=!1,this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","codeelement-row",""]],inputs:{element:"element",collapsed:"collapsed",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable"},attrs:yT,decls:24,vars:20,consts:[["href","#",3,"click"],[3,"ngClass"],[1,"right"],[1,"right",3,"title"],[3,"percentage"],["class","right",4,"ngIf"],["class","right",3,"title",4,"ngIf"]],template:function(n,r){1&n&&(y(0,"th")(1,"a",0),z("click",function(i){return r.element.toggleCollapse(i)}),F(2,"i",1),b(3),v()(),y(4,"th",2),b(5),v(),y(6,"th",2),b(7),v(),y(8,"th",2),b(9),v(),y(10,"th",2),b(11),v(),y(12,"th",3),b(13),v(),y(14,"th",2),F(15,"coverage-bar",4),v(),E(16,CT,2,1,"th",5),E(17,DT,2,1,"th",5),E(18,wT,2,2,"th",6),E(19,bT,2,1,"th",5),E(20,ET,2,1,"th",5),E(21,MT,2,1,"th",5),E(22,IT,2,2,"th",6),E(23,AT,2,1,"th",5)),2&n&&(h(2),g("ngClass",xl(17,TT,r.element.collapsed,!r.element.collapsed)),h(1),q(" ",r.element.name,""),h(2),x(r.element.coveredLines),h(2),x(r.element.uncoveredLines),h(2),x(r.element.coverableLines),h(2),x(r.element.totalLines),h(1),g("title",r.element.coverageRatioText),h(1),x(r.element.coveragePercentage),h(2),g("percentage",r.element.coverage),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable))},directives:[Do,Q_,xr],encapsulation:2,changeDetection:0}),e})();const xT=["coverage-history-chart",""];let NT=(()=>{class e{constructor(){this.path=null,this._historicCoverages=[]}get historicCoverages(){return this._historicCoverages}set historicCoverages(n){if(this._historicCoverages=n,n.length>1){let r="";for(let o=0;o<n.length;o++)r+=0===o?"M":"L",r+=`${Vn.roundNumber(30*o/(n.length-1),1)}`,r+=`,${Vn.roundNumber(18-18*n[o]/100,1)}`;this.path=r}else this.path=null}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","coverage-history-chart",""]],inputs:{historicCoverages:"historicCoverages"},attrs:xT,decls:3,vars:1,consts:[["width","30","height","18",1,"ct-chart-line"],[1,"ct-series","ct-series-a"],[1,"ct-line"]],template:function(n,r){1&n&&(function sd(){P.lFrame.currentNamespace="svg"}(),y(0,"svg",0)(1,"g",1),F(2,"path",2),v()()),2&n&&(h(2),kt("d",r.path))},encapsulation:2,changeDetection:0}),e})();const FT=["class-row",""];function OT(e,t){if(1&e&&(y(0,"a",8),b(1),v()),2&e){const n=C();g("href",n.clazz.reportPath,rr),h(1),x(n.clazz.name)}}function RT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),x(n.clazz.name)}}function PT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredLines,n.clazz.currentHistoricCoverage.cl),""),h(1),q(" ",n.clazz.coveredLines," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cl," ")}}function VT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coveredLines," ")}}function kT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.currentHistoricCoverage.ucl,n.clazz.uncoveredLines),""),h(1),q(" ",n.clazz.uncoveredLines," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.ucl," ")}}function LT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.uncoveredLines," ")}}function BT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(2),x(n.clazz.coverableLines),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.cal)}}function HT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coverableLines," ")}}function jT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(2),x(n.clazz.totalLines),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tl)}}function $T(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.totalLines," ")}}const Ku=function(e){return{historiccoverageoffset:e}};function UT(e,t){if(1&e&&F(0,"div",11),2&e){const n=C();wr("title",n.translations.history+": "+n.translations.coverage),g("historicCoverages",n.clazz.lineCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function zT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C();h(1),Ht("currenthistory ",n.getClassName(n.clazz.coverage,n.clazz.currentHistoricCoverage.lcq),""),h(1),q(" ",n.clazz.coveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.coverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.lcq,"%")}}function GT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C();h(1),q(" ",n.clazz.coveragePercentage," ")}}function qT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredBranches,n.clazz.currentHistoricCoverage.cb),""),h(1),q(" ",n.clazz.coveredBranches," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cb," ")}}function WT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.coveredBranches," ")}}function QT(e,t){if(1&e&&(y(0,"td",2),E(1,qT,5,6,"ng-container",1),E(2,WT,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function ZT(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(2),x(n.clazz.totalBranches),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tb)}}function YT(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.totalBranches," ")}}function KT(e,t){if(1&e&&(y(0,"td",2),E(1,ZT,5,3,"ng-container",1),E(2,YT,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function JT(e,t){if(1&e&&F(0,"div",13),2&e){const n=C(2);wr("title",n.translations.history+": "+n.translations.branchCoverage),g("historicCoverages",n.clazz.branchCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function XT(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.branchCoverage,n.clazz.currentHistoricCoverage.bcq),""),h(1),q(" ",n.clazz.branchCoveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.branchCoverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.bcq,"%")}}function eS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.branchCoveragePercentage," ")}}function tS(e,t){if(1&e&&(y(0,"td",3),E(1,JT,1,5,"div",12),E(2,XT,5,6,"ng-container",1),E(3,eS,2,1,"ng-container",1),v()),2&e){const n=C();g("title",n.clazz.branchCoverageRatioText),h(1),g("ngIf",n.clazz.branchCoverageHistory.length>1),h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function nS(e,t){if(1&e&&(y(0,"td",2),F(1,"coverage-bar",5),v()),2&e){const n=C();h(1),g("percentage",n.clazz.branchCoverage)}}function rS(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.coveredMethods,n.clazz.currentHistoricCoverage.cm),""),h(1),q(" ",n.clazz.coveredMethods," "),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),q(" ",n.clazz.currentHistoricCoverage.cm," ")}}function oS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.coveredMethods," ")}}function iS(e,t){if(1&e&&(y(0,"td",2),E(1,rS,5,6,"ng-container",1),E(2,oS,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function sS(e,t){if(1&e&&(Q(0),y(1,"div",10),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(2),x(n.clazz.totalMethods),h(1),g("title",n.clazz.currentHistoricCoverage.et),h(1),x(n.clazz.currentHistoricCoverage.tm)}}function aS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.totalMethods," ")}}function lS(e,t){if(1&e&&(y(0,"td",2),E(1,sS,5,3,"ng-container",1),E(2,aS,2,1,"ng-container",1),v()),2&e){const n=C();h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function uS(e,t){if(1&e&&F(0,"div",15),2&e){const n=C(2);wr("title",n.translations.history+": "+n.translations.methodCoverage),g("historicCoverages",n.clazz.methodCoverageHistory)("ngClass",Vi(3,Ku,null!==n.clazz.currentHistoricCoverage))}}function cS(e,t){if(1&e&&(Q(0),y(1,"div"),b(2),v(),y(3,"div",9),b(4),v(),Z()),2&e){const n=C(2);h(1),Ht("currenthistory ",n.getClassName(n.clazz.methodCoverage,n.clazz.currentHistoricCoverage.mcq),""),h(1),q(" ",n.clazz.methodCoveragePercentage," "),h(1),g("title",n.clazz.currentHistoricCoverage.et+": "+n.clazz.currentHistoricCoverage.methodCoverageRatioText),h(1),q("",n.clazz.currentHistoricCoverage.mcq,"%")}}function dS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),q(" ",n.clazz.methodCoveragePercentage," ")}}function fS(e,t){if(1&e&&(y(0,"td",3),E(1,uS,1,5,"div",14),E(2,cS,5,6,"ng-container",1),E(3,dS,2,1,"ng-container",1),v()),2&e){const n=C();g("title",n.clazz.methodCoverageRatioText),h(1),g("ngIf",n.clazz.methodCoverageHistory.length>1),h(1),g("ngIf",null!==n.clazz.currentHistoricCoverage),h(1),g("ngIf",null===n.clazz.currentHistoricCoverage)}}function hS(e,t){if(1&e&&(y(0,"td",2),F(1,"coverage-bar",5),v()),2&e){const n=C();h(1),g("percentage",n.clazz.methodCoverage)}}let pS=(()=>{class e{constructor(){this.translations={},this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.historyComparisionDate=""}getClassName(n,r){return n>r?"lightgreen":n<r?"lightred":"lightgraybg"}}return e.\u0275fac=function(n){return new(n||e)},e.\u0275cmp=rn({type:e,selectors:[["","class-row",""]],inputs:{clazz:"clazz",translations:"translations",branchCoverageAvailable:"branchCoverageAvailable",methodCoverageAvailable:"methodCoverageAvailable",historyComparisionDate:"historyComparisionDate"},attrs:FT,decls:29,vars:23,consts:[[3,"href",4,"ngIf"],[4,"ngIf"],[1,"right"],[1,"right",3,"title"],["coverage-history-chart","","class","tinylinecoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],[3,"percentage"],["class","right",4,"ngIf"],["class","right",3,"title",4,"ngIf"],[3,"href"],[3,"title"],[1,"currenthistory"],["coverage-history-chart","",1,"tinylinecoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","","class","tinybranchcoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],["coverage-history-chart","",1,"tinybranchcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"],["coverage-history-chart","","class","tinymethodcoveragechart ct-chart",3,"historicCoverages","ngClass","title",4,"ngIf"],["coverage-history-chart","",1,"tinymethodcoveragechart","ct-chart",3,"historicCoverages","ngClass","title"]],template:function(n,r){1&n&&(y(0,"td"),E(1,OT,2,2,"a",0),E(2,RT,2,1,"ng-container",1),v(),y(3,"td",2),E(4,PT,5,6,"ng-container",1),E(5,VT,2,1,"ng-container",1),v(),y(6,"td",2),E(7,kT,5,6,"ng-container",1),E(8,LT,2,1,"ng-container",1),v(),y(9,"td",2),E(10,BT,5,3,"ng-container",1),E(11,HT,2,1,"ng-container",1),v(),y(12,"td",2),E(13,jT,5,3,"ng-container",1),E(14,$T,2,1,"ng-container",1),v(),y(15,"td",3),E(16,UT,1,5,"div",4),E(17,zT,5,6,"ng-container",1),E(18,GT,2,1,"ng-container",1),v(),y(19,"td",2),F(20,"coverage-bar",5),v(),E(21,QT,3,2,"td",6),E(22,KT,3,2,"td",6),E(23,tS,4,4,"td",7),E(24,nS,2,1,"td",6),E(25,iS,3,2,"td",6),E(26,lS,3,2,"td",6),E(27,fS,4,4,"td",7),E(28,hS,2,1,"td",6)),2&n&&(h(1),g("ngIf",""!==r.clazz.reportPath),h(1),g("ngIf",""===r.clazz.reportPath),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(1),g("title",r.clazz.coverageType+": "+r.clazz.coverageRatioText),h(1),g("ngIf",r.clazz.lineCoverageHistory.length>1),h(1),g("ngIf",null!==r.clazz.currentHistoricCoverage),h(1),g("ngIf",null===r.clazz.currentHistoricCoverage),h(2),g("percentage",r.clazz.coverage),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.branchCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable),h(1),g("ngIf",r.methodCoverageAvailable))},directives:[xr,NT,Do,Q_],encapsulation:2,changeDetection:0}),e})();function gS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.noGrouping)}}function mS(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.byAssembly)}}function _S(e,t){if(1&e&&(Q(0),b(1),Z()),2&e){const n=C(2);h(1),x(n.translations.byNamespace+" "+n.settings.grouping)}}function vS(e,t){if(1&e&&(y(0,"option",31),b(1),v()),2&e){const n=t.$implicit;g("value",n),h(1),x(n)}}function yS(e,t){1&e&&F(0,"br")}function CS(e,t){if(1&e&&(y(0,"option",39),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.branchCoverageIncreaseOnly," ")}}function DS(e,t){if(1&e&&(y(0,"option",40),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.branchCoverageDecreaseOnly," ")}}function wS(e,t){if(1&e&&(y(0,"option",41),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.methodCoverageIncreaseOnly," ")}}function bS(e,t){if(1&e&&(y(0,"option",42),b(1),v()),2&e){const n=C(4);h(1),q(" ",n.translations.methodCoverageDecreaseOnly," ")}}function ES(e,t){if(1&e){const n=rt();y(0,"div")(1,"select",28),z("ngModelChange",function(o){return ee(n),C(3).settings.historyComparisionType=o}),y(2,"option",29),b(3),v(),y(4,"option",32),b(5),v(),y(6,"option",33),b(7),v(),y(8,"option",34),b(9),v(),E(10,CS,2,1,"option",35),E(11,DS,2,1,"option",36),E(12,wS,2,1,"option",37),E(13,bS,2,1,"option",38),v()()}if(2&e){const n=C(3);h(1),g("ngModel",n.settings.historyComparisionType),h(2),x(n.translations.filter),h(2),x(n.translations.allChanges),h(2),x(n.translations.lineCoverageIncreaseOnly),h(2),x(n.translations.lineCoverageDecreaseOnly),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable)}}function MS(e,t){if(1&e){const n=rt();Q(0),y(1,"div"),b(2),y(3,"select",28),z("ngModelChange",function(o){return ee(n),C(2).settings.historyComparisionDate=o})("ngModelChange",function(){return ee(n),C(2).updateCurrentHistoricCoverage()}),y(4,"option",29),b(5),v(),E(6,vS,2,2,"option",30),v()(),E(7,yS,1,0,"br",0),E(8,ES,14,9,"div",0),Z()}if(2&e){const n=C(2);h(2),q(" ",n.translations.compareHistory," "),h(1),g("ngModel",n.settings.historyComparisionDate),h(2),x(n.translations.date),h(1),g("ngForOf",n.historicCoverageExecutionTimes),h(1),g("ngIf",""!==n.settings.historyComparisionDate),h(1),g("ngIf",""!==n.settings.historyComparisionDate)}}function IS(e,t){1&e&&F(0,"col",10)}function AS(e,t){1&e&&F(0,"col",13)}function TS(e,t){1&e&&F(0,"col",14)}function SS(e,t){1&e&&F(0,"col",15)}function xS(e,t){1&e&&F(0,"col",10)}function NS(e,t){1&e&&F(0,"col",13)}function FS(e,t){1&e&&F(0,"col",14)}function OS(e,t){1&e&&F(0,"col",15)}function RS(e,t){if(1&e&&(y(0,"th",43),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.branchCoverage)}}function PS(e,t){if(1&e&&(y(0,"th",43),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.methodCoverage)}}const pt=function(e,t,n){return{"icon-up-dir_active":e,"icon-down-dir_active":t,"icon-down-dir":n}};function VS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("covered_branches",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"covered_branches"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered_branches"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered_branches"!==n.settings.sortBy)),h(1),x(n.translations.covered)}}function kS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("total_branches",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"total_branches"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total_branches"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total_branches"!==n.settings.sortBy)),h(1),x(n.translations.total)}}function LS(e,t){if(1&e){const n=rt();y(0,"th",24)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("branchcoverage",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"branchcoverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"branchcoverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"branchcoverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage)}}function BS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("covered_methods",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"covered_methods"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered_methods"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered_methods"!==n.settings.sortBy)),h(1),x(n.translations.covered)}}function HS(e,t){if(1&e){const n=rt();y(0,"th",5)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("total_methods",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"total_methods"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total_methods"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total_methods"!==n.settings.sortBy)),h(1),x(n.translations.total)}}function jS(e,t){if(1&e){const n=rt();y(0,"th",24)(1,"a",2),z("click",function(o){return ee(n),C(2).updateSorting("methodcoverage",o)}),F(2,"i",23),b(3),v()()}if(2&e){const n=C(2);h(2),g("ngClass",xe(2,pt,"methodcoverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"methodcoverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"methodcoverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage)}}function $S(e,t){if(1&e&&F(0,"tr",45),2&e){const n=C().$implicit,r=C(2);g("element",n)("collapsed",n.collapsed)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)}}function US(e,t){if(1&e&&F(0,"tr",47),2&e){const n=C().$implicit,r=C(3);g("clazz",n)("translations",r.translations)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)("historyComparisionDate",r.settings.historyComparisionDate)}}function zS(e,t){if(1&e&&(Q(0),E(1,US,1,5,"tr",46),Z()),2&e){const n=t.$implicit,r=C().$implicit,o=C(2);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function GS(e,t){if(1&e&&F(0,"tr",50),2&e){const n=C().$implicit,r=C(5);g("clazz",n)("translations",r.translations)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable)("historyComparisionDate",r.settings.historyComparisionDate)}}function qS(e,t){if(1&e&&(Q(0),E(1,GS,1,5,"tr",49),Z()),2&e){const n=t.$implicit,r=C(2).$implicit,o=C(3);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function WS(e,t){if(1&e&&(Q(0),F(1,"tr",48),E(2,qS,2,1,"ng-container",27),Z()),2&e){const n=C().$implicit,r=C(3);h(1),g("element",n)("collapsed",n.collapsed)("branchCoverageAvailable",r.branchCoverageAvailable)("methodCoverageAvailable",r.methodCoverageAvailable),h(1),g("ngForOf",n.classes)}}function QS(e,t){if(1&e&&(Q(0),E(1,WS,3,5,"ng-container",0),Z()),2&e){const n=t.$implicit,r=C().$implicit,o=C(2);h(1),g("ngIf",!r.collapsed&&n.visible(o.settings.filter,o.settings.historyComparisionType))}}function ZS(e,t){if(1&e&&(Q(0),E(1,$S,1,4,"tr",44),E(2,zS,2,1,"ng-container",27),E(3,QS,2,1,"ng-container",27),Z()),2&e){const n=t.$implicit,r=C(2);h(1),g("ngIf",n.visible(r.settings.filter,r.settings.historyComparisionType)),h(1),g("ngForOf",n.classes),h(1),g("ngForOf",n.subElements)}}function YS(e,t){if(1&e){const n=rt();y(0,"div")(1,"div",1)(2,"div")(3,"a",2),z("click",function(o){return ee(n),C().collapseAll(o)}),b(4),v(),b(5," | "),y(6,"a",2),z("click",function(o){return ee(n),C().expandAll(o)}),b(7),v()(),y(8,"div",3),E(9,gS,2,1,"ng-container",0),E(10,mS,2,1,"ng-container",0),E(11,_S,2,1,"ng-container",0),F(12,"br"),b(13),y(14,"input",4),z("ngModelChange",function(o){return ee(n),C().settings.grouping=o})("ngModelChange",function(){return ee(n),C().updateCoverageInfo()}),v()(),y(15,"div",3),E(16,MS,9,6,"ng-container",0),v(),y(17,"div",5)(18,"span"),b(19),v(),y(20,"input",6),z("ngModelChange",function(o){return ee(n),C().settings.filter=o}),v()()(),y(21,"div",7)(22,"table",8)(23,"colgroup"),F(24,"col",9)(25,"col",10)(26,"col",11)(27,"col",12)(28,"col",13)(29,"col",14)(30,"col",15),E(31,IS,1,0,"col",16),E(32,AS,1,0,"col",17),E(33,TS,1,0,"col",18),E(34,SS,1,0,"col",19),E(35,xS,1,0,"col",16),E(36,NS,1,0,"col",17),E(37,FS,1,0,"col",18),E(38,OS,1,0,"col",19),v(),y(39,"thead")(40,"tr",20),F(41,"th"),y(42,"th",21),b(43),v(),E(44,RS,2,1,"th",22),E(45,PS,2,1,"th",22),v(),y(46,"tr")(47,"th")(48,"a",2),z("click",function(o){return ee(n),C().updateSorting("name",o)}),F(49,"i",23),b(50),v()(),y(51,"th",5)(52,"a",2),z("click",function(o){return ee(n),C().updateSorting("covered",o)}),F(53,"i",23),b(54),v()(),y(55,"th",5)(56,"a",2),z("click",function(o){return ee(n),C().updateSorting("uncovered",o)}),F(57,"i",23),b(58),v()(),y(59,"th",5)(60,"a",2),z("click",function(o){return ee(n),C().updateSorting("coverable",o)}),F(61,"i",23),b(62),v()(),y(63,"th",5)(64,"a",2),z("click",function(o){return ee(n),C().updateSorting("total",o)}),F(65,"i",23),b(66),v()(),y(67,"th",24)(68,"a",2),z("click",function(o){return ee(n),C().updateSorting("coverage",o)}),F(69,"i",23),b(70),v()(),E(71,VS,4,6,"th",25),E(72,kS,4,6,"th",25),E(73,LS,4,6,"th",26),E(74,BS,4,6,"th",25),E(75,HS,4,6,"th",25),E(76,jS,4,6,"th",26),v()(),y(77,"tbody"),E(78,ZS,4,3,"ng-container",27),v()()()()}if(2&e){const n=C();h(4),x(n.translations.collapseAll),h(3),x(n.translations.expandAll),h(2),g("ngIf",-1===n.settings.grouping),h(1),g("ngIf",0===n.settings.grouping),h(1),g("ngIf",n.settings.grouping>0),h(2),q(" ",n.translations.grouping," "),h(1),g("max",n.settings.groupingMaximum)("ngModel",n.settings.grouping),h(2),g("ngIf",n.historicCoverageExecutionTimes.length>0),h(3),q("",n.translations.filter," "),h(1),g("ngModel",n.settings.filter),h(11),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(5),x(n.translations.coverage),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(4),g("ngClass",xe(41,pt,"name"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"name"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"name"!==n.settings.sortBy)),h(1),x(n.translations.name),h(3),g("ngClass",xe(45,pt,"covered"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"covered"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"covered"!==n.settings.sortBy)),h(1),x(n.translations.covered),h(3),g("ngClass",xe(49,pt,"uncovered"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"uncovered"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"uncovered"!==n.settings.sortBy)),h(1),x(n.translations.uncovered),h(3),g("ngClass",xe(53,pt,"coverable"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"coverable"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"coverable"!==n.settings.sortBy)),h(1),x(n.translations.coverable),h(3),g("ngClass",xe(57,pt,"total"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"total"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"total"!==n.settings.sortBy)),h(1),x(n.translations.total),h(3),g("ngClass",xe(61,pt,"coverage"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"coverage"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"coverage"!==n.settings.sortBy)),h(1),x(n.translations.percentage),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.branchCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(1),g("ngIf",n.methodCoverageAvailable),h(2),g("ngForOf",n.codeElements)}}let KS=(()=>{class e{constructor(n){this.queryString="",this.historicCoverageExecutionTimes=[],this.branchCoverageAvailable=!1,this.methodCoverageAvailable=!1,this.codeElements=[],this.translations={},this.settings=new hT,this.window=n.nativeWindow}ngOnInit(){this.historicCoverageExecutionTimes=this.window.historicCoverageExecutionTimes,this.branchCoverageAvailable=this.window.branchCoverageAvailable,this.methodCoverageAvailable=this.window.methodCoverageAvailable,this.translations=this.window.translations;let n=!1;if(void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.coverageInfoSettings)console.log("Coverage info: Restoring from history",this.window.history.state.coverageInfoSettings),n=!0,this.settings=JSON.parse(JSON.stringify(this.window.history.state.coverageInfoSettings));else{let o=0,i=this.window.assemblies;for(let s=0;s<i.length;s++)for(let a=0;a<i[s].classes.length;a++)o=Math.max(o,(i[s].classes[a].name.match(/\./g)||[]).length);this.settings.groupingMaximum=o,console.log("Grouping maximum: "+o)}const r=window.location.href.indexOf("?");r>-1&&(this.queryString=window.location.href.substr(r)),this.updateCoverageInfo(),n&&this.restoreCollapseState()}onDonBeforeUnlodad(){if(this.saveCollapseState(),void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Coverage info: Updating history",this.settings);let n=new q_;null!==window.history.state&&(n=JSON.parse(JSON.stringify(this.window.history.state))),n.coverageInfoSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(n,"")}}updateCoverageInfo(){let n=(new Date).getTime(),r=this.window.assemblies,o=[],i=0;if(0===this.settings.grouping)for(let l=0;l<r.length;l++){let u=new vn(r[l].name,null);o.push(u);for(let c=0;c<r[l].classes.length;c++)u.insertClass(new Zu(r[l].classes[c],this.queryString),null),i++}else if(-1===this.settings.grouping){let l=new vn(this.translations.all,null);o.push(l);for(let u=0;u<r.length;u++)for(let c=0;c<r[u].classes.length;c++)l.insertClass(new Zu(r[u].classes[c],this.queryString),null),i++}else for(let l=0;l<r.length;l++){let u=new vn(r[l].name,null);o.push(u);for(let c=0;c<r[l].classes.length;c++)u.insertClass(new Zu(r[l].classes[c],this.queryString),this.settings.grouping),i++}let s=-1,a=1;"name"===this.settings.sortBy&&(s="asc"===this.settings.sortOrder?-1:1,a="asc"===this.settings.sortOrder?1:-1),o.sort(function(l,u){return l.name===u.name?0:l.name<u.name?s:a}),vn.sortCodeElementViewModels(o,this.settings.sortBy,"asc"===this.settings.sortOrder);for(let l=0;l<o.length;l++)o[l].changeSorting(this.settings.sortBy,"asc"===this.settings.sortOrder);this.codeElements=o,console.log(`Processing assemblies finished (Duration: ${(new Date).getTime()-n}ms, Assemblies: ${o.length}, Classes: ${i})`),""!==this.settings.historyComparisionDate&&this.updateCurrentHistoricCoverage()}updateCurrentHistoricCoverage(){let n=(new Date).getTime();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].updateCurrentHistoricCoverage(this.settings.historyComparisionDate);console.log(`Updating current historic coverage finished (Duration: ${(new Date).getTime()-n}ms)`)}collapseAll(n){n.preventDefault();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].collapse()}expandAll(n){n.preventDefault();for(let r=0;r<this.codeElements.length;r++)this.codeElements[r].expand()}updateSorting(n,r){r.preventDefault(),this.settings.sortOrder=n===this.settings.sortBy&&"asc"===this.settings.sortOrder?"desc":"asc",this.settings.sortBy=n,console.log(`Updating sort column: '${this.settings.sortBy}' (${this.settings.sortOrder})`),vn.sortCodeElementViewModels(this.codeElements,this.settings.sortBy,"asc"===this.settings.sortOrder);for(let o=0;o<this.codeElements.length;o++)this.codeElements[o].changeSorting(this.settings.sortBy,"asc"===this.settings.sortOrder)}saveCollapseState(){this.settings.collapseStates=[];let n=r=>{for(let o=0;o<r.length;o++)this.settings.collapseStates.push(r[o].collapsed),n(r[o].subElements)};n(this.codeElements)}restoreCollapseState(){let n=0,r=o=>{for(let i=0;i<o.length;i++)this.settings.collapseStates.length>n&&(o[i].collapsed=this.settings.collapseStates[n]),n++,r(o[i].subElements)};r(this.codeElements)}}return e.\u0275fac=function(n){return new(n||e)(A(Yu))},e.\u0275cmp=rn({type:e,selectors:[["coverage-info"]],hostBindings:function(n,r){1&n&&z("beforeunload",function(){return r.onDonBeforeUnlodad()},!1,Ma)},decls:1,vars:1,consts:[[4,"ngIf"],[1,"customizebox"],["href","#",3,"click"],[1,"center"],["type","range","step","1","min","-1",3,"max","ngModel","ngModelChange"],[1,"right"],["type","text",3,"ngModel","ngModelChange"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],[1,"column-min-200"],[1,"column90"],[1,"column105"],[1,"column100"],[1,"column70"],[1,"column98"],[1,"column112"],["class","column90",4,"ngIf"],["class","column70",4,"ngIf"],["class","column98",4,"ngIf"],["class","column112",4,"ngIf"],[1,"header"],["colspan","6",1,"center"],["class","center","colspan","4",4,"ngIf"],[1,"icon-down-dir",3,"ngClass"],["colspan","2",1,"center"],["class","right",4,"ngIf"],["class","center","colspan","2",4,"ngIf"],[4,"ngFor","ngForOf"],[3,"ngModel","ngModelChange"],["value",""],[3,"value",4,"ngFor","ngForOf"],[3,"value"],["value","allChanges"],["value","lineCoverageIncreaseOnly"],["value","lineCoverageDecreaseOnly"],["value","branchCoverageIncreaseOnly",4,"ngIf"],["value","branchCoverageDecreaseOnly",4,"ngIf"],["value","methodCoverageIncreaseOnly",4,"ngIf"],["value","methodCoverageDecreaseOnly",4,"ngIf"],["value","branchCoverageIncreaseOnly"],["value","branchCoverageDecreaseOnly"],["value","methodCoverageIncreaseOnly"],["value","methodCoverageDecreaseOnly"],["colspan","4",1,"center"],["codeelement-row","",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable",4,"ngIf"],["codeelement-row","",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable"],["class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate",4,"ngIf"],["class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate"],["codeelement-row","",1,"namespace",3,"element","collapsed","branchCoverageAvailable","methodCoverageAvailable"],["class","namespace","class-row","",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate",4,"ngIf"],["class-row","",1,"namespace",3,"clazz","translations","branchCoverageAvailable","methodCoverageAvailable","historyComparisionDate"]],template:function(n,r){1&n&&E(0,YS,79,65,"div",0),2&n&&g("ngIf",r.codeElements.length>0)},directives:[xr,ju,Eo,Au,hs,So,Gu,Wu,fu,Do,ST,pS],encapsulation:2}),e})();class JS{constructor(){this.assembly="",this.numberOfRiskHotspots=10,this.filter="",this.sortBy="",this.sortOrder="asc"}}function XS(e,t){if(1&e&&(y(0,"option",15),b(1),v()),2&e){const n=t.$implicit;g("value",n),h(1),x(n)}}function ex(e,t){if(1&e&&(y(0,"span"),b(1),v()),2&e){const n=C(2);h(1),x(n.translations.top)}}function tx(e,t){1&e&&(y(0,"option",22),b(1,"20"),v())}function nx(e,t){1&e&&(y(0,"option",23),b(1,"50"),v())}function rx(e,t){1&e&&(y(0,"option",24),b(1,"100"),v())}function ox(e,t){if(1&e&&(y(0,"option",15),b(1),v()),2&e){const n=C(3);g("value",n.totalNumberOfRiskHotspots),h(1),x(n.translations.all)}}function ix(e,t){if(1&e){const n=rt();y(0,"select",16),z("ngModelChange",function(o){return ee(n),C(2).settings.numberOfRiskHotspots=o}),y(1,"option",17),b(2,"10"),v(),E(3,tx,2,0,"option",18),E(4,nx,2,0,"option",19),E(5,rx,2,0,"option",20),E(6,ox,2,2,"option",21),v()}if(2&e){const n=C(2);g("ngModel",n.settings.numberOfRiskHotspots),h(3),g("ngIf",n.totalNumberOfRiskHotspots>10),h(1),g("ngIf",n.totalNumberOfRiskHotspots>20),h(1),g("ngIf",n.totalNumberOfRiskHotspots>50),h(1),g("ngIf",n.totalNumberOfRiskHotspots>100)}}function sx(e,t){1&e&&F(0,"col",25)}const ps=function(e,t,n){return{"icon-up-dir_active":e,"icon-down-dir_active":t,"icon-down-dir":n}};function ax(e,t){if(1&e){const n=rt();y(0,"th")(1,"a",12),z("click",function(o){const s=ee(n).index;return C(2).updateSorting(""+s,o)}),F(2,"i",13),b(3),v(),y(4,"a",26),F(5,"i",27),v()()}if(2&e){const n=t.$implicit,r=t.index,o=C(2);h(2),g("ngClass",xe(3,ps,o.settings.sortBy===""+r&&"desc"===o.settings.sortOrder,o.settings.sortBy===""+r&&"asc"===o.settings.sortOrder,o.settings.sortBy!==""+r)),h(1),x(n.name),h(1),wr("href",n.explanationUrl,rr)}}const lx=function(e,t){return{lightred:e,lightgreen:t}};function ux(e,t){if(1&e&&(y(0,"td",30),b(1),v()),2&e){const n=t.$implicit;g("ngClass",xl(2,lx,n.exceeded,!n.exceeded)),h(1),x(n.value)}}function cx(e,t){if(1&e&&(y(0,"tr")(1,"td"),b(2),v(),y(3,"td")(4,"a",26),b(5),v()(),y(6,"td",28)(7,"a",26),b(8),v()(),E(9,ux,2,5,"td",29),v()),2&e){const n=t.$implicit,r=C(2);h(2),x(n.assembly),h(2),g("href",n.reportPath+r.queryString,rr),h(1),x(n.class),h(1),g("title",n.methodName),h(1),g("href",n.reportPath+r.queryString+"#file"+n.fileIndex+"_line"+n.line,rr),h(1),q(" ",n.methodShortName," "),h(1),g("ngForOf",n.metrics)}}function dx(e,t){if(1&e){const n=rt();y(0,"div")(1,"div",1)(2,"div")(3,"select",2),z("ngModelChange",function(o){return ee(n),C().settings.assembly=o})("ngModelChange",function(){return ee(n),C().updateRiskHotpots()}),y(4,"option",3),b(5),v(),E(6,XS,2,2,"option",4),v()(),y(7,"div",5),E(8,ex,2,1,"span",0),E(9,ix,7,5,"select",6),v(),F(10,"div",5),y(11,"div",7)(12,"span"),b(13),v(),y(14,"input",8),z("ngModelChange",function(o){return ee(n),C().settings.filter=o})("ngModelChange",function(){return ee(n),C().updateRiskHotpots()}),v()()(),y(15,"div",9)(16,"table",10)(17,"colgroup"),F(18,"col")(19,"col")(20,"col"),E(21,sx,1,0,"col",11),v(),y(22,"thead")(23,"tr")(24,"th")(25,"a",12),z("click",function(o){return ee(n),C().updateSorting("assembly",o)}),F(26,"i",13),b(27),v()(),y(28,"th")(29,"a",12),z("click",function(o){return ee(n),C().updateSorting("class",o)}),F(30,"i",13),b(31),v()(),y(32,"th")(33,"a",12),z("click",function(o){return ee(n),C().updateSorting("method",o)}),F(34,"i",13),b(35),v()(),E(36,ax,6,7,"th",14),v()(),y(37,"tbody"),E(38,cx,10,7,"tr",14),function mg(e,t){const n=K();let r;const o=e+20;n.firstCreatePass?(r=function xE(e,t){if(t)for(let n=t.length-1;n>=0;n--){const r=t[n];if(e===r.name)return r}}(t,n.pipeRegistry),n.data[o]=r,r.onDestroy&&(n.destroyHooks||(n.destroyHooks=[])).push(o,r.onDestroy)):r=n.data[o];const i=r.factory||(r.factory=An(r.type)),s=tn(A);try{const a=Xo(!1),l=i();return Xo(a),function Zw(e,t,n,r){n>=e.data.length&&(e.data[n]=null,e.blueprint[n]=null),t[n]=r}(n,w(),o,l),l}finally{tn(s)}}(39,"slice"),v()()()()}if(2&e){const n=C();h(3),g("ngModel",n.settings.assembly),h(2),x(n.translations.assembly),h(1),g("ngForOf",n.assemblies),h(2),g("ngIf",n.totalNumberOfRiskHotspots>10),h(1),g("ngIf",n.totalNumberOfRiskHotspots>10),h(4),q("",n.translations.filter," "),h(1),g("ngModel",n.settings.filter),h(7),g("ngForOf",n.riskHotspotMetrics),h(5),g("ngClass",xe(20,ps,"assembly"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"assembly"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"assembly"!==n.settings.sortBy)),h(1),x(n.translations.assembly),h(3),g("ngClass",xe(24,ps,"class"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"class"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"class"!==n.settings.sortBy)),h(1),x(n.translations.class),h(3),g("ngClass",xe(28,ps,"method"===n.settings.sortBy&&"desc"===n.settings.sortOrder,"method"===n.settings.sortBy&&"asc"===n.settings.sortOrder,"method"!==n.settings.sortBy)),h(1),x(n.translations.method),h(1),g("ngForOf",n.riskHotspotMetrics),h(2),g("ngForOf",function _g(e,t,n,r,o){const i=e+20,s=w(),a=function Gn(e,t){return e[t]}(s,i);return function go(e,t){return e[1].data[t].pure}(s,i)?hg(s,He(),t,a.transform,n,r,o,a):a.transform(n,r,o)}(39,16,n.riskHotspots,0,n.settings.numberOfRiskHotspots))}}let fx=(()=>{class e{constructor(n){this.queryString="",this.riskHotspotMetrics=[],this.riskHotspots=[],this.totalNumberOfRiskHotspots=0,this.assemblies=[],this.translations={},this.settings=new JS,this.window=n.nativeWindow}ngOnInit(){this.riskHotspotMetrics=this.window.riskHotspotMetrics,this.translations=this.window.translations,void 0!==this.window.history&&void 0!==this.window.history.replaceState&&null!==this.window.history.state&&null!=this.window.history.state.riskHotspotsSettings&&(console.log("Risk hotspots: Restoring from history",this.window.history.state.riskHotspotsSettings),this.settings=JSON.parse(JSON.stringify(this.window.history.state.riskHotspotsSettings)));const n=window.location.href.indexOf("?");n>-1&&(this.queryString=window.location.href.substr(n)),this.updateRiskHotpots()}onDonBeforeUnlodad(){if(void 0!==this.window.history&&void 0!==this.window.history.replaceState){console.log("Risk hotspots: Updating history",this.settings);let n=new q_;null!==window.history.state&&(n=JSON.parse(JSON.stringify(this.window.history.state))),n.riskHotspotsSettings=JSON.parse(JSON.stringify(this.settings)),window.history.replaceState(n,"")}}updateRiskHotpots(){const n=this.window.riskHotspots;if(this.totalNumberOfRiskHotspots=n.length,0===this.assemblies.length){let s=[];for(let a=0;a<n.length;a++)-1===s.indexOf(n[a].assembly)&&s.push(n[a].assembly);this.assemblies=s.sort()}let r=[];for(let s=0;s<n.length;s++)""!==this.settings.filter&&-1===n[s].class.toLowerCase().indexOf(this.settings.filter)||""!==this.settings.assembly&&n[s].assembly!==this.settings.assembly||r.push(n[s]);let o="asc"===this.settings.sortOrder?-1:1,i="asc"===this.settings.sortOrder?1:-1;if("assembly"===this.settings.sortBy)r.sort(function(s,a){return s.assembly===a.assembly?0:s.assembly<a.assembly?o:i});else if("class"===this.settings.sortBy)r.sort(function(s,a){return s.class===a.class?0:s.class<a.class?o:i});else if("method"===this.settings.sortBy)r.sort(function(s,a){return s.methodShortName===a.methodShortName?0:s.methodShortName<a.methodShortName?o:i});else if(""!==this.settings.sortBy){let s=parseInt(this.settings.sortBy,10);r.sort(function(a,l){return a.metrics[s].value===l.metrics[s].value?0:a.metrics[s].value<l.metrics[s].value?o:i})}this.riskHotspots=r}updateSorting(n,r){r.preventDefault(),this.settings.sortOrder=n===this.settings.sortBy&&"asc"===this.settings.sortOrder?"desc":"asc",this.settings.sortBy=n,console.log(`Updating sort column: '${this.settings.sortBy}' (${this.settings.sortOrder})`),this.updateRiskHotpots()}}return e.\u0275fac=function(n){return new(n||e)(A(Yu))},e.\u0275cmp=rn({type:e,selectors:[["risk-hotspots"]],hostBindings:function(n,r){1&n&&z("beforeunload",function(){return r.onDonBeforeUnlodad()},!1,Ma)},decls:1,vars:1,consts:[[4,"ngIf"],[1,"customizebox"],["name","assembly",3,"ngModel","ngModelChange"],["value",""],[3,"value",4,"ngFor","ngForOf"],[1,"center"],[3,"ngModel","ngModelChange",4,"ngIf"],[1,"right"],["type","text",3,"ngModel","ngModelChange"],[1,"table-responsive"],[1,"overview","table-fixed","stripped"],["class","column105",4,"ngFor","ngForOf"],["href","#",3,"click"],[1,"icon-down-dir",3,"ngClass"],[4,"ngFor","ngForOf"],[3,"value"],[3,"ngModel","ngModelChange"],["value","10"],["value","20",4,"ngIf"],["value","50",4,"ngIf"],["value","100",4,"ngIf"],[3,"value",4,"ngIf"],["value","20"],["value","50"],["value","100"],[1,"column105"],[3,"href"],[1,"icon-info-circled"],[3,"title"],["class","right",3,"ngClass",4,"ngFor","ngForOf"],[1,"right",3,"ngClass"]],template:function(n,r){1&n&&E(0,dx,40,32,"div",0),2&n&&g("ngIf",r.totalNumberOfRiskHotspots>0)},directives:[xr,So,Au,hs,Gu,Wu,fu,Eo,Do],pipes:[Am],encapsulation:2}),e})(),hx=(()=>{class e{}return e.\u0275fac=function(n){return new(n||e)},e.\u0275mod=on({type:e,bootstrap:[fx,KS]}),e.\u0275inj=Gt({providers:[Yu],imports:[[QI,fT]]}),e})();(function L1(){tm=!1})(),qI().bootstrapModule(hx).catch(e=>console.error(e))}},pe=>{pe(pe.s=873)}]);
\ No newline at end of file
diff --git a/ld_client/doc/coverage/coveragereport/report.css b/ld_client/doc/coverage/coveragereport/report.css
new file mode 100644
index 0000000..06b6d2d
--- /dev/null
+++ b/ld_client/doc/coverage/coveragereport/report.css
@@ -0,0 +1,736 @@
+html { font-family: sans-serif; margin: 0; padding: 0; font-size: 0.9em; background-color: #d6d6d6; height: 100%; }
+body { margin: 0; padding: 0; height: 100%; color: #000; }
+h1 { font-family: 'Century Gothic', sans-serif; font-size: 1.2em; font-weight: normal; color: #fff; background-color: #6f6f6f; padding: 10px; margin: 20px -20px 20px -20px;  }
+h1:first-of-type { margin-top: 0; }
+h2 { font-size: 1.0em; font-weight: bold; margin: 10px 0 15px 0; padding: 0; }
+h3 { font-size: 1.0em; font-weight: bold; margin: 0 0 10px 0; padding: 0; display: inline-block; }
+a { color: #c00; text-decoration: none; }
+a:hover { color: #000; text-decoration: none; }
+h1 a.back { color: #fff; background-color: #949494; display: inline-block; margin: -12px 5px -10px -10px; padding: 10px; border-right: 1px solid #fff; }
+h1 a.back:hover { background-color: #ccc; }
+h1 a.button { color: #000; background-color: #bebebe; margin: -5px 0 0 10px; padding: 5px 8px 5px 8px; border: 1px solid #fff; font-size: 0.9em; border-radius: 3px; float:right; }
+h1 a.button:hover { background-color: #ccc; }
+h1 a.button i { position: relative; top: 1px; }
+
+.container { margin: auto; max-width: 1650px; width: 90%; background-color: #fff; display: flex; box-shadow: 0 0 60px #7d7d7d; min-height: 100%; }
+.containerleft { padding: 0 20px 20px 20px; flex: 1; min-width: 1%; }
+.containerright { width: 340px; min-width: 340px; background-color: #e5e5e5; height: 100%; }
+.containerrightfixed { position: fixed; padding: 0 20px 20px 20px; border-left: 1px solid #6f6f6f; width: 300px; overflow-y: auto; height: 100%; top: 0; bottom: 0; }
+.containerrightfixed h1 { background-color: #c00; }
+.containerrightfixed label, .containerright a { white-space: nowrap; overflow: hidden; display: inline-block; width: 100%; max-width: 300px; text-overflow: ellipsis; }
+.containerright a { margin-bottom: 3px; }
+
+@media screen and (max-width:1200px){ 
+    .container { box-shadow: none; width: 100%; }
+    .containerright { display: none; }
+}
+
+.footer { font-size: 0.7em; text-align: center; margin-top: 35px; }
+
+.card-group { display: flex; flex-wrap: wrap; margin-top: -15px; margin-left: -15px; }
+.card-group + .card-group { margin-top: 0; }
+.card-group .card { margin-top: 15px; margin-left: 15px; display: flex; flex-direction: column; background-color: #e4e4e4; background: radial-gradient(circle, #fefefe 0%, #f6f6f6 100%); border: 1px solid #c1c1c1; padding: 15px; color: #6f6f6f; max-width: 100% }
+.card-group .card .card-header { font-size: 1.5rem; font-family: 'Century Gothic', sans-serif; margin-bottom: 15px; flex-grow: 1; }
+.card-group .card .card-body { display: flex; flex-direction: row; gap: 15px; flex-grow: 1; }
+.card-group .card .card-body div.table { display: flex; flex-direction: column; }
+.card-group .card .large { font-size: 5rem; line-height: 5rem; font-weight: bold; align-self: flex-end; border-left-width: 4px; padding-left: 10px; }
+.card-group .card table { align-self: flex-end; border-collapse: collapse; }
+.card-group .card table tr { border-bottom: 1px solid #c1c1c1; }
+.card-group .card table tr:hover { background-color: #c1c1c1; }
+.card-group .card table tr:last-child { border-bottom: none; }
+.card-group .card table th, .card-group .card table td { padding: 2px; }
+.card-group td.limit-width { max-width: 200px; text-overflow: ellipsis; overflow: hidden; }
+.card-group td.overflow-wrap { overflow-wrap: anywhere; }
+
+.pro-button { color: #fff; background-color: #20A0D2; background-image: linear-gradient(50deg, #1c7ed6 0%, #23b8cf 100%); padding: 10px; border-radius: 3px; font-weight: bold; display: inline-block; }
+.pro-button:hover { color: #fff; background-color: #1C8EB7; background-image: linear-gradient(50deg, #1A6FBA 0%, #1EA1B5 100%); }
+
+th { text-align: left; }
+.table-fixed { table-layout: fixed; }
+.table-responsive { overflow-x: auto; }
+.overview { border: 1px solid #c1c1c1; border-collapse: collapse; width: 100%; word-wrap: break-word; }
+.overview th { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 4px 2px 4px; background-color: #ddd; }
+.overview tr.namespace th { background-color: #dcdcdc; }
+.overview thead th { background-color: #d1d1d1; }
+.overview th a { color: #000; }
+.overview tr.namespace a { margin-left: 15px; display: block; }
+.overview td { border: 1px solid #c1c1c1; border-collapse: collapse; padding: 2px 5px 2px 5px; }
+.overview tr.header th { background-color: #d1d1d1; }
+.overview tr.header th:nth-child(2n+1) { background-color: #ddd; }
+.overview tr.header th:first-child { border-left: 1px solid #fff; border-top: 1px solid #fff; background-color: #fff; }
+
+div.currenthistory { margin: -2px -5px 0 -5px; padding: 2px 5px 2px 5px; height: 16px; }
+.coverage { border-collapse: collapse; font-size: 5px; height: 10px; }
+.coverage td { padding: 0; border: none; }
+.stripped tr:nth-child(2n+1) { background-color: #F3F3F3; }
+
+.customizebox { font-size: 0.75em; margin-bottom: 7px; }
+.customizebox>div { width: 25%; display: inline-block; }
+.customizebox div.right input { width: 150px; }
+#namespaceslider { width: 200px; display: inline-block; margin-left: 8px; }
+
+.percentagebar {
+    padding-left: 3px;
+}
+a.percentagebar {
+    padding-left: 6px;
+}
+.percentagebarundefined {
+    border-left: 2px solid #fff;
+}
+.percentagebar0 {
+    border-left: 2px solid #c10909;
+}
+.percentagebar10 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 90%, #0aad0a 90%, #0aad0a 100%) 1;
+}
+.percentagebar20 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 80%, #0aad0a 80%, #0aad0a 100%) 1;
+}
+.percentagebar30 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 70%, #0aad0a 70%, #0aad0a 100%) 1;
+}
+.percentagebar40 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 60%, #0aad0a 60%, #0aad0a 100%) 1;
+}
+.percentagebar50 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 50%, #0aad0a 50%, #0aad0a 100%) 1;
+}
+.percentagebar60 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 40%, #0aad0a 40%, #0aad0a 100%) 1;
+}
+.percentagebar70 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 30%, #0aad0a 30%, #0aad0a 100%) 1;
+}
+.percentagebar80 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 20%, #0aad0a 20%, #0aad0a 100%) 1;
+}
+.percentagebar90 {
+    border-left: 2px solid;
+    border-image: linear-gradient(to bottom, #c10909 10%, #0aad0a 10%, #0aad0a 100%) 1;
+}
+.percentagebar100 {
+    border-left: 2px solid #0aad0a;
+}
+
+.hidden, .ng-hide { display: none; }
+.right { text-align: right; }
+.center { text-align: center; }
+.rightmargin  { padding-right: 8px; }
+.leftmargin { padding-left: 5px; }
+.green { background-color: #0aad0a; }
+.lightgreen { background-color: #dcf4dc; }
+.red { background-color: #c10909; }
+.lightred { background-color: #f7dede; }
+.orange { background-color: #FFA500; }
+.lightorange { background-color: #FFEFD5; }
+.gray { background-color: #dcdcdc; }
+.lightgray { color: #888888; }
+.lightgraybg { background-color: #dadada; }
+
+code { font-family: Consolas, monospace; font-size: 0.9em; }
+
+.toggleZoom { text-align:right; }
+
+.ct-chart { position: relative; }
+.ct-chart .ct-line { stroke-width: 2px !important; }
+.ct-chart .ct-point { stroke-width: 6px !important; transition: stroke-width .2s; }
+.ct-chart .ct-point:hover { stroke-width: 10px !important; }
+.ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point { stroke: #c00 !important;}
+.ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point { stroke: #1c2298 !important;}
+.ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point { stroke: #0aad0a !important;}
+
+.tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart { background-color: #fff; margin-left: -3px; float: left; border: 1px solid #c1c1c1; width: 30px; height: 18px; }
+.historiccoverageoffset { margin-top: 7px; }
+
+.tinylinecoveragechart .ct-line, .tinybranchcoveragechart .ct-line, .tinymethodcoveragechart .ct-line { stroke-width: 1px !important; }
+.tinybranchcoveragechart .ct-series.ct-series-a .ct-line { stroke: #1c2298 !important; }
+.tinymethodcoveragechart .ct-series.ct-series-a .ct-line { stroke: #0aad0a !important; }
+
+.linecoverage { background-color: #c00; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; }
+.branchcoverage { background-color: #1c2298; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; }
+.codeelementcoverage { background-color: #0aad0a; width: 10px; height: 8px; border: 1px solid #000; display: inline-block; }
+
+.tooltip { position: absolute; display: none; padding: 5px; background: #F4C63D; color: #453D3F; pointer-events: none; z-index: 1; min-width: 250px; }
+
+.column-min-200 { min-width: 200px; }
+.column60 { width: 60px; }
+.column70 { width: 70px; }
+.column90 { width: 90px; }
+.column98 { width: 98px; }
+.column100 { width: 100px; }
+.column105 { width: 105px; }
+.column112 { width: 112px; }
+
+.cardpercentagebar { border-left-style: solid; }
+.cardpercentagebar0 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 0%, #0aad0a 0%) 1; }
+.cardpercentagebar1 { border-image: linear-gradient(to bottom, #c10909 1%, #c10909 1%, #0aad0a 1%) 1; }
+.cardpercentagebar2 { border-image: linear-gradient(to bottom, #c10909 2%, #c10909 2%, #0aad0a 2%) 1; }
+.cardpercentagebar3 { border-image: linear-gradient(to bottom, #c10909 3%, #c10909 3%, #0aad0a 3%) 1; }
+.cardpercentagebar4 { border-image: linear-gradient(to bottom, #c10909 4%, #c10909 4%, #0aad0a 4%) 1; }
+.cardpercentagebar5 { border-image: linear-gradient(to bottom, #c10909 5%, #c10909 5%, #0aad0a 5%) 1; }
+.cardpercentagebar6 { border-image: linear-gradient(to bottom, #c10909 6%, #c10909 6%, #0aad0a 6%) 1; }
+.cardpercentagebar7 { border-image: linear-gradient(to bottom, #c10909 7%, #c10909 7%, #0aad0a 7%) 1; }
+.cardpercentagebar8 { border-image: linear-gradient(to bottom, #c10909 8%, #c10909 8%, #0aad0a 8%) 1; }
+.cardpercentagebar9 { border-image: linear-gradient(to bottom, #c10909 9%, #c10909 9%, #0aad0a 9%) 1; }
+.cardpercentagebar10 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 10%, #0aad0a 10%) 1; }
+.cardpercentagebar11 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 11%, #0aad0a 11%) 1; }
+.cardpercentagebar12 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 12%, #0aad0a 12%) 1; }
+.cardpercentagebar13 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 13%, #0aad0a 13%) 1; }
+.cardpercentagebar14 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 14%, #0aad0a 14%) 1; }
+.cardpercentagebar15 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 15%, #0aad0a 15%) 1; }
+.cardpercentagebar16 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 16%, #0aad0a 16%) 1; }
+.cardpercentagebar17 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 17%, #0aad0a 17%) 1; }
+.cardpercentagebar18 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 18%, #0aad0a 18%) 1; }
+.cardpercentagebar19 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 19%, #0aad0a 19%) 1; }
+.cardpercentagebar20 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 20%, #0aad0a 20%) 1; }
+.cardpercentagebar21 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 21%, #0aad0a 21%) 1; }
+.cardpercentagebar22 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 22%, #0aad0a 22%) 1; }
+.cardpercentagebar23 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 23%, #0aad0a 23%) 1; }
+.cardpercentagebar24 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 24%, #0aad0a 24%) 1; }
+.cardpercentagebar25 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 25%, #0aad0a 25%) 1; }
+.cardpercentagebar26 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 26%, #0aad0a 26%) 1; }
+.cardpercentagebar27 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 27%, #0aad0a 27%) 1; }
+.cardpercentagebar28 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 28%, #0aad0a 28%) 1; }
+.cardpercentagebar29 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 29%, #0aad0a 29%) 1; }
+.cardpercentagebar30 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 30%, #0aad0a 30%) 1; }
+.cardpercentagebar31 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 31%, #0aad0a 31%) 1; }
+.cardpercentagebar32 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 32%, #0aad0a 32%) 1; }
+.cardpercentagebar33 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 33%, #0aad0a 33%) 1; }
+.cardpercentagebar34 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 34%, #0aad0a 34%) 1; }
+.cardpercentagebar35 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 35%, #0aad0a 35%) 1; }
+.cardpercentagebar36 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 36%, #0aad0a 36%) 1; }
+.cardpercentagebar37 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 37%, #0aad0a 37%) 1; }
+.cardpercentagebar38 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 38%, #0aad0a 38%) 1; }
+.cardpercentagebar39 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 39%, #0aad0a 39%) 1; }
+.cardpercentagebar40 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 40%, #0aad0a 40%) 1; }
+.cardpercentagebar41 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 41%, #0aad0a 41%) 1; }
+.cardpercentagebar42 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 42%, #0aad0a 42%) 1; }
+.cardpercentagebar43 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 43%, #0aad0a 43%) 1; }
+.cardpercentagebar44 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 44%, #0aad0a 44%) 1; }
+.cardpercentagebar45 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 45%, #0aad0a 45%) 1; }
+.cardpercentagebar46 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 46%, #0aad0a 46%) 1; }
+.cardpercentagebar47 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 47%, #0aad0a 47%) 1; }
+.cardpercentagebar48 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 48%, #0aad0a 48%) 1; }
+.cardpercentagebar49 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 49%, #0aad0a 49%) 1; }
+.cardpercentagebar50 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 50%, #0aad0a 50%) 1; }
+.cardpercentagebar51 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 51%, #0aad0a 51%) 1; }
+.cardpercentagebar52 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 52%, #0aad0a 52%) 1; }
+.cardpercentagebar53 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 53%, #0aad0a 53%) 1; }
+.cardpercentagebar54 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 54%, #0aad0a 54%) 1; }
+.cardpercentagebar55 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 55%, #0aad0a 55%) 1; }
+.cardpercentagebar56 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 56%, #0aad0a 56%) 1; }
+.cardpercentagebar57 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 57%, #0aad0a 57%) 1; }
+.cardpercentagebar58 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 58%, #0aad0a 58%) 1; }
+.cardpercentagebar59 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 59%, #0aad0a 59%) 1; }
+.cardpercentagebar60 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 60%, #0aad0a 60%) 1; }
+.cardpercentagebar61 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 61%, #0aad0a 61%) 1; }
+.cardpercentagebar62 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 62%, #0aad0a 62%) 1; }
+.cardpercentagebar63 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 63%, #0aad0a 63%) 1; }
+.cardpercentagebar64 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 64%, #0aad0a 64%) 1; }
+.cardpercentagebar65 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 65%, #0aad0a 65%) 1; }
+.cardpercentagebar66 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 66%, #0aad0a 66%) 1; }
+.cardpercentagebar67 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 67%, #0aad0a 67%) 1; }
+.cardpercentagebar68 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 68%, #0aad0a 68%) 1; }
+.cardpercentagebar69 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 69%, #0aad0a 69%) 1; }
+.cardpercentagebar70 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 70%, #0aad0a 70%) 1; }
+.cardpercentagebar71 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 71%, #0aad0a 71%) 1; }
+.cardpercentagebar72 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 72%, #0aad0a 72%) 1; }
+.cardpercentagebar73 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 73%, #0aad0a 73%) 1; }
+.cardpercentagebar74 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 74%, #0aad0a 74%) 1; }
+.cardpercentagebar75 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 75%, #0aad0a 75%) 1; }
+.cardpercentagebar76 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 76%, #0aad0a 76%) 1; }
+.cardpercentagebar77 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 77%, #0aad0a 77%) 1; }
+.cardpercentagebar78 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 78%, #0aad0a 78%) 1; }
+.cardpercentagebar79 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 79%, #0aad0a 79%) 1; }
+.cardpercentagebar80 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 80%, #0aad0a 80%) 1; }
+.cardpercentagebar81 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 81%, #0aad0a 81%) 1; }
+.cardpercentagebar82 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 82%, #0aad0a 82%) 1; }
+.cardpercentagebar83 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 83%, #0aad0a 83%) 1; }
+.cardpercentagebar84 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 84%, #0aad0a 84%) 1; }
+.cardpercentagebar85 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 85%, #0aad0a 85%) 1; }
+.cardpercentagebar86 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 86%, #0aad0a 86%) 1; }
+.cardpercentagebar87 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 87%, #0aad0a 87%) 1; }
+.cardpercentagebar88 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 88%, #0aad0a 88%) 1; }
+.cardpercentagebar89 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 89%, #0aad0a 89%) 1; }
+.cardpercentagebar90 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 90%, #0aad0a 90%) 1; }
+.cardpercentagebar91 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 91%, #0aad0a 91%) 1; }
+.cardpercentagebar92 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 92%, #0aad0a 92%) 1; }
+.cardpercentagebar93 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 93%, #0aad0a 93%) 1; }
+.cardpercentagebar94 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 94%, #0aad0a 94%) 1; }
+.cardpercentagebar95 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 95%, #0aad0a 95%) 1; }
+.cardpercentagebar96 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 96%, #0aad0a 96%) 1; }
+.cardpercentagebar97 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 97%, #0aad0a 97%) 1; }
+.cardpercentagebar98 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 98%, #0aad0a 98%) 1; }
+.cardpercentagebar99 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 99%, #0aad0a 99%) 1; }
+.cardpercentagebar100 { border-image: linear-gradient(to bottom, #c10909 0%, #c10909 100%, #0aad0a 100%) 1; }
+
+.covered0 { width: 0px; }
+.covered1 { width: 1px; }
+.covered2 { width: 2px; }
+.covered3 { width: 3px; }
+.covered4 { width: 4px; }
+.covered5 { width: 5px; }
+.covered6 { width: 6px; }
+.covered7 { width: 7px; }
+.covered8 { width: 8px; }
+.covered9 { width: 9px; }
+.covered10 { width: 10px; }
+.covered11 { width: 11px; }
+.covered12 { width: 12px; }
+.covered13 { width: 13px; }
+.covered14 { width: 14px; }
+.covered15 { width: 15px; }
+.covered16 { width: 16px; }
+.covered17 { width: 17px; }
+.covered18 { width: 18px; }
+.covered19 { width: 19px; }
+.covered20 { width: 20px; }
+.covered21 { width: 21px; }
+.covered22 { width: 22px; }
+.covered23 { width: 23px; }
+.covered24 { width: 24px; }
+.covered25 { width: 25px; }
+.covered26 { width: 26px; }
+.covered27 { width: 27px; }
+.covered28 { width: 28px; }
+.covered29 { width: 29px; }
+.covered30 { width: 30px; }
+.covered31 { width: 31px; }
+.covered32 { width: 32px; }
+.covered33 { width: 33px; }
+.covered34 { width: 34px; }
+.covered35 { width: 35px; }
+.covered36 { width: 36px; }
+.covered37 { width: 37px; }
+.covered38 { width: 38px; }
+.covered39 { width: 39px; }
+.covered40 { width: 40px; }
+.covered41 { width: 41px; }
+.covered42 { width: 42px; }
+.covered43 { width: 43px; }
+.covered44 { width: 44px; }
+.covered45 { width: 45px; }
+.covered46 { width: 46px; }
+.covered47 { width: 47px; }
+.covered48 { width: 48px; }
+.covered49 { width: 49px; }
+.covered50 { width: 50px; }
+.covered51 { width: 51px; }
+.covered52 { width: 52px; }
+.covered53 { width: 53px; }
+.covered54 { width: 54px; }
+.covered55 { width: 55px; }
+.covered56 { width: 56px; }
+.covered57 { width: 57px; }
+.covered58 { width: 58px; }
+.covered59 { width: 59px; }
+.covered60 { width: 60px; }
+.covered61 { width: 61px; }
+.covered62 { width: 62px; }
+.covered63 { width: 63px; }
+.covered64 { width: 64px; }
+.covered65 { width: 65px; }
+.covered66 { width: 66px; }
+.covered67 { width: 67px; }
+.covered68 { width: 68px; }
+.covered69 { width: 69px; }
+.covered70 { width: 70px; }
+.covered71 { width: 71px; }
+.covered72 { width: 72px; }
+.covered73 { width: 73px; }
+.covered74 { width: 74px; }
+.covered75 { width: 75px; }
+.covered76 { width: 76px; }
+.covered77 { width: 77px; }
+.covered78 { width: 78px; }
+.covered79 { width: 79px; }
+.covered80 { width: 80px; }
+.covered81 { width: 81px; }
+.covered82 { width: 82px; }
+.covered83 { width: 83px; }
+.covered84 { width: 84px; }
+.covered85 { width: 85px; }
+.covered86 { width: 86px; }
+.covered87 { width: 87px; }
+.covered88 { width: 88px; }
+.covered89 { width: 89px; }
+.covered90 { width: 90px; }
+.covered91 { width: 91px; }
+.covered92 { width: 92px; }
+.covered93 { width: 93px; }
+.covered94 { width: 94px; }
+.covered95 { width: 95px; }
+.covered96 { width: 96px; }
+.covered97 { width: 97px; }
+.covered98 { width: 98px; }
+.covered99 { width: 99px; }
+.covered100 { width: 100px; }
+
+ @media print {
+    html, body { background-color: #fff; }
+    .container { max-width: 100%; width: 100%; padding: 0; }
+    .overview colgroup col:first-child { width: 300px; }
+}
+
+.icon-up-dir_active {
+    background-image: url(icon_up-dir.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDEyMTZxMCAyNi0xOSA0NXQtNDUgMTloLTg5NnEtMjYgMC00NS0xOXQtMTktNDUgMTktNDVsNDQ4LTQ0OHExOS0xOSA0NS0xOXQ0NSAxOWw0NDggNDQ4cTE5IDE5IDE5IDQ1eiIvPjwvc3ZnPg==);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+    position: relative;
+    top: 3px;
+}
+.icon-down-dir_active {
+    background-image: url(icon_up-dir_active.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNDA4IDcwNHEwIDI2LTE5IDQ1bC00NDggNDQ4cS0xOSAxOS00NSAxOXQtNDUtMTlsLTQ0OC00NDhxLTE5LTE5LTE5LTQ1dDE5LTQ1IDQ1LTE5aDg5NnEyNiAwIDQ1IDE5dDE5IDQ1eiIvPjwvc3ZnPg==);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+    position: relative;
+    top: 3px;
+}
+.icon-down-dir {
+    background-image: url(icon_down-dir_active.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNDA4IDcwNHEwIDI2LTE5IDQ1bC00NDggNDQ4cS0xOSAxOS00NSAxOXQtNDUtMTlsLTQ0OC00NDhxLTE5LTE5LTE5LTQ1dDE5LTQ1IDQ1LTE5aDg5NnEyNiAwIDQ1IDE5dDE5IDQ1eiIvPjwvc3ZnPg==);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+    position: relative;
+    top: 3px;
+}
+.icon-info-circled {
+    background-image: url(icon_info-circled.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-plus {
+    background-image: url(icon_plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTQxNnY0MTZxMCA0MC0yOCA2OHQtNjggMjhoLTE5MnEtNDAgMC02OC0yOHQtMjgtNjh2LTQxNmgtNDE2cS00MCAwLTY4LTI4dC0yOC02OHYtMTkycTAtNDAgMjgtNjh0NjgtMjhoNDE2di00MTZxMC00MCAyOC02OHQ2OC0yOGgxOTJxNDAgMCA2OCAyOHQyOCA2OHY0MTZoNDE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+    position: relative;
+    top: 3px;
+}
+.icon-minus {
+    background-image: url(icon_minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiNjMDAiIGQ9Ik0xNjAwIDczNnYxOTJxMCA0MC0yOCA2OHQtNjggMjhoLTEyMTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGgxMjE2cTQwIDAgNjggMjh0MjggNjh6Ii8+PC9zdmc+);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 15px;
+    height: 0.9em;
+    display: inline-block;
+    position: relative;
+    top: 3px;
+}
+.icon-wrench {
+    background-image: url(icon_wrench.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik00NDggMTQ3MnEwLTI2LTE5LTQ1dC00NS0xOS00NSAxOS0xOSA0NSAxOSA0NSA0NSAxOSA0NS0xOSAxOS00NXptNjQ0LTQyMGwtNjgyIDY4MnEtMzcgMzctOTAgMzctNTIgMC05MS0zN2wtMTA2LTEwOHEtMzgtMzYtMzgtOTAgMC01MyAzOC05MWw2ODEtNjgxcTM5IDk4IDExNC41IDE3My41dDE3My41IDExNC41em02MzQtNDM1cTAgMzktMjMgMTA2LTQ3IDEzNC0xNjQuNSAyMTcuNXQtMjU4LjUgODMuNXEtMTg1IDAtMzE2LjUtMTMxLjV0LTEzMS41LTMxNi41IDEzMS41LTMxNi41IDMxNi41LTEzMS41cTU4IDAgMTIxLjUgMTYuNXQxMDcuNSA0Ni41cTE2IDExIDE2IDI4dC0xNiAyOGwtMjkzIDE2OXYyMjRsMTkzIDEwN3E1LTMgNzktNDguNXQxMzUuNS04MSA3MC41LTM1LjVxMTUgMCAyMy41IDEwdDguNSAyNXoiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-fork {
+    background-image: url(icon_fork.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxyZWN0IHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHN0eWxlPSJmaWxsOiNmZmYiIC8+PHBhdGggZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-cube {
+    background-image: url(icon_cube.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTYyOWw2NDAtMzQ5di02MzZsLTY0MCAyMzN2NzUyem0tNjQtODY1bDY5OC0yNTQtNjk4LTI1NC02OTggMjU0em04MzItMjUydjc2OHEwIDM1LTE4IDY1dC00OSA0N2wtNzA0IDM4NHEtMjggMTYtNjEgMTZ0LTYxLTE2bC03MDQtMzg0cS0zMS0xNy00OS00N3QtMTgtNjV2LTc2OHEwLTQwIDIzLTczdDYxLTQ3bDcwNC0yNTZxMjItOCA0NC04dDQ0IDhsNzA0IDI1NnEzOCAxNCA2MSA0N3QyMyA3M3oiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-search-plus {
+    background-image: url(icon_search-plus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtMjI0djIyNHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNjRxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di0yMjRoLTIyNHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTY0cTAtMTMgOS41LTIyLjV0MjIuNS05LjVoMjI0di0yMjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg2NHExMyAwIDIyLjUgOS41dDkuNSAyMi41djIyNGgyMjRxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-search-minus {
+    background-image: url(icon_search-minus.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGZpbGw9IiM2ZjZmNmYiIGQ9Ik0xMDg4IDgwMHY2NHEwIDEzLTkuNSAyMi41dC0yMi41IDkuNWgtNTc2cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWg1NzZxMTMgMCAyMi41IDkuNXQ5LjUgMjIuNXptMTI4IDMycTAtMTg1LTEzMS41LTMxNi41dC0zMTYuNS0xMzEuNS0zMTYuNSAxMzEuNS0xMzEuNSAzMTYuNSAxMzEuNSAzMTYuNSAzMTYuNSAxMzEuNSAzMTYuNS0xMzEuNSAxMzEuNS0zMTYuNXptNTEyIDgzMnEwIDUzLTM3LjUgOTAuNXQtOTAuNSAzNy41cS01NCAwLTkwLTM4bC0zNDMtMzQycS0xNzkgMTI0LTM5OSAxMjQtMTQzIDAtMjczLjUtNTUuNXQtMjI1LTE1MC0xNTAtMjI1LTU1LjUtMjczLjUgNTUuNS0yNzMuNSAxNTAtMjI1IDIyNS0xNTAgMjczLjUtNTUuNSAyNzMuNSA1NS41IDIyNSAxNTAgMTUwIDIyNSA1NS41IDI3My41cTAgMjIwLTEyNCAzOTlsMzQzIDM0M3EzNyAzNyAzNyA5MHoiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-star {
+    background-image: url(icon_star.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiMwMDAiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+.icon-sponsor {
+    background-image: url(icon_sponsor.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik04OTYgMTY2NHEtMjYgMC00NC0xOGwtNjI0LTYwMnEtMTAtOC0yNy41LTI2dC01NS41LTY1LjUtNjgtOTcuNS01My41LTEyMS0yMy41LTEzOHEwLTIyMCAxMjctMzQ0dDM1MS0xMjRxNjIgMCAxMjYuNSAyMS41dDEyMCA1OCA5NS41IDY4LjUgNzYgNjhxMzYtMzYgNzYtNjh0OTUuNS02OC41IDEyMC01OCAxMjYuNS0yMS41cTIyNCAwIDM1MSAxMjR0MTI3IDM0NHEwIDIyMS0yMjkgNDUwbC02MjMgNjAwcS0xOCAxOC00NCAxOHoiIGZpbGw9IiNlYTRhYWEiLz48L3N2Zz4=);
+    background-repeat: no-repeat;
+    background-size: contain;
+    padding-left: 20px;
+    height: 0.9em;
+    display: inline-block;
+}
+
+
+
+@media (prefers-color-scheme: dark) {
+    @media screen {
+        html {
+            background-color: #333;
+            color: #fff;
+        }
+
+        body {
+            color: #fff;
+        }
+
+        h1 {
+            background-color: #555453;
+            color: #fff;
+        }
+
+        .container {
+            background-color: #333;
+            box-shadow: 0 0 60px #0c0c0c;
+        }
+
+        .containerrightfixed {
+            background-color: #3D3C3C;
+            border-left: 1px solid #515050;
+        }
+
+            .containerrightfixed h1 {
+                background-color: #484747;
+            }
+
+        .card-group .card {
+            background-color: #333;
+            background: radial-gradient(circle, #444 0%, #333 100%);
+            border: 1px solid #545454;
+            color: #fff;
+        }
+
+            .card-group .card table tr {
+                border-bottom: 1px solid #545454;
+            }
+
+                .card-group .card table tr:hover {
+                    background-color: #2E2D2C;
+                }
+
+        .overview tr:hover {
+            background-color: #2E2D2C;
+        }
+
+        .overview th {
+            background-color: #444;
+            border: 1px solid #3B3A39;
+        }
+
+        .overview tr.namespace th {
+            background-color: #444;
+        }
+
+        .overview thead th {
+            background-color: #444;
+        }
+
+        .overview th a {
+            color: #fff;
+            color: rgba(255, 255, 255, 0.95);
+        }
+
+            .overview th a:hover {
+                color: #0078d4;
+            }
+
+        .overview td {
+            border: 1px solid #3B3A39;
+        }
+
+        .overview .coverage td {
+            border: none;
+        }
+
+        .overview tr.header th {
+            background-color: #444;
+        }
+
+            .overview tr.header th:nth-child(2n+1) {
+                background-color: #3a3a3a;
+            }
+
+            .overview tr.header th:first-child {
+                border-left: 1px solid #333;
+                border-top: 1px solid #333;
+                background-color: #333;
+            }
+
+        .stripped tr:nth-child(2n+1) {
+            background-color: #3c3c3c;
+        }
+
+        input, select {
+            background-color: #333;
+            color: #fff;
+            border: 1px solid #A19F9D;
+        }
+
+        a {
+            color: #fff;
+            color: rgba(255, 255, 255, 0.95);
+        }
+
+            a:hover {
+                color: #0078d4;
+            }
+
+        h1 a.back {
+            background-color: #4a4846;
+        }
+
+        h1 a.button {
+            color: #fff;
+            background-color: #565656;
+            border-color: #c1c1c1;
+        }
+
+            h1 a.button:hover {
+                background-color: #8d8d8d;
+            }
+
+        .gray {
+            background-color: #484747;
+        }
+
+        .lightgray {
+            color: #ebebeb;
+        }
+
+        .lightgraybg {
+            background-color: #474747;
+        }
+
+        .lightgreen {
+            background-color: #406540;
+        }
+
+        .lightorange {
+            background-color: #ab7f36;
+        }
+
+        .lightred {
+            background-color: #954848;
+        }
+
+        .ct-label {
+            color: #fff !important;
+        }
+
+        .ct-grid {
+            stroke: #fff !important;
+        }
+
+        .ct-chart .ct-series.ct-series-a .ct-line, .ct-chart .ct-series.ct-series-a .ct-point {
+            stroke: #0078D4 !important;
+        }
+
+        .ct-chart .ct-series.ct-series-b .ct-line, .ct-chart .ct-series.ct-series-b .ct-point {
+            stroke: #6dc428 !important;
+        }
+
+        .ct-chart .ct-series.ct-series-c .ct-line, .ct-chart .ct-series.ct-series-c .ct-point {
+            stroke: #e58f1d !important;
+        }
+
+        .linecoverage {
+            background-color: #0078D4;
+        }
+
+        .branchcoverage {
+            background-color: #6dc428;
+        }
+        .codeelementcoverage {
+            background-color: #e58f1d;
+        }
+
+        .tinylinecoveragechart, .tinybranchcoveragechart, .tinymethodcoveragechart {
+            background-color: #333;
+        }
+
+            .tinybranchcoveragechart .ct-series.ct-series-a .ct-line {
+                stroke: #6dc428 !important;
+            }
+
+            .tinymethodcoveragechart .ct-series.ct-series-a .ct-line {
+                stroke: #e58f1d !important;
+            }
+
+        .icon-down-dir {
+            background-image: url(icon_down-dir_active_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE0MDggNzA0cTAgMjYtMTkgNDVsLTQ0OCA0NDhxLTE5IDE5LTQ1IDE5dC00NS0xOWwtNDQ4LTQ0OHEtMTktMTktMTktNDV0MTktNDUgNDUtMTloODk2cTI2IDAgNDUgMTl0MTkgNDV6Ii8+PC9zdmc+);
+        }
+
+        .icon-info-circled {
+            background-image: url(icon_info-circled_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxjaXJjbGUgY3g9Ijg5NiIgY3k9Ijg5NiIgcj0iNzUwIiBmaWxsPSIjZmZmIiAvPjxwYXRoIGZpbGw9IiMyOEE1RkYiIGQ9Ik0xMTUyIDEzNzZ2LTE2MHEwLTE0LTktMjN0LTIzLTloLTk2di01MTJxMC0xNC05LTIzdC0yMy05aC0zMjBxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloOTZ2MzIwaC05NnEtMTQgMC0yMyA5dC05IDIzdjE2MHEwIDE0IDkgMjN0MjMgOWg0NDhxMTQgMCAyMy05dDktMjN6bS0xMjgtODk2di0xNjBxMC0xNC05LTIzdC0yMy05aC0xOTJxLTE0IDAtMjMgOXQtOSAyM3YxNjBxMCAxNCA5IDIzdDIzIDloMTkycTE0IDAgMjMtOXQ5LTIzem02NDAgNDE2cTAgMjA5LTEwMyAzODUuNXQtMjc5LjUgMjc5LjUtMzg1LjUgMTAzLTM4NS41LTEwMy0yNzkuNS0yNzkuNS0xMDMtMzg1LjUgMTAzLTM4NS41IDI3OS41LTI3OS41IDM4NS41LTEwMyAzODUuNSAxMDMgMjc5LjUgMjc5LjUgMTAzIDM4NS41eiIvPjwvc3ZnPg==);
+        }
+
+        .icon-plus {
+            background-image: url(icon_plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtNDE2djQxNnEwIDQwLTI4IDY4dC02OCAyOGgtMTkycS00MCAwLTY4LTI4dC0yOC02OHYtNDE2aC00MTZxLTQwIDAtNjgtMjh0LTI4LTY4di0xOTJxMC00MCAyOC02OHQ2OC0yOGg0MTZ2LTQxNnEwLTQwIDI4LTY4dDY4LTI4aDE5MnE0MCAwIDY4IDI4dDI4IDY4djQxNmg0MTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=);
+        }
+
+        .icon-minus {
+            background-image: url(icon_minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTE2MDAgNzM2djE5MnEwIDQwLTI4IDY4dC02OCAyOGgtMTIxNnEtNDAgMC02OC0yOHQtMjgtNjh2LTE5MnEwLTQwIDI4LTY4dDY4LTI4aDEyMTZxNDAgMCA2OCAyOHQyOCA2OHoiLz48L3N2Zz4=);
+        }
+
+        .icon-wrench {
+            background-image: url(icon_wrench_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JEQkRCRiIgZD0iTTQ0OCAxNDcycTAtMjYtMTktNDV0LTQ1LTE5LTQ1IDE5LTE5IDQ1IDE5IDQ1IDQ1IDE5IDQ1LTE5IDE5LTQ1em02NDQtNDIwbC02ODIgNjgycS0zNyAzNy05MCAzNy01MiAwLTkxLTM3bC0xMDYtMTA4cS0zOC0zNi0zOC05MCAwLTUzIDM4LTkxbDY4MS02ODFxMzkgOTggMTE0LjUgMTczLjV0MTczLjUgMTE0LjV6bTYzNC00MzVxMCAzOS0yMyAxMDYtNDcgMTM0LTE2NC41IDIxNy41dC0yNTguNSA4My41cS0xODUgMC0zMTYuNS0xMzEuNXQtMTMxLjUtMzE2LjUgMTMxLjUtMzE2LjUgMzE2LjUtMTMxLjVxNTggMCAxMjEuNSAxNi41dDEwNy41IDQ2LjVxMTYgMTEgMTYgMjh0LTE2IDI4bC0yOTMgMTY5djIyNGwxOTMgMTA3cTUtMyA3OS00OC41dDEzNS41LTgxIDcwLjUtMzUuNXExNSAwIDIzLjUgMTB0OC41IDI1eiIvPjwvc3ZnPg==);
+        }
+
+        .icon-fork {
+            background-image: url(icon_fork_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTY3MiAxNDcycTAtNDAtMjgtNjh0LTY4LTI4LTY4IDI4LTI4IDY4IDI4IDY4IDY4IDI4IDY4LTI4IDI4LTY4em0wLTExNTJxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTY0MCAxMjhxMC00MC0yOC02OHQtNjgtMjgtNjggMjgtMjggNjggMjggNjggNjggMjggNjgtMjggMjgtNjh6bTk2IDBxMCA1Mi0yNiA5Ni41dC03MCA2OS41cS0yIDI4Ny0yMjYgNDE0LTY3IDM4LTIwMyA4MS0xMjggNDAtMTY5LjUgNzF0LTQxLjUgMTAwdjI2cTQ0IDI1IDcwIDY5LjV0MjYgOTYuNXEwIDgwLTU2IDEzNnQtMTM2IDU2LTEzNi01Ni01Ni0xMzZxMC01MiAyNi05Ni41dDcwLTY5LjV2LTgyMHEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnEwIDUyLTI2IDk2LjV0LTcwIDY5LjV2NDk3cTU0LTI2IDE1NC01NyA1NS0xNyA4Ny41LTI5LjV0NzAuNS0zMSA1OS0zOS41IDQwLjUtNTEgMjgtNjkuNSA4LjUtOTEuNXEtNDQtMjUtNzAtNjkuNXQtMjYtOTYuNXEwLTgwIDU2LTEzNnQxMzYtNTYgMTM2IDU2IDU2IDEzNnoiLz48L3N2Zz4=);
+        }
+
+        .icon-cube {
+            background-image: url(icon_cube_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTg5NiAxNjI5bDY0MC0zNDl2LTYzNmwtNjQwIDIzM3Y3NTJ6bS02NC04NjVsNjk4LTI1NC02OTgtMjU0LTY5OCAyNTR6bTgzMi0yNTJ2NzY4cTAgMzUtMTggNjV0LTQ5IDQ3bC03MDQgMzg0cS0yOCAxNi02MSAxNnQtNjEtMTZsLTcwNC0zODRxLTMxLTE3LTQ5LTQ3dC0xOC02NXYtNzY4cTAtNDAgMjMtNzN0NjEtNDdsNzA0LTI1NnEyMi04IDQ0LTh0NDQgOGw3MDQgMjU2cTM4IDE0IDYxIDQ3dDIzIDczeiIvPjwvc3ZnPg==);
+        }
+
+        .icon-search-plus {
+            background-image: url(icon_search-plus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC0yMjR2MjI0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC02NHEtMTMgMC0yMi41LTkuNXQtOS41LTIyLjV2LTIyNGgtMjI0cS0xMyAwLTIyLjUtOS41dC05LjUtMjIuNXYtNjRxMC0xMyA5LjUtMjIuNXQyMi41LTkuNWgyMjR2LTIyNHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDY0cTEzIDAgMjIuNSA5LjV0OS41IDIyLjV2MjI0aDIyNHExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==);
+        }
+
+        .icon-search-minus {
+            background-image: url(icon_search-minus_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHdpZHRoPSIxNzkyIiBoZWlnaHQ9IjE3OTIiIHZpZXdCb3g9IjAgMCAxNzkyIDE3OTIiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PHBhdGggZmlsbD0iI0JGQkZDMCIgZD0iTTEwODggODAwdjY0cTAgMTMtOS41IDIyLjV0LTIyLjUgOS41aC01NzZxLTEzIDAtMjIuNS05LjV0LTkuNS0yMi41di02NHEwLTEzIDkuNS0yMi41dDIyLjUtOS41aDU3NnExMyAwIDIyLjUgOS41dDkuNSAyMi41em0xMjggMzJxMC0xODUtMTMxLjUtMzE2LjV0LTMxNi41LTEzMS41LTMxNi41IDEzMS41LTEzMS41IDMxNi41IDEzMS41IDMxNi41IDMxNi41IDEzMS41IDMxNi41LTEzMS41IDEzMS41LTMxNi41em01MTIgODMycTAgNTMtMzcuNSA5MC41dC05MC41IDM3LjVxLTU0IDAtOTAtMzhsLTM0My0zNDJxLTE3OSAxMjQtMzk5IDEyNC0xNDMgMC0yNzMuNS01NS41dC0yMjUtMTUwLTE1MC0yMjUtNTUuNS0yNzMuNSA1NS41LTI3My41IDE1MC0yMjUgMjI1LTE1MCAyNzMuNS01NS41IDI3My41IDU1LjUgMjI1IDE1MCAxNTAgMjI1IDU1LjUgMjczLjVxMCAyMjAtMTI0IDM5OWwzNDMgMzQzcTM3IDM3IDM3IDkweiIvPjwvc3ZnPg==);
+        }
+
+        .icon-star {
+            background-image: url(icon_star_dark.svg), url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB3aWR0aD0iMTc5MiIgaGVpZ2h0PSIxNzkyIiB2aWV3Qm94PSIwIDAgMTc5MiAxNzkyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0xNzI4IDY0N3EwIDIyLTI2IDQ4bC0zNjMgMzU0IDg2IDUwMHExIDcgMSAyMCAwIDIxLTEwLjUgMzUuNXQtMzAuNSAxNC41cS0xOSAwLTQwLTEybC00NDktMjM2LTQ0OSAyMzZxLTIyIDEyLTQwIDEyLTIxIDAtMzEuNS0xNC41dC0xMC41LTM1LjVxMC02IDItMjBsODYtNTAwLTM2NC0zNTRxLTI1LTI3LTI1LTQ4IDAtMzcgNTYtNDZsNTAyLTczIDIyNS00NTVxMTktNDEgNDktNDF0NDkgNDFsMjI1IDQ1NSA1MDIgNzNxNTYgOSA1NiA0NnoiIGZpbGw9IiNmZmYiLz48L3N2Zz4=);
+        }
+    }
+}
+
+.ct-double-octave:after,.ct-golden-section:after,.ct-major-eleventh:after,.ct-major-second:after,.ct-major-seventh:after,.ct-major-sixth:after,.ct-major-tenth:after,.ct-major-third:after,.ct-major-twelfth:after,.ct-minor-second:after,.ct-minor-seventh:after,.ct-minor-sixth:after,.ct-minor-third:after,.ct-octave:after,.ct-perfect-fifth:after,.ct-perfect-fourth:after,.ct-square:after{content:"";clear:both}.ct-label{fill:rgba(0,0,0,.4);color:rgba(0,0,0,.4);font-size:.75rem;line-height:1}.ct-chart-bar .ct-label,.ct-chart-line .ct-label{display:block;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:-webkit-flex;display:flex}.ct-chart-donut .ct-label,.ct-chart-pie .ct-label{dominant-baseline:central}.ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-label.ct-vertical.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-label.ct-vertical.ct-end{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:center;-webkit-justify-content:center;-ms-flex-pack:center;justify-content:center;text-align:center;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-start{-webkit-box-align:flex-end;-webkit-align-items:flex-end;-ms-flex-align:flex-end;align-items:flex-end;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-horizontal.ct-end{-webkit-box-align:flex-start;-webkit-align-items:flex-start;-ms-flex-align:flex-start;align-items:flex-start;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:start}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-start{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-end;-webkit-justify-content:flex-end;-ms-flex-pack:flex-end;justify-content:flex-end;text-align:right;text-anchor:end}.ct-chart-bar.ct-horizontal-bars .ct-label.ct-vertical.ct-end{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:flex-start;-webkit-justify-content:flex-start;-ms-flex-pack:flex-start;justify-content:flex-start;text-align:left;text-anchor:end}.ct-grid{stroke:rgba(0,0,0,.2);stroke-width:1px;stroke-dasharray:2px}.ct-grid-background{fill:none}.ct-point{stroke-width:10px;stroke-linecap:round}.ct-line{fill:none;stroke-width:4px}.ct-area{stroke:none;fill-opacity:.1}.ct-bar{fill:none;stroke-width:10px}.ct-slice-donut{fill:none;stroke-width:60px}.ct-series-a .ct-bar,.ct-series-a .ct-line,.ct-series-a .ct-point,.ct-series-a .ct-slice-donut{stroke:#d70206}.ct-series-a .ct-area,.ct-series-a .ct-slice-donut-solid,.ct-series-a .ct-slice-pie{fill:#d70206}.ct-series-b .ct-bar,.ct-series-b .ct-line,.ct-series-b .ct-point,.ct-series-b .ct-slice-donut{stroke:#f05b4f}.ct-series-b .ct-area,.ct-series-b .ct-slice-donut-solid,.ct-series-b .ct-slice-pie{fill:#f05b4f}.ct-series-c .ct-bar,.ct-series-c .ct-line,.ct-series-c .ct-point,.ct-series-c .ct-slice-donut{stroke:#f4c63d}.ct-series-c .ct-area,.ct-series-c .ct-slice-donut-solid,.ct-series-c .ct-slice-pie{fill:#f4c63d}.ct-series-d .ct-bar,.ct-series-d .ct-line,.ct-series-d .ct-point,.ct-series-d .ct-slice-donut{stroke:#d17905}.ct-series-d .ct-area,.ct-series-d .ct-slice-donut-solid,.ct-series-d .ct-slice-pie{fill:#d17905}.ct-series-e .ct-bar,.ct-series-e .ct-line,.ct-series-e .ct-point,.ct-series-e .ct-slice-donut{stroke:#453d3f}.ct-series-e .ct-area,.ct-series-e .ct-slice-donut-solid,.ct-series-e .ct-slice-pie{fill:#453d3f}.ct-series-f .ct-bar,.ct-series-f .ct-line,.ct-series-f .ct-point,.ct-series-f .ct-slice-donut{stroke:#59922b}.ct-series-f .ct-area,.ct-series-f .ct-slice-donut-solid,.ct-series-f .ct-slice-pie{fill:#59922b}.ct-series-g .ct-bar,.ct-series-g .ct-line,.ct-series-g .ct-point,.ct-series-g .ct-slice-donut{stroke:#0544d3}.ct-series-g .ct-area,.ct-series-g .ct-slice-donut-solid,.ct-series-g .ct-slice-pie{fill:#0544d3}.ct-series-h .ct-bar,.ct-series-h .ct-line,.ct-series-h .ct-point,.ct-series-h .ct-slice-donut{stroke:#6b0392}.ct-series-h .ct-area,.ct-series-h .ct-slice-donut-solid,.ct-series-h .ct-slice-pie{fill:#6b0392}.ct-series-i .ct-bar,.ct-series-i .ct-line,.ct-series-i .ct-point,.ct-series-i .ct-slice-donut{stroke:#f05b4f}.ct-series-i .ct-area,.ct-series-i .ct-slice-donut-solid,.ct-series-i .ct-slice-pie{fill:#f05b4f}.ct-series-j .ct-bar,.ct-series-j .ct-line,.ct-series-j .ct-point,.ct-series-j .ct-slice-donut{stroke:#dda458}.ct-series-j .ct-area,.ct-series-j .ct-slice-donut-solid,.ct-series-j .ct-slice-pie{fill:#dda458}.ct-series-k .ct-bar,.ct-series-k .ct-line,.ct-series-k .ct-point,.ct-series-k .ct-slice-donut{stroke:#eacf7d}.ct-series-k .ct-area,.ct-series-k .ct-slice-donut-solid,.ct-series-k .ct-slice-pie{fill:#eacf7d}.ct-series-l .ct-bar,.ct-series-l .ct-line,.ct-series-l .ct-point,.ct-series-l .ct-slice-donut{stroke:#86797d}.ct-series-l .ct-area,.ct-series-l .ct-slice-donut-solid,.ct-series-l .ct-slice-pie{fill:#86797d}.ct-series-m .ct-bar,.ct-series-m .ct-line,.ct-series-m .ct-point,.ct-series-m .ct-slice-donut{stroke:#b2c326}.ct-series-m .ct-area,.ct-series-m .ct-slice-donut-solid,.ct-series-m .ct-slice-pie{fill:#b2c326}.ct-series-n .ct-bar,.ct-series-n .ct-line,.ct-series-n .ct-point,.ct-series-n .ct-slice-donut{stroke:#6188e2}.ct-series-n .ct-area,.ct-series-n .ct-slice-donut-solid,.ct-series-n .ct-slice-pie{fill:#6188e2}.ct-series-o .ct-bar,.ct-series-o .ct-line,.ct-series-o .ct-point,.ct-series-o .ct-slice-donut{stroke:#a748ca}.ct-series-o .ct-area,.ct-series-o .ct-slice-donut-solid,.ct-series-o .ct-slice-pie{fill:#a748ca}.ct-square{display:block;position:relative;width:100%}.ct-square:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:100%}.ct-square:after{display:table}.ct-square>svg{display:block;position:absolute;top:0;left:0}.ct-minor-second{display:block;position:relative;width:100%}.ct-minor-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:93.75%}.ct-minor-second:after{display:table}.ct-minor-second>svg{display:block;position:absolute;top:0;left:0}.ct-major-second{display:block;position:relative;width:100%}.ct-major-second:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:88.8888888889%}.ct-major-second:after{display:table}.ct-major-second>svg{display:block;position:absolute;top:0;left:0}.ct-minor-third{display:block;position:relative;width:100%}.ct-minor-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:83.3333333333%}.ct-minor-third:after{display:table}.ct-minor-third>svg{display:block;position:absolute;top:0;left:0}.ct-major-third{display:block;position:relative;width:100%}.ct-major-third:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:80%}.ct-major-third:after{display:table}.ct-major-third>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fourth{display:block;position:relative;width:100%}.ct-perfect-fourth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:75%}.ct-perfect-fourth:after{display:table}.ct-perfect-fourth>svg{display:block;position:absolute;top:0;left:0}.ct-perfect-fifth{display:block;position:relative;width:100%}.ct-perfect-fifth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:66.6666666667%}.ct-perfect-fifth:after{display:table}.ct-perfect-fifth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-sixth{display:block;position:relative;width:100%}.ct-minor-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:62.5%}.ct-minor-sixth:after{display:table}.ct-minor-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-golden-section{display:block;position:relative;width:100%}.ct-golden-section:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:61.804697157%}.ct-golden-section:after{display:table}.ct-golden-section>svg{display:block;position:absolute;top:0;left:0}.ct-major-sixth{display:block;position:relative;width:100%}.ct-major-sixth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:60%}.ct-major-sixth:after{display:table}.ct-major-sixth>svg{display:block;position:absolute;top:0;left:0}.ct-minor-seventh{display:block;position:relative;width:100%}.ct-minor-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:56.25%}.ct-minor-seventh:after{display:table}.ct-minor-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-seventh{display:block;position:relative;width:100%}.ct-major-seventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:53.3333333333%}.ct-major-seventh:after{display:table}.ct-major-seventh>svg{display:block;position:absolute;top:0;left:0}.ct-octave{display:block;position:relative;width:100%}.ct-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:50%}.ct-octave:after{display:table}.ct-octave>svg{display:block;position:absolute;top:0;left:0}.ct-major-tenth{display:block;position:relative;width:100%}.ct-major-tenth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:40%}.ct-major-tenth:after{display:table}.ct-major-tenth>svg{display:block;position:absolute;top:0;left:0}.ct-major-eleventh{display:block;position:relative;width:100%}.ct-major-eleventh:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:37.5%}.ct-major-eleventh:after{display:table}.ct-major-eleventh>svg{display:block;position:absolute;top:0;left:0}.ct-major-twelfth{display:block;position:relative;width:100%}.ct-major-twelfth:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:33.3333333333%}.ct-major-twelfth:after{display:table}.ct-major-twelfth>svg{display:block;position:absolute;top:0;left:0}.ct-double-octave{display:block;position:relative;width:100%}.ct-double-octave:before{display:block;float:left;content:"";width:0;height:0;padding-bottom:25%}.ct-double-octave:after{display:table}.ct-double-octave>svg{display:block;position:absolute;top:0;left:0}
\ No newline at end of file
-- 
GitLab


From 678a6a2b08dc538e3815f325d4fafdeb5827ce12 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 5 May 2022 18:44:05 +0200
Subject: [PATCH 44/67] re #9570 Commented ApiClient.cs

---
 ld_client/LDClient/network/ApiClient.cs | 107 ++++++++++++++++++++++--
 1 file changed, 100 insertions(+), 7 deletions(-)

diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index b5ca456..8668e54 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -8,36 +8,82 @@ using LDClient.network.data;
 
 namespace LDClient.network {
     
+    /// <summary>
+    /// This class implements IApiClient which is an interface
+    /// defining all the functionality required from an API client.
+    /// </summary>
     public sealed class ApiClient : IApiClient {
         
+        /// <summary>
+        /// Instance of an HTTP client the is used to send data off to the server 
+        /// </summary>
         public IHttpClient _client;
 
+        /// <summary>
+        /// Flag used to stop the client (periodical retrieval from the cache)
+        /// </summary>
         public bool ClientRunning;
 
+        /// <summary>
+        /// Number of milliseconds after which the class tries to resend failed payloads to the server.
+        /// </summary>
         private readonly uint _retryPeriod;
+        
+        /// <summary>
+        /// Maximum number of entries (payloads) that can be sent to the server within one period (_retryPeriod).
+        /// </summary>
         private readonly uint _maxEntries;
+        
+        /// <summary>
+        /// Maximum number of failed payloads to be kept in the file-based cache (FIFO - when the maximum number is reached)
+        /// </summary>
         private readonly uint _maxRetries;
         private readonly IPersistentQueue _cache;
 
+        /// <summary>
+        /// Creates an instance of the class.
+        /// </summary>
+        /// <param name="url">IP address of the server (url in case a DNS server is being used)</param>
+        /// <param name="port">port that the API is running on</param>
+        /// <param name="path">path of the API e.g. /api/v1/lg-logs</param>
+        /// <param name="retryPeriod">number of milliseconds after which the class tries to resend failed payloads to the server</param>
+        /// <param name="maxEntries">maximum number of entries (payloads) that can be sent to the server within one period</param>
+        /// <param name="maxRetries">maximum number of failed payloads to be kept in the file-based cache</param>
+        /// <param name="cache">instance of a persistent cache for storing failed payloads</param>
         public ApiClient(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache) {
+            // Construct the entire path to the API.
             var uri = $"{url}:{port}{path}";
+            
+            // Store the values into class variables.
             _retryPeriod = retryPeriod;
             _maxEntries = maxEntries;
             _maxRetries = maxRetries;
+            _cache = cache;
 
+            // Create an instance of a HttpClient which takes care of
+            // establishing a connection to the server;
             _client = new HttpClient(uri);
-            _cache = cache;
         }
 
+        /// <summary>
+        /// Sends a payload to the server (API).
+        /// </summary>
+        /// <param name="payload">instance of a payload to be sent off to the server</param>
         public async Task SendPayloadAsync(Payload payload) {
             try {
+                // Create an instance of Stopwatch (to measure how much
+                // the action took).
                 Stopwatch stopWatch = new();
-                stopWatch.Start();
                 
+                // Send the payload to the server.
+                stopWatch.Start();
                 var response = await _client.PostAsJsonAsync(payload);
                 stopWatch.Stop();
+                
+                // Create a log message.
                 CreateRequestLog(payload, response, stopWatch.ElapsedMilliseconds);
-
+                
+                // Make sure the request was successful.
                 response.EnsureSuccessStatusCode();
             } catch (Exception e) {
                 Program.DefaultLogger.Error($"Failed to send {payload} to the server. Due to: {e.Message}");
@@ -45,24 +91,43 @@ namespace LDClient.network {
             }
         }
 
+        /// <summary>
+        /// Creates a request log message.
+        /// </summary>
+        /// <param name="payload">payload involved in the process of sending data to the server</param>
+        /// <param name="response">response from the server</param>
+        /// <param name="durationMs">duration in milliseconds (how much time it took to send off the payload)</param>
         private static void CreateRequestLog(Payload payload, HttpResponseMessage response, long durationMs) {
+            // Create the log message.
             var responseToLog = new {
                 statusCode = response.StatusCode,
                 content = response.Content,
                 headers = response.Headers,
                 errorMessage = response.RequestMessage,
             };
-
+            
+            // Log the message using the logger defined in Program (main class).
             Program.DefaultLogger.Info($"Request completed in {durationMs} ms,\n" +
-                                 $"Request body: {payload},\n" +
-                                 $"Response: {responseToLog}");
+                                       $"Request body: {payload},\n" +
+                                       $"Response: {responseToLog}");
         }
         
+        /// <summary>
+        /// Resends unsuccessful payloads to the server.
+        /// </summary>
         private async Task ResendPayloadsAsync() {
+            // Calculate the maximum number of payloads to be sent to the server.
             var numberOfPayloadsToResend = Math.Min(_maxRetries, _cache.EstimatedCountOfItemsInQueue);
+            
+            // Create a list for those payloads
             var payloads = new List<Payload>();
+            
+            // Retrieve the payloads from the cache.
             if (numberOfPayloadsToResend > 0) {
+                // Open up a session to the cache.
                 using var session = _cache.OpenSession();
+                
+                // Pop out payloads, deserialize them, and store them into the list.
                 for (var i = 0; i < numberOfPayloadsToResend; i++) {
                     var rawBytes = session.Dequeue();
                     var payload = JsonSerializer.Deserialize<Payload>(rawBytes);
@@ -70,35 +135,63 @@ namespace LDClient.network {
                         payloads.Add(payload);
                     }
                 }
+                // Flush the changes.
                 session.Flush();
             }
-
+            
+            // If there are some payloads to be resent to the server.
             if (payloads.Count > 0) {
                 Program.DefaultLogger.Debug($"ResendPayloadAsync -> {payloads.Count} unsent payloads");
                 var tasks = new List<Task>();
+                
+                // Create a separate task for each payload - resend them to the server.
                 foreach (var payload in payloads) {
                     Program.DefaultLogger.Info($"Resending {payload}.");
                     tasks.Add(SendPayloadAsync(payload));
                 }
+                // Wait until all tasks are finished. 
                 await Task.WhenAll(tasks);
             }
         }
         
+        /// <summary>
+        /// Stores a failed payload into a persistent cache.
+        /// </summary>
+        /// <param name="payload"></param>
         private void CachePayload(Payload payload) {
             Program.DefaultLogger.Info($"Storing {payload} into the cache.");
+            
+            // Number of payloads stored in the cache.
             var numberOfCachedPayloads = _cache.EstimatedCountOfItemsInQueue;
+            
+            // Open up a session to the cache.
             using var session = _cache.OpenSession();
+            
+            // If the cache is "full", make room for the latest failed
+            // payload by discarding the oldest one.
             if (numberOfCachedPayloads >= _maxEntries) {
                 session.Dequeue();
             }
+            
+            // Store the payload into the cache.
             var payloadJson = JsonSerializer.Serialize(payload);
             session.Enqueue(Encoding.UTF8.GetBytes(payloadJson));
+            
+            // Flush the changes.
             session.Flush();
         }
 
+        /// <summary>
+        /// Runs the periodical retrieval of failed payloads stored
+        /// in a file-based cache. This method is instantiated as a thread.
+        /// </summary>
         public async void Run() {
             Program.DefaultLogger.Info("Api Client thread has started");
+            
+            // Keep the thread running.
             ClientRunning = true;
+            
+            // Keep resending failed payloads to the server.
             while (ClientRunning) {
                 await ResendPayloadsAsync();
                 Thread.Sleep((int) _retryPeriod);
-- 
GitLab


From a155a76350ed6c6804382370a8c7acfab1cf18f1 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 5 May 2022 18:55:11 +0200
Subject: [PATCH 45/67] re #9570 Commented HttpClient.cs, IHttpClient.cs, and
 IApiClient.cs

---
 ld_client/LDClient/network/HttpClient.cs  | 23 ++++++++++++++++++++++-
 ld_client/LDClient/network/IApiClient.cs  | 13 +++++++++++++
 ld_client/LDClient/network/IHttpClient.cs | 10 ++++++++++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/ld_client/LDClient/network/HttpClient.cs b/ld_client/LDClient/network/HttpClient.cs
index fa6f3d1..9672006 100644
--- a/ld_client/LDClient/network/HttpClient.cs
+++ b/ld_client/LDClient/network/HttpClient.cs
@@ -9,18 +9,39 @@ using System.Threading.Tasks;
 using LDClient.network.data;
 
 namespace LDClient.network {
+    
+    /// <summary>
+    /// Implementation of IHttpClient which defines the functionality
+    /// of a HTTP client that is used by the API client to send data to the server. 
+    /// </summary>
     public class HttpClient : IHttpClient{
 
+        /// <summary>
+        /// Instance of System.Net.Http.HttpClient
+        /// </summary>
         private readonly System.Net.Http.HttpClient _httpClient;
 
+        /// <summary>
+        /// URL to which the HTTP client will connect
+        /// </summary>
         private readonly string _uri;
+        
+        /// <summary>
+        /// Creates an instance of the class
+        /// </summary>
+        /// <param name="uri">URL to which the HTTP client will connect</param>
         public HttpClient(string uri) {
-
             _httpClient = new System.Net.Http.HttpClient();
             _uri = uri;
         }
 
+        /// <summary>
+        /// Asynchronically sends data in JSON format to the server.
+        /// </summary>
+        /// <param name="payload">Payload to be sent to the server</param>
+        /// <returns></returns>
         public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload) {
+            // Serialize the payload and send it to the server as JSON.
             return _httpClient.PostAsJsonAsync(_uri, payload, new JsonSerializerOptions {
                 Converters = {
                     new JsonStringEnumConverter( JsonNamingPolicy.CamelCase)
diff --git a/ld_client/LDClient/network/IApiClient.cs b/ld_client/LDClient/network/IApiClient.cs
index 5574d23..79d70e1 100644
--- a/ld_client/LDClient/network/IApiClient.cs
+++ b/ld_client/LDClient/network/IApiClient.cs
@@ -2,9 +2,22 @@
 
 namespace LDClient.network {
     
+    /// <summary>
+    /// This interface defines the functionality of an API client
+    /// which is used to send information (payloads) to the server.
+    /// </summary>
     public interface IApiClient {
         
+        /// <summary>
+        /// Sends a payload to the server (API).
+        /// </summary>
+        /// <param name="payload">instance of a payload to be sent off to the server</param>
         public Task SendPayloadAsync(Payload payload);
+        
+        /// <summary>
+        /// Runs the periodical retrieval of failed payloads stored
+        /// in a file-based cache. This method is instantiated as a thread.
+        /// </summary>
         public void Run();
     }
 }
diff --git a/ld_client/LDClient/network/IHttpClient.cs b/ld_client/LDClient/network/IHttpClient.cs
index daf0c60..0f3fc72 100644
--- a/ld_client/LDClient/network/IHttpClient.cs
+++ b/ld_client/LDClient/network/IHttpClient.cs
@@ -6,8 +6,18 @@ using System.Threading.Tasks;
 using LDClient.network.data;
 
 namespace LDClient.network {
+    
+    /// <summary>
+    /// This interface defines the functionality of a HTTP client
+    /// through which the API client sends data (payloads) to the server.
+    /// </summary>
     public interface IHttpClient {
 
+        /// <summary>
+        /// Asynchronically sends data in JSON format to the server.
+        /// </summary>
+        /// <param name="payload">Payload to be sent to the server</param>
+        /// <returns></returns>
         public Task<HttpResponseMessage> PostAsJsonAsync(Payload payload);
     }
 }
-- 
GitLab


From 625c7c2ed9d2c1b536120b6363bcfb3989414a2d Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 5 May 2022 19:04:07 +0200
Subject: [PATCH 46/67] re #9570 Commented ConnectionStatus.cs,
 DebuggerInfo.cs, and Payload.cs

---
 .../LDClient/network/data/ConnectionStatus.cs | 11 +++++
 .../LDClient/network/data/DebuggerInfo.cs     |  8 ++++
 ld_client/LDClient/network/data/Payload.cs    | 41 +++++++++++++++++--
 3 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/ld_client/LDClient/network/data/ConnectionStatus.cs b/ld_client/LDClient/network/data/ConnectionStatus.cs
index 9cd1ded..96d87ae 100644
--- a/ld_client/LDClient/network/data/ConnectionStatus.cs
+++ b/ld_client/LDClient/network/data/ConnectionStatus.cs
@@ -2,10 +2,21 @@
 
 namespace LDClient.network.data {
     
+    /// <summary>
+    /// This enumeration defines different states in
+    /// which a debugger can be.
+    /// </summary>
     public enum ConnectionStatus {
         
+        /// <summary>
+        /// Debugger is connected
+        /// </summary>
         [EnumMember(Value = "connected")]
         Connected,
+        
+        /// <summary>
+        /// Debugger is disconnected
+        /// </summary>
         [EnumMember(Value = "disconnected")]
         Disconnected
     }
diff --git a/ld_client/LDClient/network/data/DebuggerInfo.cs b/ld_client/LDClient/network/data/DebuggerInfo.cs
index 9402110..fd7fa8a 100644
--- a/ld_client/LDClient/network/data/DebuggerInfo.cs
+++ b/ld_client/LDClient/network/data/DebuggerInfo.cs
@@ -1,8 +1,16 @@
 using System.Text.Json.Serialization;
 
 namespace LDClient.network.data {
+    
+    /// <summary>
+    /// This class holds all the information about
+    /// a specific part of a debugger (head/body).
+    /// </summary>
     public class DebuggerInfo {
         
+        /// <summary>
+        /// Serial number of the part of a debugger.
+        /// </summary>
         [JsonPropertyName("serial_number")]
         public string? SerialNumber { get; set; }
     }
diff --git a/ld_client/LDClient/network/data/Payload.cs b/ld_client/LDClient/network/data/Payload.cs
index ae7302a..afa714f 100644
--- a/ld_client/LDClient/network/data/Payload.cs
+++ b/ld_client/LDClient/network/data/Payload.cs
@@ -5,44 +5,77 @@ using JsonSerializer = System.Text.Json.JsonSerializer;
 
 namespace LDClient.network.data {
     
+    /// <summary>
+    /// This class represents a single payload that is sent to the server.
+    /// </summary>
     [JsonObject(MemberSerialization.OptIn)]
     public class Payload {
 
+        /// <summary>
+        /// Username of the currently logged user.
+        /// </summary>
         [JsonPropertyName("username")]
         public string? UserName { get; set; }
 
+        /// <summary>
+        /// Hostname of the pc.
+        /// </summary>
         [JsonPropertyName("hostname")]
         public string? HostName { get; set; }
 
+        /// <summary>
+        /// Timestamp (when a debugger was plugged/unplugged).
+        /// </summary>
         [JsonPropertyName("timestamp")]
         public string? TimeStamp { get; set; }
 
+        /// <summary>
+        /// Information about the head of the debugger.
+        /// </summary>
         [JsonPropertyName("head_device")]
         public DebuggerInfo? HeadDevice { get; set; }
 
-
+        /// <summary>
+        /// Information about the body of the debugger.
+        /// </summary>
         [JsonPropertyName("body_device")]
         public DebuggerInfo?  BodyDevice { get; set; }
         
+        /// <summary>
+        /// Status of the debugger (connected/disconnected).
+        /// </summary>
         [JsonPropertyName("status")]
         public ConnectionStatus Status { get; set; }
-
-
+        
+        /// <summary>
+        /// Returns a string representation of the payload.
+        /// </summary>
+        /// <returns></returns>
         public override string ToString() {
             return ParseToJson(this);
         }
 
+        /// <summary>
+        /// Parses (converts) the payload into JSON format.
+        /// </summary>
+        /// <returns></returns>
         public string ParseToJson() {
             return Payload.ParseToJson(this);
         }
 
+        /// <summary>
+        /// Serializes a given payload into JSON format.
+        /// </summary>
+        /// <param name="payload">payload to be serialized into JSON</param>
+        /// <returns></returns>
         public static string ParseToJson(Payload payload) {
+            // Create options for serialization.
             var options = new JsonSerializerOptions {
                 Converters = {
                     new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
                 }
             };
-
+            // Serialize the payload and return it.
             return JsonSerializer.Serialize(payload, options);
         }
     }
-- 
GitLab


From 9657d7e0e156d39c8deea6a2b318e894689255c5 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 5 May 2022 20:57:48 +0200
Subject: [PATCH 47/67] re #9570 Commented ConfigLoader.cs, FileUtils.cs, and
 IFileUtils.cs

---
 ld_client/LDClient/utils/ConfigLoader.cs | 139 +++++++++++++++++++++++
 ld_client/LDClient/utils/FileUtils.cs    |  11 ++
 ld_client/LDClient/utils/IFileUtils.cs   |   9 ++
 3 files changed, 159 insertions(+)

diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 251e663..6dc3cf7 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -3,69 +3,196 @@ using Microsoft.Extensions.Configuration;
 
 namespace LDClient.utils {
     
+    /// <summary>
+    /// This class loads up the configuration file (appsettingss.json).
+    /// </summary>
     internal class ConfigLoader {
 
+        /// <summary>
+        /// Status code indicating a successful termination of an application.
+        /// </summary>
         private const int ErrorExitCode = 1;
+        
+        /// <summary>
+        /// Path to the configuration file.
+        /// </summary>
         private const string ConfigFile = "appsettings.json";
+        
+        /// <summary>
+        /// Name of the logging section defined in the config file.
+        /// </summary>
         private const string LoggingSection = "Logging";
+        
+        /// <summary>
+        /// Name of the network section defined in the config file.
+        /// </summary>
         private const string NetworkSection = "Network";
+        
+        /// <summary>
+        /// Name of the cache section defined in the config file.
+        /// </summary>
         private const string CacheSection = "Cache";
+        
+        /// <summary>
+        /// Name of the detection section defined in the config file.
+        /// </summary>
         private const string DdSection = "DebuggerDetection";
 
         #region Logger
         
+        /// <summary>
+        /// Maximum size of the log file (it will start to rotate when this limit is reached).
+        /// </summary>
         public int LogChunkSize { get; private set; }
+        
+        /// <summary>
+        /// Number of files to be created until there will be zipped up.
+        /// </summary>
         public int LogChunkMaxCount { get; private set; }
+        
+        /// <summary>
+        /// Maximum number of zip files
+        /// </summary>
         public int LogArchiveMaxCount { get; private set; }
+        
+        /// <summary>
+        /// Time after which the last logs will be cleaned up.
+        /// </summary>
         public int LogCleanupPeriod { get; private set; }
+        
+        /// <summary>
+        /// Level of verbosity.
+        /// </summary>
         public LogVerbosity LogVerbosityType { get; private set; } = LogVerbosity.Full;
+        
+        /// <summary>
+        /// Logger flow type.
+        /// </summary>
         public LogFlow LogFlowType { get; private set; } = LogFlow.Console;
         
         #endregion
 
         #region Api
         
+        /// <summary>
+        /// URL to the API (it can be an IP address or a domain name if a DNS server is being used).
+        /// </summary>
         public string ApiBaseAddress { get; private set; } = null!;
+        
+        /// <summary>
+        /// Path to the API (e.g. /api/v1/ld-logs).
+        /// </summary>
         public string ApiUsbEndPoint { get; private set; } = null!;
+        
+        /// <summary>
+        /// Number of the port that the API runs on.
+        /// </summary>
         public uint ApiPort { get; private set; }
 
         #endregion
 
         #region Cache
         
+        /// <summary>
+        /// Name of the cache (a directory of this name will be created).
+        /// </summary>
         public string CacheFileName { get; private set; } = null!;
+        
+        /// <summary>
+        /// Maximum number of payloads (entries) to be sent to the server at a time.
+        /// </summary>
         public uint MaxRetries { get; private set; }
+        
+        /// <summary>
+        /// Maximum number of entries that can be stored in the database.
+        /// </summary>
         public uint MaxEntries { get; private set; }
+        
+        /// <summary>
+        /// Period (how often) a certain number of entries will be resent to the server.
+        /// </summary>
         public uint RetryPeriod { get; private set; }
         
         #endregion
 
         #region Detection
+        
+        /// <summary>
+        /// Name of the process to be detected (the application programmers use to connect to the debugger).
+        /// </summary>
         public string T32ProcessName { get; private set; } = null!;
+        
+        /// <summary>
+        /// How often the application checks if there is the process (T32ProcessName) running on the PC.
+        /// </summary>
         public uint DetectionPeriod { get; private set; }
+        
+        /// <summary>
+        /// Location of the generated .txt file containing all information about a debugger.
+        /// </summary>
         public string T32InfoLocation { get; private set; } = null!;
+        
+        /// <summary>
+        /// Path to the t32rem.exe which is used to send commands to a debugger.
+        /// </summary>
         public string F32RemExecutable { get; private set; } = null!;
+        
+        /// <summary>
+        /// How many times the application attempts to check if there
+        /// has been a .txt file generated containing all the desired information.
+        /// </summary>
         public uint FetchInfoMaxAttempts { get; private set;  }
+        
+        /// <summary>
+        /// Period in milliseconds after which the application tries to locate and parse the .txt file. 
+        /// </summary>
         public uint FetchInfoAttemptPeriod { get; private set; }
+        
+        /// <summary>
+        /// Arguments (commands) sent to the t32rem.exe file.
+        /// </summary>
         public string[] F32RemArguments { get; private set; } = null!;
+        
+        /// <summary>
+        /// Status code indication successful execution of the t32rem.exe file.
+        /// </summary>
         public int T32RemSuccessExitCode { get; private set; }
+        
+        /// <summary>
+        /// Timeout of the execution of t32rem.exe (when sending one command).
+        /// </summary>
         public int T32RemWaitTimeoutMs { get; private set; }
 
         #endregion
 
+        /// <summary>
+        /// Creates an instance of the class.
+        /// </summary>
         public ConfigLoader() {
+            // Create a new config builder to read the configuration file.
             var configuration = new ConfigurationBuilder()
                 .AddJsonFile(ConfigFile)
                 .Build();
 
+            // Parse the logger section.
             ReadLoggerSection(configuration);
+            
+            // Parse the api section. 
             ReadApiSection(configuration);
+            
+            // Parse the cache section.
             ReadCacheSection(configuration);
+            
+            // Parse the detection section.
             ReadDebuggerSection(configuration);
             
             Console.WriteLine("Configuration successfully loaded!");
         }
 
+        /// <summary>
+        /// Parses the logging section of the configuration file.
+        /// </summary>
+        /// <param name="configuration">configuration</param>
         private void ReadLoggerSection(IConfiguration configuration) {
             try {
                 var logging = configuration.GetSection(LoggingSection);
@@ -81,6 +208,10 @@ namespace LDClient.utils {
             }
         }
 
+        /// <summary>
+        /// Parses the api section of the configuration file.
+        /// </summary>
+        /// <param name="configuration">configuration</param>
         private void ReadApiSection(IConfiguration configuration) {
             try {
                 var network = configuration.GetSection(NetworkSection);
@@ -93,6 +224,10 @@ namespace LDClient.utils {
             }
         }
 
+        /// <summary>
+        /// Parses the cache section of the configuration file.
+        /// </summary>
+        /// <param name="configuration">configuration</param>
         private void ReadCacheSection(IConfiguration configuration) {
             try {
                 var cache = configuration.GetSection(CacheSection);
@@ -106,6 +241,10 @@ namespace LDClient.utils {
             }
         }
 
+        /// <summary>
+        /// Parses the detection section of the configuration file.
+        /// </summary>
+        /// <param name="configuration">configuration</param>
         private void ReadDebuggerSection(IConfiguration configuration) {
             try {
                 var debugger = configuration.GetSection(DdSection);
diff --git a/ld_client/LDClient/utils/FileUtils.cs b/ld_client/LDClient/utils/FileUtils.cs
index abd3e98..b749389 100644
--- a/ld_client/LDClient/utils/FileUtils.cs
+++ b/ld_client/LDClient/utils/FileUtils.cs
@@ -5,7 +5,18 @@ using System.Text;
 using System.Threading.Tasks;
 
 namespace LDClient.utils {
+    
+    /// <summary>
+    /// This class implements the IFileUtils interface
+    /// which defines IO operations.
+    /// </summary>
     public class FileUtils : IFileUtils {
+        
+        /// <summary>
+        /// Reads all lines of a files and returns them as a array.
+        /// </summary>
+        /// <param name="file">path to the file</param>
+        /// <returns>all the lines of the file (as an array)</returns>
         public string[] ReadFileAllLines(string file) {
             return File.ReadAllLines(file);
         }
diff --git a/ld_client/LDClient/utils/IFileUtils.cs b/ld_client/LDClient/utils/IFileUtils.cs
index f3daf17..cc1547f 100644
--- a/ld_client/LDClient/utils/IFileUtils.cs
+++ b/ld_client/LDClient/utils/IFileUtils.cs
@@ -5,8 +5,17 @@ using System.Text;
 using System.Threading.Tasks;
 
 namespace LDClient.utils {
+    
+    /// <summary>
+    /// This interface defines IO operations.
+    /// </summary>
     public interface IFileUtils {
 
+        /// <summary>
+        /// Reads all lines of a files and returns them as a array.
+        /// </summary>
+        /// <param name="file">path to the file</param>
+        /// <returns>all the lines of the file (as an array)</returns>
         public string[] ReadFileAllLines(string file);
     }
 }
-- 
GitLab


From 31b6e8b723d1e34724104be7978ca00452d89207 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Thu, 5 May 2022 21:06:17 +0200
Subject: [PATCH 48/67] re #9570 Commented Program.cs

---
 ld_client/LDClient/Program.cs | 36 +++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index d8a7cb4..98a61b2 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -9,14 +9,34 @@ using static System.Reflection.Assembly;
 
 namespace LDClient;
 
+/// <summary>
+/// This class represents the main class of the application.
+/// </summary>
 internal static class Program {
 
+    /// <summary>
+    /// Sleep period of the main thread of the application.
+    /// </summary>
     private const int MainLoopDelayMs = 30000; 
 
+    /// <summary>
+    /// Instance of a config loader.
+    /// </summary>
     public static ConfigLoader Config { get; } = new();
+    
+    /// <summary>
+    /// Default logger used throughout the application.
+    /// </summary>
     public static ALogger DefaultLogger { get; } = ALogger.Current;
+    
+    /// <summary>
+    /// Instance of an API client.
+    /// </summary>
     private static IApiClient? DefaultApiClient { get; set; }
     
+    /// <summary>
+    /// Instance of an info fetcher.
+    /// </summary>
     private static readonly InfoFetcher InfoFetcher = new(
         Config.FetchInfoMaxAttempts,
         Config.FetchInfoAttemptPeriod,
@@ -27,12 +47,19 @@ internal static class Program {
         Config.T32RemWaitTimeoutMs
     );
     
+    /// <summary>
+    /// The main entry pint of the application.
+    /// </summary>
+    /// <returns>1 if something goes wrong, 0 otherwise.</returns>
     public static int Main() {
+        // Make sure that there is only one running instance of this application.
         if (GetProcessesByName(Path.GetFileNameWithoutExtension(GetEntryAssembly()?.Location)).Length > 1) {
             DefaultLogger.Error("Another instance of the application is already running");
             return 1;
         }
         
+        // Create an instance of an API client with all
+        // the appropriate parameters defined in the config file.
         DefaultApiClient = new ApiClient(
             Config.ApiBaseAddress,
             Config.ApiPort, 
@@ -42,6 +69,7 @@ internal static class Program {
             new PersistentQueue(Config.CacheFileName)
         );
         
+        // Create a new process detector.
         IProcessDetection processProcessDetection = new ProcessDetection(
             Config.T32ProcessName,
             Config.DetectionPeriod,
@@ -50,18 +78,26 @@ internal static class Program {
             new ProcessUtils()
         );
         
+        // Create and start a new thread that periodically
+        // resends filed payloads to the server.
         var apiClientThread = new Thread(DefaultApiClient.Run) {
             IsBackground = true
         };
         apiClientThread.Start();
 
+        // Create and start a new thread that periodically checks
+        // if the desired process is currently running or not.
         var processThread = new Thread(processProcessDetection.RunPeriodicDetection) {
             IsBackground = true
         };
         processThread.Start();
 
+        // The main thread does "nothing"
         while (true) {
             Thread.Sleep(MainLoopDelayMs);
         }
+
+        // The execution of the program should never reach this point.
+        return 0;
     }
 }
\ No newline at end of file
-- 
GitLab


From f63d5489ac5cb2fdeb659c4b7ef46667efdf40f5 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Fri, 6 May 2022 08:59:03 +0200
Subject: [PATCH 49/67] re #9570 Commented DebuggerInfoParser.cs,
 IInfoFetcher.cs, and InfoFetcher.cs

---
 .../LDClient/detection/DebuggerInfoParser.cs  |  20 ++++
 ld_client/LDClient/detection/IInfoFetcher.cs  |  18 +++
 ld_client/LDClient/detection/InfoFetcher.cs   | 106 +++++++++++++++++-
 3 files changed, 141 insertions(+), 3 deletions(-)

diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs
index dec8bd0..27b80c6 100644
--- a/ld_client/LDClient/detection/DebuggerInfoParser.cs
+++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs
@@ -2,19 +2,39 @@ using System.Text.RegularExpressions;
 
 namespace LDClient.detection {
 
+    /// <summary>
+    /// This class parses the .txt file generated from the debugger.
+    /// Its primary interest is to find two serial numbers (head + body). 
+    /// </summary>
     public static class DebuggerInfoParser {
 
+        /// <summary>
+        /// Number of serial numbers expected to be in the .txt file (number of matches - regex).
+        /// </summary>
         private const int ExpectedNumberOfMatches = 2;
         
+        /// <summary>
+        /// Regular expression used to find the serial numbers.
+        /// </summary>
         private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)");
         
+        /// <summary>
+        /// Takes the content of a .txt file and tries to find the two serial numbers (head and body).
+        /// If it succeed, it will return the two numbers.
+        /// </summary>
+        /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param>
+        /// <returns>two serial numbers (head and body) of the debugger</returns>
+        /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception>
         public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) {
+            // Find all matches in the content of the file that satisfy the regular expression.
             var matches = SerialNumberRegex.Matches(dataTxt);
 
+            // Make sure an exact number of matches has been found.
             if (matches.Count != ExpectedNumberOfMatches) {
                 throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})");
             }
             
+            // Return the two serial numbers (head and body).
             return (matches[1].ToString().Trim(), matches[0].ToString().Trim());
         }
     }
diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs
index e48005c..f8c47a3 100644
--- a/ld_client/LDClient/detection/IInfoFetcher.cs
+++ b/ld_client/LDClient/detection/IInfoFetcher.cs
@@ -5,11 +5,29 @@ using System.Text;
 using System.Threading.Tasks;
 
 namespace LDClient.detection {
+    
+    /// <summary>
+    /// This interface defines the functionality of an info fetcher which
+    /// takes care of sending commands to the debugger. 
+    /// </summary>
     public interface IInfoFetcher {
 
+        /// <summary>
+        /// Returns the head serial number of the debugger.
+        /// </summary>
         public string HeadSerialNumber { get; set; }
+        
+        /// <summary>
+        /// Returns the body serial number of the debugger.
+        /// </summary>
         public string BodySerialNumber { get; set; }
 
+        /// <summary>
+        /// Fetches data from the debugger. It sends the commands defined
+        /// in the appsettings.json file to the debugger and tries to
+        /// parse the .txt (contains the serial numbers).
+        /// </summary>
+        /// <returns>True, if data was fetched successfully. False otherwise.</returns>
         public Task<bool> FetchDataAsync();
     }
 }
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
index 07ddba1..7854ea6 100644
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ b/ld_client/LDClient/detection/InfoFetcher.cs
@@ -4,27 +4,88 @@ using LDClient.utils.loggers;
 
 namespace LDClient.detection {
 
+    /// <summary>
+    /// This class implements the IInfoFetcher interface
+    /// which defines the functionality of an info fetcher.
+    /// </summary>
     public class InfoFetcher : IInfoFetcher {
         
+        /// <summary>
+        /// Default value of a serial number (undefined).
+        /// </summary>
         private const string UndefinedSerialNumber = "number";
 
+        /// <summary>
+        /// Path to the t32rem.exe file which is used to send commands to the debugger.
+        /// </summary>
         private readonly string _f32RemExecutable;
+        
+        /// <summary>
+        /// Arguments (commands) sent to the debugger in order to generate a .txt file
+        /// containing all the desired information.
+        /// </summary>
         private readonly string[] _f32RemArguments;
+        
+        /// <summary>
+        /// Status code indicating a successful termination of t32rem.exe
+        /// </summary>
         private readonly int _f32SuccessExitCode;
+        
+        /// <summary>
+        /// Timeout used when waiting for the t32rem.exe to finish.
+        /// </summary>
         private readonly int _f32WaitTimeoutMs;
+        
+        /// <summary>
+        /// Maximum number of attempts to locate and parse the .txt file.
+        /// </summary>
         private readonly uint _maxAttempts;
+        
+        /// <summary>
+        /// Period (how often) the application tries to locate and parse the .txt file.
+        /// </summary>
         private readonly uint _waitPeriodMs;
+        
+        /// <summary>
+        /// Path to the .txt file which is generated from the debugger.
+        /// </summary>
         private readonly string _infoFilePath;
 
+        /// <summary>
+        /// Instance of ProcessUtils which encapsulates common functionality
+        /// when it comes to dealing with processes (limited by the needs of this application).
+        /// </summary>
         public IProcessUtils ProcessUtils;
+        
+        /// <summary>
+        /// Instance of FileUtils which encapsulates common functionality
+        /// when it comes to dealing with files (limited by the needs of this application).
+        /// </summary>
         public IFileUtils FileUtils;
 
+        /// <summary>
+        /// Returns the head serial number of the debugger.
+        /// </summary>
         public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;
+        
+        /// <summary>
+        /// Returns the body serial number of the debugger.
+        /// </summary>
         public string BodySerialNumber { get; set; } = UndefinedSerialNumber;
-
-
+        
+        /// <summary>
+        /// Creates an instance of this class.
+        /// </summary>
+        /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
+        /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
+        /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
+        /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param>
+        /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param>
+        /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param>
+        /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param>
         public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
             string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {
+            // Store the parameters into the class variables.
             _maxAttempts = maxAttempts;
             _waitPeriodMs = waitPeriodMs;
             _infoFilePath = infoFilePath;
@@ -32,36 +93,66 @@ namespace LDClient.detection {
             _f32RemArguments = f32RemArguments;
             _f32SuccessExitCode = f32SuccessExitCode;
             _f32WaitTimeoutMs = f32WaitTimeoutMs;
+            
+            // Create an instance of ProcessUtils.
             ProcessUtils = new ProcessUtils();
+            
+            // Create an instance of FileUtils.
             FileUtils = new FileUtils();
-
         }
 
+        /// <summary>
+        /// Fetches data from the debugger. It sends the commands defined
+        /// in the appsettings.json file to the debugger and tries to
+        /// parse the .txt (contains the serial numbers).
+        /// </summary>
+        /// <returns>True, if data was fetched successfully. False otherwise.</returns>
         public async Task<bool> FetchDataAsync() {
             Program.DefaultLogger.Info("Fetching data from the debugger.");
+            
+            // Send the commands to the debugger.
             var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs);
+            
+            // Make sure that all commands were sent and executed successfully.
             if (!success) {
                 Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
                 return false;
             }
+            
+            // Periodically try to parse the .txt file. 
             for (var i = 0; i < _maxAttempts; i++) {
                 Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");
+                
+                // Try to parse .txt file.
                 if (RetrieveDebuggerInfo(_infoFilePath)) {
                     Program.DefaultLogger.Info($"Info file has been parsed successfully.");
                     return true;
                 }
+                // Wait for a specified number of milliseconds.
                 await Task.Delay((int)_waitPeriodMs);
             }
             Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
             return false;
         }
 
+        /// <summary>
+        /// Tries to retrieve information from the debugger.
+        /// </summary>
+        /// <param name="filePath">path to the .txt file that contains all information</param>
+        /// <returns>True if the information was retrieved successfully. False, otherwise.</returns>
         private bool RetrieveDebuggerInfo(string filePath) {
             try {
+                // Read the content of the .txt file.
                 var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
+                
+                // Parse it (try to find the serial numbers)
                 var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
+                
+                // Store the serial numbers into class variables (properties)
                 HeadSerialNumber = headSerialNumber;
                 BodySerialNumber = bodySerialNumber;
+                
+                // Finally, delete the file.
                 File.Delete(filePath);
             } catch (Exception exception) {
                 Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
@@ -70,11 +161,20 @@ namespace LDClient.detection {
             return true;
         }
 
+        /// <summary>
+        /// Sends commands to the debugger.
+        /// </summary>
+        /// <param name="executableFile">Path to the t32rem.exe file</param>
+        /// <param name="arguments">Arguments sent to the debugger through t32rem.exe (one argument is one command)</param>
+        /// <param name="desiredExitCode">Status code indicating successful termination of t32rem.exe</param>
+        /// <param name="waitTimeoutMs">Timeout used when waiting for t32rem.exe to finish</param>
+        /// <returns>True if all the commands were executed successfully. False, otherwise.</returns>
         private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) {
             if (arguments == null) {
                 Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given");
                 return false;
             }
+            // Execute one all arguments (commands) one by one.
             foreach (var argument in arguments) {
                 if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) {
                     return false;
-- 
GitLab


From 12899c8b237991309a93f0d2efd441d178183a60 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Fri, 6 May 2022 09:56:15 +0200
Subject: [PATCH 50/67] re #9570 - Commented IProcessDetection.cs,
 IProcessUtils.cs, ProcessDetection.cs, and ProcessUtils.cs

---
 .../LDClient/detection/IProcessDetection.cs   |   9 ++
 ld_client/LDClient/detection/IProcessUtils.cs |  20 +++
 .../LDClient/detection/ProcessDetection.cs    | 114 ++++++++++++++++--
 ld_client/LDClient/detection/ProcessUtils.cs  |  32 ++++-
 4 files changed, 159 insertions(+), 16 deletions(-)

diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs
index 26782e1..27383f5 100644
--- a/ld_client/LDClient/detection/IProcessDetection.cs
+++ b/ld_client/LDClient/detection/IProcessDetection.cs
@@ -1,7 +1,16 @@
 namespace LDClient.detection {
     
+    /// <summary>
+    /// This interface defines the functionality of a process detector.
+    /// A process detector is used to determine whether a user is currently
+    /// using a debugger or not.
+    /// </summary>
     internal interface IProcessDetection {
         
+        /// <summary>
+        /// Periodically runs process detection. This method is instantiated
+        /// as a thread from the main class (Program.cs).
+        /// </summary>
         public void RunPeriodicDetection();
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs
index b900375..d55a663 100644
--- a/ld_client/LDClient/detection/IProcessUtils.cs
+++ b/ld_client/LDClient/detection/IProcessUtils.cs
@@ -5,9 +5,29 @@ using System.Text;
 using System.Threading.Tasks;
 
 namespace LDClient.detection {
+    
+    /// <summary>
+    /// This interface defines the functionality of all methods that
+    /// are used to work with processes (within this project).
+    /// </summary>
     public interface IProcessUtils {
+        
+        /// <summary>
+        /// Checks if a process is running or not.
+        /// </summary>
+        /// <param name="name">Name of the process</param>
+        /// <returns>True, if the process is running. False otherwise.</returns>
         public bool IsProcessRunning(string name);
 
+        /// <summary>
+        /// Executes a new process (t32rem.exe) with arguments which are passed in
+        /// as a parameter of the method.
+        /// </summary>
+        /// <param name="fileName">Path to the .exe file</param>
+        /// <param name="argument">Arguments passed into the .exe file</param>
+        /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
+        /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
+        /// <returns>True, if the command was executed successfully. False otherwise.</returns>
         public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode);
     }
 }
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
index 27d5333..4bde0fd 100644
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -3,24 +3,76 @@ using LDClient.network;
 using LDClient.network.data;
 
 namespace LDClient.detection {
-   
-	 public sealed class ProcessDetection : IProcessDetection {
-        
+
+    /// <summary>
+    /// This class takes care of process detection. When t32mtc (process)
+    /// is detected, it means that the debugger is currently being used.
+    /// The class keeps track of the current state of a debugger.
+    /// </summary>
+    public sealed class ProcessDetection : IProcessDetection {
+
+        /// <summary>
+        /// Datetime format used when sending payloads to the server.
+        /// </summary>
         private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
 
+        /// <summary>
+        /// Name of the process the application detects.
+        /// </summary>
         private readonly string _processName;
+        
+        /// <summary>
+        /// How often the application check the current status of the process (cunning / not running).
+        /// </summary>
         private readonly uint _detectionPeriodMs;
+        
+        /// <summary>
+        /// Instance of InfoFetcher used to fetch information from the debugger
+        /// (when the process is detected).
+        /// </summary>
         private readonly IInfoFetcher _infoFetcher;
+        
+        /// <summary>
+        /// Instance of API clients used for sending data off to the server.
+        /// </summary>
         private readonly IApiClient _apiClient;
+        
+        /// <summary>
+        /// Instance of ProcessUtils which encapsulates common functionality
+        /// when it comes to dealing with processes (limited by the needs of this application).
+        /// </summary>
         private readonly IProcessUtils _processUtils;
 
+        /// <summary>
+        /// Flag indicating whether the process is currently running or not.
+        /// </summary>
         private bool _processIsActive;
+        
+        /// <summary>
+        /// Flag if the application failed to retrieve data when the process was detected.
+        /// </summary>
         private bool _failedToRetrieveData;
+        
+        /// <summary>
+        /// Last payload that was sent to the server.
+        /// </summary>
         private Payload? _lastConnectedPayload;
 
+        /// <summary>
+        /// Flag used to stop the thread (process detection).
+        /// </summary>
         public bool DetectionRunning = false;
-
-        public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils) {
+        
+        /// <summary>
+        /// Creates an instance of this class.
+        /// </summary>
+        /// <param name="processName">Name of the process the application detects</param>
+        /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param>
+        /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param>
+        /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
+        /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
+        public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
+            IApiClient apiClient, IProcessUtils processUtils) {
             _processName = processName;
             _detectionPeriodMs = detectionPeriodMs;
             _infoFetcher = infoFetcher;
@@ -29,40 +81,75 @@ namespace LDClient.detection {
             _processUtils = processUtils;
         }
 
+        /// <summary>
+        /// Retrieves data from the debugger.
+        /// </summary>
+        /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
         private async Task<bool> RetrieveDataFromDebugger() {
+            // Try to fetch data from the debugger.
             var success = await _infoFetcher.FetchDataAsync();
+            
+            // If the data was fetched successfully, send a payload off to the server.
             if (success) {
-                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber, _infoFetcher.BodySerialNumber, DatetimeFormat);
+                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
+                    _infoFetcher.BodySerialNumber, DatetimeFormat);
             }
             return success;
         }
 
+        /// <summary>
+        /// Sends a payload to the server when a debugger gets disconnected.
+        /// </summary>
         private async Task DebuggerDisconnected() {
+            // Make sure the debugger was connected in the first place.
             if (_lastConnectedPayload is not null) {
+                // Update the status and timestamp of the last payload
+                // (the serial numbers remain the same).
                 _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
                 _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
+                
+                // Send the data to the server.
                 await _apiClient.SendPayloadAsync(_lastConnectedPayload);
+                
+                // Clear the last payload.
                 _lastConnectedPayload = null;
             }
         }
 
+        /// <summary>
+        /// Checks if the t32mtc process is running or not. 
+        /// </summary>
         private async Task DetectProcessAsync() {
+            // Check if the process is running.
             var processExists = _processUtils.IsProcessRunning(_processName);
 
+            // Check if the process was not running but now it is (flip flop ON). 
             if (processExists && !_processIsActive) {
                 Program.DefaultLogger.Info($"Process started: {_processName}");
                 if (!_failedToRetrieveData) {
                     _failedToRetrieveData = !await RetrieveDataFromDebugger();
                 }
-            } else if (!processExists && _processIsActive) {
+            }
+            // Check if the process was running but now it is not (fli flop OFF).
+            else if (!processExists && _processIsActive) {
                 Program.DefaultLogger.Info($"Process stopped: {_processName}");
                 _failedToRetrieveData = false;
                 await DebuggerDisconnected();
             }
+
+            // Keep track of the current state of the debugger.
             _processIsActive = processExists;
         }
-        
+
+        /// <summary>
+        /// Creates a payload and sends it to the server.
+        /// </summary>
+        /// <param name="headSerialNumber">serial number of the head of the debugger</param>
+        /// <param name="bodySerialNumber">serial number of the body of the debugger</param>
+        /// <param name="datetimeFormat">datetime format (timestamp)</param>
+        /// <returns>the newly-created payload</returns>
         private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
+            // Create a new payload. 
             Payload payload = new() {
                 UserName = Environment.UserName,
                 HostName = Environment.MachineName,
@@ -75,16 +162,23 @@ namespace LDClient.detection {
                 },
                 Status = ConnectionStatus.Connected
             };
+            
+            // Send it to the server and return it.
             await _apiClient.SendPayloadAsync(payload);
             return payload;
         }
-        
+
+        /// <summary>
+        /// Periodically runs process detection. This method is instantiated
+        /// as a thread from the main class (Program.cs).
+        /// </summary>
         public async void RunPeriodicDetection() {
             Program.DefaultLogger.Info("Process periodic detector has started");
             DetectionRunning = true;
+            
             while (DetectionRunning) {
                 await DetectProcessAsync();
-                Thread.Sleep((int)_detectionPeriodMs);
+                Thread.Sleep((int) _detectionPeriodMs);
             }
         }
     }
diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs
index b707f66..5c448e7 100644
--- a/ld_client/LDClient/detection/ProcessUtils.cs
+++ b/ld_client/LDClient/detection/ProcessUtils.cs
@@ -6,24 +6,46 @@ using System.Text;
 using System.Threading.Tasks;
 
 namespace LDClient.detection {
-    public class ProcessUtils : IProcessUtils{
+    
+    /// <summary>
+    /// This class implements the IProcessUtils interface.
+    /// It implements methods that are used when dealing with processes.
+    /// </summary>
+    public class ProcessUtils : IProcessUtils {
 
+        /// <summary>
+        /// Checks if a process is running or not.
+        /// </summary>
+        /// <param name="name">Name of the process</param>
+        /// <returns>True, if the process is running. False otherwise.</returns>
         public bool IsProcessRunning(string name) {
             return Process.GetProcessesByName(name).Length > 0;
         }
-
-
+        
+        /// <summary>
+        /// Executes a new process (t32rem.exe) with arguments which are passed in
+        /// as a parameter of the method.
+        /// </summary>
+        /// <param name="fileName">Path to the .exe file</param>
+        /// <param name="argument">Arguments passed into the .exe file</param>
+        /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
+        /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
+        /// <returns>True, if the command was executed successfully. False otherwise.</returns>
         public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) {
-
+            // Create a new process.
             var t32RemProcess = new Process();
             t32RemProcess.StartInfo.FileName = fileName;
             t32RemProcess.StartInfo.Arguments = argument;
+            
             try {
+                // Execute the process and wait until it terminates or until the timeout is up.
                 t32RemProcess.Start();
                 if (!t32RemProcess.WaitForExit(timeout)) {
                     Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms");
                     return false;
                 }
+                
+                // Check if the process terminated successfully.
                 if (t32RemProcess.ExitCode != desiredExitCode) {
                     Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
                     return false;
@@ -32,9 +54,7 @@ namespace LDClient.detection {
                 Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}");
                 return false;
             }
-
             return true;
         }
-
     }
 }
-- 
GitLab


From d7aeccbac4b7bdcc86ca85c555107e8f4fcda80e Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 7 May 2022 23:30:02 +0200
Subject: [PATCH 51/67] re #9570 Added code documentation to logger classes and
 properties

---
 ld_client/LDClient/utils/loggers/ALogger.cs   | 88 ++++++++++++++++++-
 .../LDClient/utils/loggers/ConsoleLogger.cs   |  4 +
 .../LDClient/utils/loggers/FileLogger.cs      | 41 ++++++++-
 ld_client/LDClient/utils/loggers/LogFlow.cs   |  9 ++
 ld_client/LDClient/utils/loggers/LogType.cs   |  3 +
 .../LDClient/utils/loggers/LogVerbosity.cs    |  4 +
 6 files changed, 145 insertions(+), 4 deletions(-)

diff --git a/ld_client/LDClient/utils/loggers/ALogger.cs b/ld_client/LDClient/utils/loggers/ALogger.cs
index 260a03d..c89f161 100644
--- a/ld_client/LDClient/utils/loggers/ALogger.cs
+++ b/ld_client/LDClient/utils/loggers/ALogger.cs
@@ -2,17 +2,49 @@
 
 namespace LDClient.utils.loggers {
 
+    /// <summary>
+    /// This class implements all abstract functions of the logger.
+    /// It contains all functions (error, info, debug) that are present in any other standard logger.
+    /// Class is used as singleton design pattern
+    /// </summary>
     public abstract class ALogger : IDisposable {
 
+        /// <summary>
+        /// Logger verbosity type identifies how much information should be actually logged
+        /// </summary>
         private readonly LogVerbosity _verbosity;
+
+        /// <summary>
+        /// Current type of logger
+        /// </summary>
         private readonly LogFlow _logFlow;
 
+        /// <summary>
+        /// Queue of all not yet logged messages
+        /// </summary>
         private readonly Queue<Action> _queue = new();
+
+        /// <summary>
+        /// Synchronization prime used to identify if the is anything new in the queue 
+        /// </summary>
         private readonly ManualResetEvent _hasNewItems = new(false);
+        /// <summary>
+        /// Synchronization prime used to identify if the logger should be terminated
+        /// </summary>
         private readonly ManualResetEvent _terminate = new(false);
+        /// <summary>
+        /// Synchronization prime used to identify if the current thread is waiting
+        /// </summary>
         private readonly ManualResetEvent _waiting = new(false);
+
+        /// <summary>
+        /// Thread instance of logging thread
+        /// </summary>
         private readonly Thread _loggingThread;
 
+        /// <summary>
+        /// Instance of the default logger initialized with the lazy binding mechanism
+        /// </summary>
         private static readonly Lazy<ALogger> LazyLog = new(()
             => {
                 switch (Program.Config.LogFlowType) {
@@ -26,8 +58,14 @@ namespace LDClient.utils.loggers {
             }
         );
 
+        /// <summary>
+        /// Instance of the current logger type
+        /// </summary>
         public static ALogger Current => LazyLog.Value;
 
+        /// <summary>
+        /// Singleton constructor that initialized and starts the logger with arguments parsed by the config loader
+        /// </summary>
         protected ALogger() {
             _verbosity = Program.Config.LogVerbosityType;
             _logFlow = Program.Config.LogFlowType;
@@ -35,46 +73,87 @@ namespace LDClient.utils.loggers {
             _loggingThread.Start();
         }
 
+        /// <summary>
+        /// Creates new log with Info identifier
+        /// </summary>
+        /// <param name="message">Desired message to be logged</param>
         public void Info(string message) {
             Log(message, LogType.Info);
         }
 
+        /// <summary>
+        /// Creates new log with Debug identifier
+        /// </summary>
+        /// <param name="message">Desired message to be logged</param>
         public void Debug(string message) {
             Log(message, LogType.Debug);
         }
 
+        /// <summary>
+        /// Creates new log with Error identifier
+        /// </summary>
+        /// <param name="message">Desired message to be logged</param>
         public void Error(string message) {
             Log(message, LogType.Error);
         }
 
+        /// <summary>
+        /// Creates new log from the catched exception
+        /// </summary>
+        /// <param name="e">catched exception tha should be logged</param>
         public void Error(Exception e) {
             if (_verbosity != LogVerbosity.None) {
                 Log(UnwrapExceptionMessages(e), LogType.Error);
             }
         }
 
+        /// <summary>
+        /// Creates new string info about current logger configuration
+        /// </summary>
+        /// <returns></returns>
         public override string ToString() => $"Logger settings: [Type: {this.GetType().Name}, Verbosity: {_verbosity}, ";
-
+        
         protected abstract void CreateLog(string message);
 
+        /// <summary>
+        /// Waits for the logger to finish the logging
+        /// </summary>
         public void Flush() => _waiting.WaitOne();
 
+        /// <summary>
+        /// Function stops the logger thread
+        /// </summary>
         public void Dispose() {
             _terminate.Set();
             _loggingThread.Join();
         }
 
+        /// <summary>
+        /// Composes the log with actual timestamp, log type and its main message
+        /// </summary>
+        /// <param name="message">main message of the log</param>
+        /// <param name="logType">Type of the logged message</param>
+        /// <returns></returns>
         protected virtual string ComposeLogRow(string message, LogType logType) =>
             $"[{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss,fff", CultureInfo.InvariantCulture)} - {logType}] - {message}";
 
+        /// <summary>
+        /// Function creates log from the catched exception
+        /// </summary>
+        /// <param name="ex">catched exception tha should be logged</param>
+        /// <returns></returns>
         protected virtual string UnwrapExceptionMessages(Exception? ex) =>
             ex == null ? string.Empty : $"{ex}, Inner exception: {UnwrapExceptionMessages(ex.InnerException)} ";
         
-
+        /// <summary>
+        /// Function that periodically processes message queue
+        /// </summary>
         private void ProcessQueue() {
             while (true) {
                 _waiting.Set();
+                //wait until there is new item in the queue or until termination invoked
                 var i = WaitHandle.WaitAny(new WaitHandle[] { _hasNewItems, _terminate });
+                //was the termination invoked?
                 if (i == 1) return;
                 _hasNewItems.Reset();
                 _waiting.Reset();
@@ -91,6 +170,11 @@ namespace LDClient.utils.loggers {
             }
         }
 
+        /// <summary>
+        /// Creates new log string from the current timestamp 
+        /// </summary>
+        /// <param name="message"></param>
+        /// <param name="logType"></param>
         private void Log(string message, LogType logType) {
             if (string.IsNullOrEmpty(message))
                 return;
diff --git a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs
index b108ed6..a893d02 100644
--- a/ld_client/LDClient/utils/loggers/ConsoleLogger.cs
+++ b/ld_client/LDClient/utils/loggers/ConsoleLogger.cs
@@ -1,5 +1,9 @@
 namespace LDClient.utils.loggers {
     public class ConsoleLogger : ALogger {
+        /// <summary>
+        /// CreateLog function for the ConsoleLogger prints the desired message to the console
+        /// </summary>
+        /// <param name="message">Desired message to be printed</param>
         protected override void CreateLog(string message) {
             Console.WriteLine(message);
         }
diff --git a/ld_client/LDClient/utils/loggers/FileLogger.cs b/ld_client/LDClient/utils/loggers/FileLogger.cs
index d63ab05..6651ff9 100644
--- a/ld_client/LDClient/utils/loggers/FileLogger.cs
+++ b/ld_client/LDClient/utils/loggers/FileLogger.cs
@@ -4,17 +4,37 @@ namespace LDClient.utils.loggers;
 
 public class FileLogger : ALogger {
 
+    /// <summary>
+    /// Folder name for the created log files
+    /// </summary>
     private const string LogFolderName = "logs";
+    /// <summary>
+    /// Base name of the log file
+    /// </summary>
     private const string LogFileName = "app_info.log";
+    
     private readonly int _logChunkSize = Program.Config.LogChunkSize;
     private readonly int _logChunkMaxCount = Program.Config.LogChunkMaxCount;
     private readonly int _logArchiveMaxCount = Program.Config.LogArchiveMaxCount;
     private readonly int _logCleanupPeriod = Program.Config.LogCleanupPeriod;
 
+    /// <summary>
+    /// Destination folder used to store the created logs and zipped chunks
+    /// </summary>
     private const string LogFolderPath = $"ldClient\\{LogFolderName}";
 
+    /// <summary>
+    /// Flag that indicates that the log folder is already created
+    /// </summary>
     private bool _logDirExists;
 
+    /// <summary>
+    /// Creates one entry in the rotating file.
+    /// If the current log file is too big, it creates new log file.
+    /// If there is too many log files it archives them.
+    /// Deletes all archived files that are too old
+    /// </summary>
+    /// <param name="message">Desired message to be logged<</param>
     protected override void CreateLog(string message) {
 
         if (!_logDirExists) {
@@ -33,6 +53,10 @@ public class FileLogger : ALogger {
         sw.WriteLine(message);
     }
 
+    /// <summary>
+    /// Rotates last log file by creating new logging file in the process
+    /// </summary>
+    /// <param name="filePath">path to the last log file</param>
     private void Rotate(string filePath) {
         if (!File.Exists(filePath)) {
             return;
@@ -60,6 +84,13 @@ public class FileLogger : ALogger {
         DeleteOldArchives(logFolderContent);
     }
 
+    /// <summary>
+    /// Archives the all the last log files (chunks) 
+    /// </summary>
+    /// <param name="chunks">All log files that will be archived</param>
+    /// <param name="rotatedPath">path to the log files, which will be archived</param>
+    /// <param name="fileTime">current time stamp in string</param>
+    /// <param name="folderPath">path to to the exported archives</param>
     private void Archive(IEnumerable<FileSystemInfo> chunks, string rotatedPath, string fileTime, string? folderPath) {
 
         var archiveFolderInfo = Directory.CreateDirectory(Path.Combine(Path.GetDirectoryName(rotatedPath) ?? LogFolderPath, $"{LogFolderName}_{fileTime}"));
@@ -73,15 +104,22 @@ public class FileLogger : ALogger {
         Directory.Delete(archiveFolderInfo.FullName, true);
     }
 
+    /// <summary>
+    /// This function deletes all archives that are too old and exceeds the maximum zip files.
+    /// Cleanup period and zip max count can be specified in the configuration file.
+    /// </summary>
+    /// <param name="logFolderContent">filesystem info of the log folder</param>
     private void DeleteOldArchives(FileSystemInfo[] logFolderContent) {
 
         var archives = logFolderContent.Where(x => x.Extension.Equals(".zip", StringComparison.OrdinalIgnoreCase)).ToArray();
-
+        
         if (archives.Length <= _logArchiveMaxCount)
             return;
 
+        //find oldest archive in the folder
         var oldestArchive = archives.OrderBy(x => x.CreationTime).First();
         var cleanupDate = oldestArchive.CreationTime.AddDays(_logCleanupPeriod);
+        //is there any file older than specified cleanup cleanup period
         if (DateTime.Compare(cleanupDate, DateTime.Now) <= 0) {
             foreach (var file in logFolderContent) {
                 file.Delete();
@@ -90,6 +128,5 @@ public class FileLogger : ALogger {
             File.Delete(oldestArchive.FullName);
         }
     }
-
     public override string ToString() => $"{base.ToString()}, Chunk Size: {_logChunkSize}, Max chunk count: {_logChunkMaxCount}, Max log archive count: {_logArchiveMaxCount}, Cleanup period: {_logCleanupPeriod} days]";
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/loggers/LogFlow.cs b/ld_client/LDClient/utils/loggers/LogFlow.cs
index 5041b12..92555cd 100644
--- a/ld_client/LDClient/utils/loggers/LogFlow.cs
+++ b/ld_client/LDClient/utils/loggers/LogFlow.cs
@@ -1,6 +1,15 @@
 namespace LDClient.utils.loggers {
+    /// <summary>
+    /// This enum specifies all possible types of loggers
+    /// </summary>
     public enum LogFlow {
+        /// <summary>
+        /// Console logger
+        /// </summary>
         Console = 0,
+        /// <summary>
+        /// Rotating file logger
+        /// </summary>
         File
     }
 }
diff --git a/ld_client/LDClient/utils/loggers/LogType.cs b/ld_client/LDClient/utils/loggers/LogType.cs
index 370057f..b3caad6 100644
--- a/ld_client/LDClient/utils/loggers/LogType.cs
+++ b/ld_client/LDClient/utils/loggers/LogType.cs
@@ -1,4 +1,7 @@
 namespace LDClient.utils.loggers {
+    /// <summary>
+    /// Types of all possible logs
+    /// </summary>
     public enum LogType {
         Info = 0,
         Debug,
diff --git a/ld_client/LDClient/utils/loggers/LogVerbosity.cs b/ld_client/LDClient/utils/loggers/LogVerbosity.cs
index 03c292b..af525a9 100644
--- a/ld_client/LDClient/utils/loggers/LogVerbosity.cs
+++ b/ld_client/LDClient/utils/loggers/LogVerbosity.cs
@@ -1,4 +1,8 @@
 namespace LDClient.utils.loggers {
+
+    /// <summary>
+    /// Enum specifies the verbosity of the log messages
+    /// </summary>
     public enum LogVerbosity {
         None = 0,
         Exceptions,
-- 
GitLab


From 605fed4f4af530aa79f1ba709b08fbc5e9285530 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sat, 7 May 2022 23:31:56 +0200
Subject: [PATCH 52/67] re #9570 Added generated html documentation

---
 ld_client/doc/pdoc/annotated.html             |  124 ++
 ld_client/doc/pdoc/annotated_dup.js           |   31 +
 ld_client/doc/pdoc/bc_s.png                   |  Bin 0 -> 676 bytes
 ld_client/doc/pdoc/bdwn.png                   |  Bin 0 -> 147 bytes
 .../doc/pdoc/class_file_logger-members.html   |  103 +
 ld_client/doc/pdoc/class_file_logger.html     |  154 ++
 ld_client/doc/pdoc/class_file_logger.js       |    4 +
 ...1_1detection_1_1_info_fetcher-members.html |  107 +
 ..._client_1_1detection_1_1_info_fetcher.html |  301 +++
 ..._d_client_1_1detection_1_1_info_fetcher.js |    9 +
 ...tection_1_1_process_detection-members.html |  104 +
 ...nt_1_1detection_1_1_process_detection.html |  188 ++
 ...ient_1_1detection_1_1_process_detection.js |    6 +
 ..._1detection_1_1_process_utils-members.html |  103 +
 ...client_1_1detection_1_1_process_utils.html |  210 ++
 ...d_client_1_1detection_1_1_process_utils.js |    5 +
 ...ent_1_1network_1_1_api_client-members.html |  106 +
 ..._l_d_client_1_1network_1_1_api_client.html |  264 +++
 ...ss_l_d_client_1_1network_1_1_api_client.js |    8 +
 ...nt_1_1network_1_1_http_client-members.html |  103 +
 ...l_d_client_1_1network_1_1_http_client.html |  180 ++
 ...s_l_d_client_1_1network_1_1_http_client.js |    5 +
 ...ork_1_1data_1_1_debugger_info-members.html |  102 +
 ..._1_1network_1_1data_1_1_debugger_info.html |  118 ++
 ...nt_1_1network_1_1data_1_1_debugger_info.js |    4 +
 ..._1network_1_1data_1_1_payload-members.html |  110 +
 ...client_1_1network_1_1data_1_1_payload.html |  231 +++
 ...d_client_1_1network_1_1data_1_1_payload.js |   11 +
 ...lient_1_1utils_1_1_file_utils-members.html |  102 +
 ...ss_l_d_client_1_1utils_1_1_file_utils.html |  150 ++
 ...lass_l_d_client_1_1utils_1_1_file_utils.js |    4 +
 ...utils_1_1loggers_1_1_a_logger-members.html |  113 +
 ...ient_1_1utils_1_1loggers_1_1_a_logger.html |  395 ++++
 ...client_1_1utils_1_1loggers_1_1_a_logger.js |   13 +
 ...1_1loggers_1_1_console_logger-members.html |  113 +
 ..._1utils_1_1loggers_1_1_console_logger.html |  194 ++
 ..._1_1utils_1_1loggers_1_1_console_logger.js |    4 +
 ld_client/doc/pdoc/classes.html               |  122 ++
 ld_client/doc/pdoc/closed.png                 |  Bin 0 -> 132 bytes
 .../dir_08b4fbe3d60d6d41472a6a22c750d4c7.html |   99 +
 .../dir_43724e81dd40e09f32417973865cdd64.html |   99 +
 .../dir_7212c827820ef56532d3599ed27e3aff.html |   99 +
 .../dir_754926843367c7eee8b48719e3f14adf.html |   99 +
 .../dir_a71c3b2ad23b9ff58220dd012d201987.html |  105 +
 .../dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html |   99 +
 .../dir_c901c14b65aa229498a52b725b3d4a2c.html |  105 +
 .../dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html |  105 +
 ld_client/doc/pdoc/doc.png                    |  Bin 0 -> 746 bytes
 ld_client/doc/pdoc/doxygen.css                | 1841 +++++++++++++++++
 ld_client/doc/pdoc/doxygen.svg                |   26 +
 ld_client/doc/pdoc/dynsections.js             |  121 ++
 ld_client/doc/pdoc/folderclosed.png           |  Bin 0 -> 616 bytes
 ld_client/doc/pdoc/folderopen.png             |  Bin 0 -> 597 bytes
 ld_client/doc/pdoc/functions.html             |  189 ++
 ld_client/doc/pdoc/functions_func.html        |  166 ++
 ld_client/doc/pdoc/functions_prop.html        |  107 +
 ld_client/doc/pdoc/functions_vars.html        |  102 +
 ld_client/doc/pdoc/hierarchy.html             |  120 ++
 ld_client/doc/pdoc/hierarchy.js               |   29 +
 ld_client/doc/pdoc/index.html                 |   98 +
 ...1detection_1_1_i_info_fetcher-members.html |  104 +
 ...lient_1_1detection_1_1_i_info_fetcher.html |  203 ++
 ..._client_1_1detection_1_1_i_info_fetcher.js |    6 +
 ...detection_1_1_i_process_utils-members.html |  103 +
 ...ient_1_1detection_1_1_i_process_utils.html |  204 ++
 ...client_1_1detection_1_1_i_process_utils.js |    5 +
 ...t_1_1network_1_1_i_api_client-members.html |  103 +
 ..._d_client_1_1network_1_1_i_api_client.html |  170 ++
 ..._l_d_client_1_1network_1_1_i_api_client.js |    5 +
 ..._1_1network_1_1_i_http_client-members.html |  102 +
 ...d_client_1_1network_1_1_i_http_client.html |  147 ++
 ...l_d_client_1_1network_1_1_i_http_client.js |    4 +
 ...ent_1_1utils_1_1_i_file_utils-members.html |  102 +
 ..._l_d_client_1_1utils_1_1_i_file_utils.html |  147 ++
 ...ce_l_d_client_1_1utils_1_1_i_file_utils.js |    4 +
 ld_client/doc/pdoc/jquery.js                  |   35 +
 ld_client/doc/pdoc/menu.js                    |  135 ++
 ld_client/doc/pdoc/menudata.js                |   66 +
 ld_client/doc/pdoc/namespace_l_d_client.html  |   99 +
 ld_client/doc/pdoc/namespace_l_d_client.js    |    6 +
 .../namespace_l_d_client_1_1detection.html    |  126 ++
 .../pdoc/namespace_l_d_client_1_1detection.js |    8 +
 .../pdoc/namespace_l_d_client_1_1network.html |  117 ++
 .../pdoc/namespace_l_d_client_1_1network.js   |    8 +
 ...mespace_l_d_client_1_1network_1_1data.html |  143 ++
 ...namespace_l_d_client_1_1network_1_1data.js |    9 +
 .../pdoc/namespace_l_d_client_1_1utils.html   |  114 +
 .../doc/pdoc/namespace_l_d_client_1_1utils.js |    6 +
 ...espace_l_d_client_1_1utils_1_1loggers.html |  154 ++
 ...amespace_l_d_client_1_1utils_1_1loggers.js |   19 +
 ld_client/doc/pdoc/namespacemembers.html      |  101 +
 ld_client/doc/pdoc/namespacemembers_enum.html |  101 +
 ld_client/doc/pdoc/namespaces.html            |  123 ++
 ld_client/doc/pdoc/namespaces_dup.js          |    4 +
 ld_client/doc/pdoc/nav_f.png                  |  Bin 0 -> 153 bytes
 ld_client/doc/pdoc/nav_g.png                  |  Bin 0 -> 95 bytes
 ld_client/doc/pdoc/nav_h.png                  |  Bin 0 -> 98 bytes
 ld_client/doc/pdoc/navtree.css                |  147 ++
 ld_client/doc/pdoc/navtree.js                 |  549 +++++
 ld_client/doc/pdoc/navtreedata.js             |   55 +
 ld_client/doc/pdoc/navtreeindex0.js           |  163 ++
 ld_client/doc/pdoc/open.png                   |  Bin 0 -> 123 bytes
 ld_client/doc/pdoc/resize.js                  |  150 ++
 ld_client/doc/pdoc/search/all_0.html          |   37 +
 ld_client/doc/pdoc/search/all_0.js            |    4 +
 ld_client/doc/pdoc/search/all_1.html          |   37 +
 ld_client/doc/pdoc/search/all_1.js            |    5 +
 ld_client/doc/pdoc/search/all_2.html          |   37 +
 ld_client/doc/pdoc/search/all_2.js            |    5 +
 ld_client/doc/pdoc/search/all_3.html          |   37 +
 ld_client/doc/pdoc/search/all_3.js            |   11 +
 ld_client/doc/pdoc/search/all_4.html          |   37 +
 ld_client/doc/pdoc/search/all_4.js            |    8 +
 ld_client/doc/pdoc/search/all_5.html          |   37 +
 ld_client/doc/pdoc/search/all_5.js            |    5 +
 ld_client/doc/pdoc/search/all_6.html          |   37 +
 ld_client/doc/pdoc/search/all_6.js            |    8 +
 ld_client/doc/pdoc/search/all_7.html          |   37 +
 ld_client/doc/pdoc/search/all_7.js            |    7 +
 ld_client/doc/pdoc/search/all_8.html          |   37 +
 ld_client/doc/pdoc/search/all_8.js            |   11 +
 ld_client/doc/pdoc/search/all_9.html          |   37 +
 ld_client/doc/pdoc/search/all_9.js            |   12 +
 ld_client/doc/pdoc/search/all_a.html          |   37 +
 ld_client/doc/pdoc/search/all_a.js            |    8 +
 ld_client/doc/pdoc/search/all_b.html          |   37 +
 ld_client/doc/pdoc/search/all_b.js            |    6 +
 ld_client/doc/pdoc/search/all_c.html          |   37 +
 ld_client/doc/pdoc/search/all_c.js            |    6 +
 ld_client/doc/pdoc/search/all_d.html          |   37 +
 ld_client/doc/pdoc/search/all_d.js            |    5 +
 ld_client/doc/pdoc/search/all_e.html          |   37 +
 ld_client/doc/pdoc/search/all_e.js            |    5 +
 ld_client/doc/pdoc/search/classes_0.html      |   37 +
 ld_client/doc/pdoc/search/classes_0.js        |    5 +
 ld_client/doc/pdoc/search/classes_1.html      |   37 +
 ld_client/doc/pdoc/search/classes_1.js        |    4 +
 ld_client/doc/pdoc/search/classes_2.html      |   37 +
 ld_client/doc/pdoc/search/classes_2.js        |    4 +
 ld_client/doc/pdoc/search/classes_3.html      |   37 +
 ld_client/doc/pdoc/search/classes_3.js        |    5 +
 ld_client/doc/pdoc/search/classes_4.html      |   37 +
 ld_client/doc/pdoc/search/classes_4.js        |    4 +
 ld_client/doc/pdoc/search/classes_5.html      |   37 +
 ld_client/doc/pdoc/search/classes_5.js        |    9 +
 ld_client/doc/pdoc/search/classes_6.html      |   37 +
 ld_client/doc/pdoc/search/classes_6.js        |    6 +
 ld_client/doc/pdoc/search/close.svg           |   31 +
 ld_client/doc/pdoc/search/enums_0.html        |   37 +
 ld_client/doc/pdoc/search/enums_0.js          |    4 +
 ld_client/doc/pdoc/search/enums_1.html        |   37 +
 ld_client/doc/pdoc/search/enums_1.js          |    6 +
 ld_client/doc/pdoc/search/enumvalues_0.html   |   37 +
 ld_client/doc/pdoc/search/enumvalues_0.js     |    5 +
 ld_client/doc/pdoc/search/enumvalues_1.html   |   37 +
 ld_client/doc/pdoc/search/enumvalues_1.js     |    4 +
 ld_client/doc/pdoc/search/enumvalues_2.html   |   37 +
 ld_client/doc/pdoc/search/enumvalues_2.js     |    4 +
 ld_client/doc/pdoc/search/functions_0.html    |   37 +
 ld_client/doc/pdoc/search/functions_0.js      |    5 +
 ld_client/doc/pdoc/search/functions_1.html    |   37 +
 ld_client/doc/pdoc/search/functions_1.js      |    5 +
 ld_client/doc/pdoc/search/functions_2.html    |   37 +
 ld_client/doc/pdoc/search/functions_2.js      |    5 +
 ld_client/doc/pdoc/search/functions_3.html    |   37 +
 ld_client/doc/pdoc/search/functions_3.js      |    5 +
 ld_client/doc/pdoc/search/functions_4.html    |   37 +
 ld_client/doc/pdoc/search/functions_4.js      |    5 +
 ld_client/doc/pdoc/search/functions_5.html    |   37 +
 ld_client/doc/pdoc/search/functions_5.js      |    4 +
 ld_client/doc/pdoc/search/functions_6.html    |   37 +
 ld_client/doc/pdoc/search/functions_6.js      |    6 +
 ld_client/doc/pdoc/search/functions_7.html    |   37 +
 ld_client/doc/pdoc/search/functions_7.js      |    6 +
 ld_client/doc/pdoc/search/functions_8.html    |   37 +
 ld_client/doc/pdoc/search/functions_8.js      |    6 +
 ld_client/doc/pdoc/search/functions_9.html    |   37 +
 ld_client/doc/pdoc/search/functions_9.js      |    4 +
 ld_client/doc/pdoc/search/functions_a.html    |   37 +
 ld_client/doc/pdoc/search/functions_a.js      |    4 +
 ld_client/doc/pdoc/search/functions_b.html    |   37 +
 ld_client/doc/pdoc/search/functions_b.js      |    4 +
 ld_client/doc/pdoc/search/mag_sel.svg         |   74 +
 ld_client/doc/pdoc/search/namespaces_0.html   |   37 +
 ld_client/doc/pdoc/search/namespaces_0.js     |    9 +
 ld_client/doc/pdoc/search/nomatches.html      |   13 +
 ld_client/doc/pdoc/search/properties_0.html   |   37 +
 ld_client/doc/pdoc/search/properties_0.js     |    5 +
 ld_client/doc/pdoc/search/properties_1.html   |   37 +
 ld_client/doc/pdoc/search/properties_1.js     |    4 +
 ld_client/doc/pdoc/search/properties_2.html   |   37 +
 ld_client/doc/pdoc/search/properties_2.js     |    6 +
 ld_client/doc/pdoc/search/properties_3.html   |   37 +
 ld_client/doc/pdoc/search/properties_3.js     |    5 +
 ld_client/doc/pdoc/search/properties_4.html   |   37 +
 ld_client/doc/pdoc/search/properties_4.js     |    4 +
 ld_client/doc/pdoc/search/properties_5.html   |   37 +
 ld_client/doc/pdoc/search/properties_5.js     |    4 +
 ld_client/doc/pdoc/search/search.css          |  263 +++
 ld_client/doc/pdoc/search/search.js           |  802 +++++++
 ld_client/doc/pdoc/search/search_l.png        |  Bin 0 -> 567 bytes
 ld_client/doc/pdoc/search/search_m.png        |  Bin 0 -> 158 bytes
 ld_client/doc/pdoc/search/search_r.png        |  Bin 0 -> 553 bytes
 ld_client/doc/pdoc/search/searchdata.js       |   36 +
 ld_client/doc/pdoc/search/variables_0.html    |   37 +
 ld_client/doc/pdoc/search/variables_0.js      |    4 +
 ld_client/doc/pdoc/search/variables_1.html    |   37 +
 ld_client/doc/pdoc/search/variables_1.js      |    4 +
 ld_client/doc/pdoc/search/variables_2.html    |   37 +
 ld_client/doc/pdoc/search/variables_2.js      |    4 +
 ld_client/doc/pdoc/search/variables_3.html    |   37 +
 ld_client/doc/pdoc/search/variables_3.js      |    4 +
 ld_client/doc/pdoc/search/variables_4.html    |   37 +
 ld_client/doc/pdoc/search/variables_4.js      |    4 +
 ld_client/doc/pdoc/splitbar.png               |  Bin 0 -> 314 bytes
 ld_client/doc/pdoc/sync_off.png               |  Bin 0 -> 853 bytes
 ld_client/doc/pdoc/sync_on.png                |  Bin 0 -> 845 bytes
 ld_client/doc/pdoc/tab_a.png                  |  Bin 0 -> 142 bytes
 ld_client/doc/pdoc/tab_b.png                  |  Bin 0 -> 169 bytes
 ld_client/doc/pdoc/tab_h.png                  |  Bin 0 -> 177 bytes
 ld_client/doc/pdoc/tab_s.png                  |  Bin 0 -> 184 bytes
 ld_client/doc/pdoc/tabs.css                   |    1 +
 222 files changed, 14746 insertions(+)
 create mode 100644 ld_client/doc/pdoc/annotated.html
 create mode 100644 ld_client/doc/pdoc/annotated_dup.js
 create mode 100644 ld_client/doc/pdoc/bc_s.png
 create mode 100644 ld_client/doc/pdoc/bdwn.png
 create mode 100644 ld_client/doc/pdoc/class_file_logger-members.html
 create mode 100644 ld_client/doc/pdoc/class_file_logger.html
 create mode 100644 ld_client/doc/pdoc/class_file_logger.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
 create mode 100644 ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js
 create mode 100644 ld_client/doc/pdoc/classes.html
 create mode 100644 ld_client/doc/pdoc/closed.png
 create mode 100644 ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html
 create mode 100644 ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html
 create mode 100644 ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html
 create mode 100644 ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html
 create mode 100644 ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html
 create mode 100644 ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html
 create mode 100644 ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html
 create mode 100644 ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html
 create mode 100644 ld_client/doc/pdoc/doc.png
 create mode 100644 ld_client/doc/pdoc/doxygen.css
 create mode 100644 ld_client/doc/pdoc/doxygen.svg
 create mode 100644 ld_client/doc/pdoc/dynsections.js
 create mode 100644 ld_client/doc/pdoc/folderclosed.png
 create mode 100644 ld_client/doc/pdoc/folderopen.png
 create mode 100644 ld_client/doc/pdoc/functions.html
 create mode 100644 ld_client/doc/pdoc/functions_func.html
 create mode 100644 ld_client/doc/pdoc/functions_prop.html
 create mode 100644 ld_client/doc/pdoc/functions_vars.html
 create mode 100644 ld_client/doc/pdoc/hierarchy.html
 create mode 100644 ld_client/doc/pdoc/hierarchy.js
 create mode 100644 ld_client/doc/pdoc/index.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
 create mode 100644 ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js
 create mode 100644 ld_client/doc/pdoc/jquery.js
 create mode 100644 ld_client/doc/pdoc/menu.js
 create mode 100644 ld_client/doc/pdoc/menudata.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html
 create mode 100644 ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js
 create mode 100644 ld_client/doc/pdoc/namespacemembers.html
 create mode 100644 ld_client/doc/pdoc/namespacemembers_enum.html
 create mode 100644 ld_client/doc/pdoc/namespaces.html
 create mode 100644 ld_client/doc/pdoc/namespaces_dup.js
 create mode 100644 ld_client/doc/pdoc/nav_f.png
 create mode 100644 ld_client/doc/pdoc/nav_g.png
 create mode 100644 ld_client/doc/pdoc/nav_h.png
 create mode 100644 ld_client/doc/pdoc/navtree.css
 create mode 100644 ld_client/doc/pdoc/navtree.js
 create mode 100644 ld_client/doc/pdoc/navtreedata.js
 create mode 100644 ld_client/doc/pdoc/navtreeindex0.js
 create mode 100644 ld_client/doc/pdoc/open.png
 create mode 100644 ld_client/doc/pdoc/resize.js
 create mode 100644 ld_client/doc/pdoc/search/all_0.html
 create mode 100644 ld_client/doc/pdoc/search/all_0.js
 create mode 100644 ld_client/doc/pdoc/search/all_1.html
 create mode 100644 ld_client/doc/pdoc/search/all_1.js
 create mode 100644 ld_client/doc/pdoc/search/all_2.html
 create mode 100644 ld_client/doc/pdoc/search/all_2.js
 create mode 100644 ld_client/doc/pdoc/search/all_3.html
 create mode 100644 ld_client/doc/pdoc/search/all_3.js
 create mode 100644 ld_client/doc/pdoc/search/all_4.html
 create mode 100644 ld_client/doc/pdoc/search/all_4.js
 create mode 100644 ld_client/doc/pdoc/search/all_5.html
 create mode 100644 ld_client/doc/pdoc/search/all_5.js
 create mode 100644 ld_client/doc/pdoc/search/all_6.html
 create mode 100644 ld_client/doc/pdoc/search/all_6.js
 create mode 100644 ld_client/doc/pdoc/search/all_7.html
 create mode 100644 ld_client/doc/pdoc/search/all_7.js
 create mode 100644 ld_client/doc/pdoc/search/all_8.html
 create mode 100644 ld_client/doc/pdoc/search/all_8.js
 create mode 100644 ld_client/doc/pdoc/search/all_9.html
 create mode 100644 ld_client/doc/pdoc/search/all_9.js
 create mode 100644 ld_client/doc/pdoc/search/all_a.html
 create mode 100644 ld_client/doc/pdoc/search/all_a.js
 create mode 100644 ld_client/doc/pdoc/search/all_b.html
 create mode 100644 ld_client/doc/pdoc/search/all_b.js
 create mode 100644 ld_client/doc/pdoc/search/all_c.html
 create mode 100644 ld_client/doc/pdoc/search/all_c.js
 create mode 100644 ld_client/doc/pdoc/search/all_d.html
 create mode 100644 ld_client/doc/pdoc/search/all_d.js
 create mode 100644 ld_client/doc/pdoc/search/all_e.html
 create mode 100644 ld_client/doc/pdoc/search/all_e.js
 create mode 100644 ld_client/doc/pdoc/search/classes_0.html
 create mode 100644 ld_client/doc/pdoc/search/classes_0.js
 create mode 100644 ld_client/doc/pdoc/search/classes_1.html
 create mode 100644 ld_client/doc/pdoc/search/classes_1.js
 create mode 100644 ld_client/doc/pdoc/search/classes_2.html
 create mode 100644 ld_client/doc/pdoc/search/classes_2.js
 create mode 100644 ld_client/doc/pdoc/search/classes_3.html
 create mode 100644 ld_client/doc/pdoc/search/classes_3.js
 create mode 100644 ld_client/doc/pdoc/search/classes_4.html
 create mode 100644 ld_client/doc/pdoc/search/classes_4.js
 create mode 100644 ld_client/doc/pdoc/search/classes_5.html
 create mode 100644 ld_client/doc/pdoc/search/classes_5.js
 create mode 100644 ld_client/doc/pdoc/search/classes_6.html
 create mode 100644 ld_client/doc/pdoc/search/classes_6.js
 create mode 100644 ld_client/doc/pdoc/search/close.svg
 create mode 100644 ld_client/doc/pdoc/search/enums_0.html
 create mode 100644 ld_client/doc/pdoc/search/enums_0.js
 create mode 100644 ld_client/doc/pdoc/search/enums_1.html
 create mode 100644 ld_client/doc/pdoc/search/enums_1.js
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_0.html
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_0.js
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_1.html
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_1.js
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_2.html
 create mode 100644 ld_client/doc/pdoc/search/enumvalues_2.js
 create mode 100644 ld_client/doc/pdoc/search/functions_0.html
 create mode 100644 ld_client/doc/pdoc/search/functions_0.js
 create mode 100644 ld_client/doc/pdoc/search/functions_1.html
 create mode 100644 ld_client/doc/pdoc/search/functions_1.js
 create mode 100644 ld_client/doc/pdoc/search/functions_2.html
 create mode 100644 ld_client/doc/pdoc/search/functions_2.js
 create mode 100644 ld_client/doc/pdoc/search/functions_3.html
 create mode 100644 ld_client/doc/pdoc/search/functions_3.js
 create mode 100644 ld_client/doc/pdoc/search/functions_4.html
 create mode 100644 ld_client/doc/pdoc/search/functions_4.js
 create mode 100644 ld_client/doc/pdoc/search/functions_5.html
 create mode 100644 ld_client/doc/pdoc/search/functions_5.js
 create mode 100644 ld_client/doc/pdoc/search/functions_6.html
 create mode 100644 ld_client/doc/pdoc/search/functions_6.js
 create mode 100644 ld_client/doc/pdoc/search/functions_7.html
 create mode 100644 ld_client/doc/pdoc/search/functions_7.js
 create mode 100644 ld_client/doc/pdoc/search/functions_8.html
 create mode 100644 ld_client/doc/pdoc/search/functions_8.js
 create mode 100644 ld_client/doc/pdoc/search/functions_9.html
 create mode 100644 ld_client/doc/pdoc/search/functions_9.js
 create mode 100644 ld_client/doc/pdoc/search/functions_a.html
 create mode 100644 ld_client/doc/pdoc/search/functions_a.js
 create mode 100644 ld_client/doc/pdoc/search/functions_b.html
 create mode 100644 ld_client/doc/pdoc/search/functions_b.js
 create mode 100644 ld_client/doc/pdoc/search/mag_sel.svg
 create mode 100644 ld_client/doc/pdoc/search/namespaces_0.html
 create mode 100644 ld_client/doc/pdoc/search/namespaces_0.js
 create mode 100644 ld_client/doc/pdoc/search/nomatches.html
 create mode 100644 ld_client/doc/pdoc/search/properties_0.html
 create mode 100644 ld_client/doc/pdoc/search/properties_0.js
 create mode 100644 ld_client/doc/pdoc/search/properties_1.html
 create mode 100644 ld_client/doc/pdoc/search/properties_1.js
 create mode 100644 ld_client/doc/pdoc/search/properties_2.html
 create mode 100644 ld_client/doc/pdoc/search/properties_2.js
 create mode 100644 ld_client/doc/pdoc/search/properties_3.html
 create mode 100644 ld_client/doc/pdoc/search/properties_3.js
 create mode 100644 ld_client/doc/pdoc/search/properties_4.html
 create mode 100644 ld_client/doc/pdoc/search/properties_4.js
 create mode 100644 ld_client/doc/pdoc/search/properties_5.html
 create mode 100644 ld_client/doc/pdoc/search/properties_5.js
 create mode 100644 ld_client/doc/pdoc/search/search.css
 create mode 100644 ld_client/doc/pdoc/search/search.js
 create mode 100644 ld_client/doc/pdoc/search/search_l.png
 create mode 100644 ld_client/doc/pdoc/search/search_m.png
 create mode 100644 ld_client/doc/pdoc/search/search_r.png
 create mode 100644 ld_client/doc/pdoc/search/searchdata.js
 create mode 100644 ld_client/doc/pdoc/search/variables_0.html
 create mode 100644 ld_client/doc/pdoc/search/variables_0.js
 create mode 100644 ld_client/doc/pdoc/search/variables_1.html
 create mode 100644 ld_client/doc/pdoc/search/variables_1.js
 create mode 100644 ld_client/doc/pdoc/search/variables_2.html
 create mode 100644 ld_client/doc/pdoc/search/variables_2.js
 create mode 100644 ld_client/doc/pdoc/search/variables_3.html
 create mode 100644 ld_client/doc/pdoc/search/variables_3.js
 create mode 100644 ld_client/doc/pdoc/search/variables_4.html
 create mode 100644 ld_client/doc/pdoc/search/variables_4.js
 create mode 100644 ld_client/doc/pdoc/splitbar.png
 create mode 100644 ld_client/doc/pdoc/sync_off.png
 create mode 100644 ld_client/doc/pdoc/sync_on.png
 create mode 100644 ld_client/doc/pdoc/tab_a.png
 create mode 100644 ld_client/doc/pdoc/tab_b.png
 create mode 100644 ld_client/doc/pdoc/tab_h.png
 create mode 100644 ld_client/doc/pdoc/tab_s.png
 create mode 100644 ld_client/doc/pdoc/tabs.css

diff --git a/ld_client/doc/pdoc/annotated.html b/ld_client/doc/pdoc/annotated.html
new file mode 100644
index 0000000..b2bd7ee
--- /dev/null
+++ b/ld_client/doc/pdoc/annotated.html
@@ -0,0 +1,124 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('annotated.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Class List</div></div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here are the classes, structs, unions and interfaces with brief descriptions:</div><div class="directory">
+<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span><span onclick="javascript:toggleLevel(4);">4</span>]</div><table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client.html" target="_self">LDClient</a></td><td class="desc"></td></tr>
+<tr id="row_0_0_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1detection.html" target="_self">detection</a></td><td class="desc"></td></tr>
+<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr>
+<tr id="row_0_0_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr>
+<tr id="row_0_0_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr>
+<tr id="row_0_0_3_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr>
+<tr id="row_0_0_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr>
+<tr id="row_0_1_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_1_" class="arrow" onclick="toggleFolder('0_1_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network.html" target="_self">network</a></td><td class="desc"></td></tr>
+<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_1_0_" class="arrow" onclick="toggleFolder('0_1_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network_1_1data.html" target="_self">data</a></td><td class="desc"></td></tr>
+<tr id="row_0_1_0_0_"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr>
+<tr id="row_0_1_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr>
+<tr id="row_0_1_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr>
+<tr id="row_0_1_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr>
+<tr id="row_0_1_3_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr>
+<tr id="row_0_1_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr>
+<tr id="row_0_2_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_2_" class="arrow" onclick="toggleFolder('0_2_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils.html" target="_self">utils</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_2_0_" class="arrow" onclick="toggleFolder('0_2_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html" target="_self">loggers</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_0_0_"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr>
+<tr id="row_0_2_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">ConsoleLogger</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr>
+<tr id="row_0_2_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr>
+<tr id="row_1_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_file_logger.html" target="_self">FileLogger</a></td><td class="desc"></td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/annotated_dup.js b/ld_client/doc/pdoc/annotated_dup.js
new file mode 100644
index 0000000..af9f396
--- /dev/null
+++ b/ld_client/doc/pdoc/annotated_dup.js
@@ -0,0 +1,31 @@
+var annotated_dup =
+[
+    [ "LDClient", "namespace_l_d_client.html", [
+      [ "detection", "namespace_l_d_client_1_1detection.html", [
+        [ "IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", "interface_l_d_client_1_1detection_1_1_i_info_fetcher" ],
+        [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", "class_l_d_client_1_1detection_1_1_info_fetcher" ],
+        [ "IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", "interface_l_d_client_1_1detection_1_1_i_process_utils" ],
+        [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", "class_l_d_client_1_1detection_1_1_process_detection" ],
+        [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", "class_l_d_client_1_1detection_1_1_process_utils" ]
+      ] ],
+      [ "network", "namespace_l_d_client_1_1network.html", [
+        [ "data", "namespace_l_d_client_1_1network_1_1data.html", [
+          [ "DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", "class_l_d_client_1_1network_1_1data_1_1_debugger_info" ],
+          [ "Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", "class_l_d_client_1_1network_1_1data_1_1_payload" ]
+        ] ],
+        [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", "class_l_d_client_1_1network_1_1_api_client" ],
+        [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", "class_l_d_client_1_1network_1_1_http_client" ],
+        [ "IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", "interface_l_d_client_1_1network_1_1_i_api_client" ],
+        [ "IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", "interface_l_d_client_1_1network_1_1_i_http_client" ]
+      ] ],
+      [ "utils", "namespace_l_d_client_1_1utils.html", [
+        [ "loggers", "namespace_l_d_client_1_1utils_1_1loggers.html", [
+          [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger" ],
+          [ "ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger" ]
+        ] ],
+        [ "FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", "class_l_d_client_1_1utils_1_1_file_utils" ],
+        [ "IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", "interface_l_d_client_1_1utils_1_1_i_file_utils" ]
+      ] ]
+    ] ],
+    [ "FileLogger", "class_file_logger.html", "class_file_logger" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/bc_s.png b/ld_client/doc/pdoc/bc_s.png
new file mode 100644
index 0000000000000000000000000000000000000000..224b29aa9847d5a4b3902efd602b7ddf7d33e6c2
GIT binary patch
literal 676
zcmV;V0$crwP)<h;3K|Lk000e1NJLTq000O80015c1^@s65rAI}0007ONkl<ZcmeI5
z%WD%+6voe;xyj6=NhXt~4{e$zF*P<SZp4L@2Hd!iQY<tJD@e5{RU55hl&Talf{KWb
zN*6A=C`Gqz5#NvcXzNOCOH(I9n<#?l<k5ws2omoMCgj%s3y1G=&gJ~>y__>=_9%My
z{n931IS})GlGUF8K#6VIbs%684A^L3@%PlP2>_sk`UWPq@f;rU*V%rPy_ekbhXT&s
z(GN{DxFv}*vZp`F>S!r||M`I*nOwwKX+BC~3P5N3-)Y{65c;ywYiAh-1*hZcToLHK
ztpl1xomJ+Yb}K(cfbJr2=GNOnT!UFA7Vy~fBz8?J>XHsbZoDad^8PxfSa0GDgENZS
zuLCEqzb*xWX2CG*b&5IiO#NzrW*;`VC9455M`o1NBh+(k8~`XCEEoC1Ybwf;vr4K3
zg|EB<07?SOqHp9DhLpS&bzgo70I+ghB_#)K7H%AMU3v}xuyQq9&Bm~++VYhF09a+U
zl7>n7Jjm$K#b*FONz~fj;I->Bf;ule1prFN9FovcDGBkpg>)O*-}eLnC{6oZHZ$o%
zXKW$;0_{8hxHQ>l;_*HATI(`7t#^{$(zLe}h*mqwOc*nRY9=?Sx4OOeVIfI|0V(V2
zBrW#G7Ss9wvzr@>H*`r>zE<Gz)cj&*s5lRy$b&*W@2j<GZEpXZ$P|Z!4Q$_|`5gj>
z+e8bOBgqIgldUJlG(YUDviMB`9+DH8n-s9SXRLyJHO1!=wY^79WYZMTa(wiZ!zP66
zA~!21vmF3H2{ngD;+`6j#~6j;$*f*G_2ZD1E;9(yaw7d-QnSCpK(cR1zU3qU0000<
KMNUMnLSTYoA~SLT

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/bdwn.png b/ld_client/doc/pdoc/bdwn.png
new file mode 100644
index 0000000000000000000000000000000000000000..940a0b950443a0bb1b216ac03c45b8a16c955452
GIT binary patch
literal 147
zcmeAS@N?(olHy`uVBq!ia0vp^>_E)H!3HEvS)PKZC{Gv1kP61Pb5HX&C<wUB513~7
zF-Lk{?g8$ijf`2F^ip|Vw7EpzIJxiU`6~>2wk~_T<sM_r%les%%^JdHy*A#$ew5wb
vr&wL1c8#4j*F5jfGT)c(PZrEb5O3m+yDrVre6KeTXbXd<tDnm{r-UW|3$!!q

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/class_file_logger-members.html b/ld_client/doc/pdoc/class_file_logger-members.html
new file mode 100644
index 0000000..3ec38a0
--- /dev/null
+++ b/ld_client/doc/pdoc/class_file_logger-members.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_file_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">FileLogger Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_file_logger.html">FileLogger</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">CreateLog</a>(string message)</td><td class="entry"><a class="el" href="class_file_logger.html">FileLogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="odd"><td class="entry"><b>ToString</b>() (defined in <a class="el" href="class_file_logger.html">FileLogger</a>)</td><td class="entry"><a class="el" href="class_file_logger.html">FileLogger</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_file_logger.html b/ld_client/doc/pdoc/class_file_logger.html
new file mode 100644
index 0000000..a2ebfca
--- /dev/null
+++ b/ld_client/doc/pdoc/class_file_logger.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: FileLogger Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_file_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pro-methods">Protected Member Functions</a> &#124;
+<a href="class_file_logger-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">FileLogger Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a81ffd2cce04042e6fadc3362ca5f1cf6"><td class="memItemLeft" align="right" valign="top"><a id="a81ffd2cce04042e6fadc3362ca5f1cf6" name="a81ffd2cce04042e6fadc3362ca5f1cf6"></a>
+override string&#160;</td><td class="memItemRight" valign="bottom"><b>ToString</b> ()</td></tr>
+<tr class="separator:a81ffd2cce04042e6fadc3362ca5f1cf6"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a>
+Protected Member Functions</h2></td></tr>
+<tr class="memitem:ad39844b2267623f858ab77e6f5433896"><td class="memItemLeft" align="right" valign="top">override void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">CreateLog</a> (string message)</td></tr>
+<tr class="memdesc:ad39844b2267623f858ab77e6f5433896"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates one entry in the rotating file. If the current log file is too big, it creates new log file. If there is too many log files it archives them. Deletes all archived files that are too old  <a href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">More...</a><br /></td></tr>
+<tr class="separator:ad39844b2267623f858ab77e6f5433896"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="ad39844b2267623f858ab77e6f5433896" name="ad39844b2267623f858ab77e6f5433896"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad39844b2267623f858ab77e6f5433896">&#9670;&nbsp;</a></span>CreateLog()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">override void FileLogger.CreateLog </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Creates one entry in the rotating file. If the current log file is too big, it creates new log file. If there is too many log files it archives them. Deletes all archived files that are too old </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>Desired message to be logged&lt;</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>utils/loggers/FileLogger.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="class_file_logger.html">FileLogger</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_file_logger.js b/ld_client/doc/pdoc/class_file_logger.js
new file mode 100644
index 0000000..5aafedf
--- /dev/null
+++ b/ld_client/doc/pdoc/class_file_logger.js
@@ -0,0 +1,4 @@
+var class_file_logger =
+[
+    [ "CreateLog", "class_file_logger.html#ad39844b2267623f858ab77e6f5433896", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html
new file mode 100644
index 0000000..5dcc6d0
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher-members.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_info_fetcher.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.detection.InfoFetcher Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">BodySerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">FetchDataAsync</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">FileUtils</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">HeadSerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">InfoFetcher</a>(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">ProcessUtils</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">LDClient.detection.InfoFetcher</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
new file mode 100644
index 0000000..e719c11
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
@@ -0,0 +1,301 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection.InfoFetcher Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_info_fetcher.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pub-attribs">Public Attributes</a> &#124;
+<a href="#properties">Properties</a> &#124;
+<a href="class_l_d_client_1_1detection_1_1_info_fetcher-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection.InfoFetcher Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher.  
+ <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:abadca27b2740339ac6c1fd5c5e08bb26"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">InfoFetcher</a> (uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable, string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs)</td></tr>
+<tr class="memdesc:abadca27b2740339ac6c1fd5c5e08bb26"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates an instance of this class.  <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">More...</a><br /></td></tr>
+<tr class="separator:abadca27b2740339ac6c1fd5c5e08bb26"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a2192ceaf45e724814bdfde96fc0e544c"><td class="memItemLeft" align="right" valign="top">async Task&lt; bool &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">FetchDataAsync</a> ()</td></tr>
+<tr class="memdesc:a2192ceaf45e724814bdfde96fc0e544c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers).  <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">More...</a><br /></td></tr>
+<tr class="separator:a2192ceaf45e724814bdfde96fc0e544c"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memItemLeft" align="right" valign="top">Task&lt; bool &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a> ()</td></tr>
+<tr class="memdesc:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers).  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">More...</a><br /></td></tr>
+<tr class="separator:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
+Public Attributes</h2></td></tr>
+<tr class="memitem:a37f11db6d7bc81193b70015fc9192ed8"><td class="memItemLeft" align="right" valign="top"><a id="a37f11db6d7bc81193b70015fc9192ed8" name="a37f11db6d7bc81193b70015fc9192ed8"></a>
+<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a>&#160;</td><td class="memItemRight" valign="bottom"><b>ProcessUtils</b></td></tr>
+<tr class="memdesc:a37f11db6d7bc81193b70015fc9192ed8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" title="This class implements the IProcessUtils interface. It implements methods that are used when dealing w...">ProcessUtils</a> which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application). <br /></td></tr>
+<tr class="separator:a37f11db6d7bc81193b70015fc9192ed8"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:af30dbfb7559215ee29998f00ef5ea140"><td class="memItemLeft" align="right" valign="top"><a id="af30dbfb7559215ee29998f00ef5ea140" name="af30dbfb7559215ee29998f00ef5ea140"></a>
+<a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a>&#160;</td><td class="memItemRight" valign="bottom"><b>FileUtils</b></td></tr>
+<tr class="memdesc:af30dbfb7559215ee29998f00ef5ea140"><td class="mdescLeft">&#160;</td><td class="mdescRight">Instance of FileUtils which encapsulates common functionality when it comes to dealing with files (limited by the needs of this application). <br /></td></tr>
+<tr class="separator:af30dbfb7559215ee29998f00ef5ea140"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a>
+Properties</h2></td></tr>
+<tr class="memitem:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">HeadSerialNumber</a> = UndefinedSerialNumber<code> [get, set]</code></td></tr>
+<tr class="memdesc:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the head serial number of the debugger.  <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">More...</a><br /></td></tr>
+<tr class="separator:a053ba7e01a8cfcbebf2325a864e98e2f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">BodySerialNumber</a> = UndefinedSerialNumber<code> [get, set]</code></td></tr>
+<tr class="memdesc:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the body serial number of the debugger.  <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">More...</a><br /></td></tr>
+<tr class="separator:af38c5cdb5dc206c65d5f018e0b30dd1d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td colspan="2" onclick="javascript:toggleInherit('properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher')"><img src="closed.png" alt="-"/>&#160;Properties inherited from <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td></tr>
+<tr class="memitem:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a><code> [get, set]</code></td></tr>
+<tr class="memdesc:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the head serial number of the debugger.  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">More...</a><br /></td></tr>
+<tr class="separator:a196620b51706ff95e86dce886bd3d3a0 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a><code> [get, set]</code></td></tr>
+<tr class="memdesc:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the body serial number of the debugger.  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">More...</a><br /></td></tr>
+<tr class="separator:afff68b22c92585ba9169cd558bcb66b9 inherit properties_interface_l_d_client_1_1detection_1_1_i_info_fetcher"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </p>
+</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
+<a id="abadca27b2740339ac6c1fd5c5e08bb26" name="abadca27b2740339ac6c1fd5c5e08bb26"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#abadca27b2740339ac6c1fd5c5e08bb26">&#9670;&nbsp;</a></span>InfoFetcher()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">LDClient.detection.InfoFetcher.InfoFetcher </td>
+          <td>(</td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>maxAttempts</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>waitPeriodMs</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>infoFilePath</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>f32RemExecutable</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string[]&#160;</td>
+          <td class="paramname"><em>f32RemArguments</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>f32SuccessExitCode</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>f32WaitTimeoutMs</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates an instance of this class. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">maxAttempts</td><td>Maximum number of attempts to locate and parse the .txt file</td></tr>
+    <tr><td class="paramname">waitPeriodMs</td><td>Period (how often) the application tries to locate and parse the .txt file</td></tr>
+    <tr><td class="paramname">infoFilePath</td><td>Path to the .txt file which is generated from the debugger</td></tr>
+    <tr><td class="paramname">f32RemExecutable</td><td>Path to the t32rem.exe file which is used to send commands to the debugger</td></tr>
+    <tr><td class="paramname">f32RemArguments</td><td>Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</td></tr>
+    <tr><td class="paramname">f32SuccessExitCode</td><td>Status code indicating a successful termination of t32rem.exe</td></tr>
+    <tr><td class="paramname">f32WaitTimeoutMs</td><td>Timeout used when waiting for the t32rem.exe to finish</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="a2192ceaf45e724814bdfde96fc0e544c" name="a2192ceaf45e724814bdfde96fc0e544c"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a2192ceaf45e724814bdfde96fc0e544c">&#9670;&nbsp;</a></span>FetchDataAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">async Task&lt; bool &gt; LDClient.detection.InfoFetcher.FetchDataAsync </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). </p>
+<dl class="section return"><dt>Returns</dt><dd>True, if data was fetched successfully. False otherwise.</dd></dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>.</p>
+
+</div>
+</div>
+<h2 class="groupheader">Property Documentation</h2>
+<a id="af38c5cdb5dc206c65d5f018e0b30dd1d" name="af38c5cdb5dc206c65d5f018e0b30dd1d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#af38c5cdb5dc206c65d5f018e0b30dd1d">&#9670;&nbsp;</a></span>BodySerialNumber</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">string LDClient.detection.InfoFetcher.BodySerialNumber = UndefinedSerialNumber</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Returns the body serial number of the debugger. </p>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>.</p>
+
+</div>
+</div>
+<a id="a053ba7e01a8cfcbebf2325a864e98e2f" name="a053ba7e01a8cfcbebf2325a864e98e2f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a053ba7e01a8cfcbebf2325a864e98e2f">&#9670;&nbsp;</a></span>HeadSerialNumber</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">string LDClient.detection.InfoFetcher.HeadSerialNumber = UndefinedSerialNumber</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Returns the head serial number of the debugger. </p>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>detection/InfoFetcher.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js
new file mode 100644
index 0000000..d90f5da
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.js
@@ -0,0 +1,9 @@
+var class_l_d_client_1_1detection_1_1_info_fetcher =
+[
+    [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26", null ],
+    [ "FetchDataAsync", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c", null ],
+    [ "FileUtils", "class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140", null ],
+    [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8", null ],
+    [ "BodySerialNumber", "class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d", null ],
+    [ "HeadSerialNumber", "class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html
new file mode 100644
index 0000000..5e7b0eb
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection-members.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_detection.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.detection.ProcessDetection Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">DetectionRunning</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">ProcessDetection</a>(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher, IApiClient apiClient, IProcessUtils processUtils)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">RunPeriodicDetection</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">LDClient.detection.ProcessDetection</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
new file mode 100644
index 0000000..7080b7a
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
@@ -0,0 +1,188 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection.ProcessDetection Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_detection.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pub-attribs">Public Attributes</a> &#124;
+<a href="class_l_d_client_1_1detection_1_1_process_detection-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection.ProcessDetection Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger.  
+ <a href="class_l_d_client_1_1detection_1_1_process_detection.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">ProcessDetection</a> (string processName, uint detectionPeriodMs, <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a> infoFetcher, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a> apiClient, <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> processUtils)</td></tr>
+<tr class="memdesc:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates an instance of this class.  <a href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">More...</a><br /></td></tr>
+<tr class="separator:a586a1c6d9a48f2f7aa5389699bb4c679"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="memItemLeft" align="right" valign="top"><a id="adc7f2823d21a1fbbddfe0328d05df3a8" name="adc7f2823d21a1fbbddfe0328d05df3a8"></a>
+async void&#160;</td><td class="memItemRight" valign="bottom"><b>RunPeriodicDetection</b> ()</td></tr>
+<tr class="memdesc:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="mdescLeft">&#160;</td><td class="mdescRight">Periodically runs process detection. This method is instantiated as a thread from the main class (Program.cs). <br /></td></tr>
+<tr class="separator:adc7f2823d21a1fbbddfe0328d05df3a8"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
+Public Attributes</h2></td></tr>
+<tr class="memitem:acb2ce395f8b608c48165ae01677aa2a6"><td class="memItemLeft" align="right" valign="top"><a id="acb2ce395f8b608c48165ae01677aa2a6" name="acb2ce395f8b608c48165ae01677aa2a6"></a>
+bool&#160;</td><td class="memItemRight" valign="bottom"><b>DetectionRunning</b> = false</td></tr>
+<tr class="memdesc:acb2ce395f8b608c48165ae01677aa2a6"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flag used to stop the thread (process detection). <br /></td></tr>
+<tr class="separator:acb2ce395f8b608c48165ae01677aa2a6"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </p>
+</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
+<a id="a586a1c6d9a48f2f7aa5389699bb4c679" name="a586a1c6d9a48f2f7aa5389699bb4c679"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a586a1c6d9a48f2f7aa5389699bb4c679">&#9670;&nbsp;</a></span>ProcessDetection()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">LDClient.detection.ProcessDetection.ProcessDetection </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>processName</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>detectionPeriodMs</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a>&#160;</td>
+          <td class="paramname"><em>infoFetcher</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a>&#160;</td>
+          <td class="paramname"><em>apiClient</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a>&#160;</td>
+          <td class="paramname"><em>processUtils</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates an instance of this class. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">processName</td><td>Name of the process the application detects</td></tr>
+    <tr><td class="paramname">detectionPeriodMs</td><td>How often the application check the current status of the process (cunning / not running)</td></tr>
+    <tr><td class="paramname">infoFetcher</td><td>Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" title="This class implements the IInfoFetcher interface which defines the functionality of an info fetcher.">InfoFetcher</a> used to fetch information from the debugger</td></tr>
+    <tr><td class="paramname">apiClient</td><td>Instance of API clients used for sending data off to the server</td></tr>
+    <tr><td class="paramname">processUtils</td><td>Instance of <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" title="This class implements the IProcessUtils interface. It implements methods that are used when dealing w...">ProcessUtils</a> which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>detection/ProcessDetection.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js
new file mode 100644
index 0000000..1128cae
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.js
@@ -0,0 +1,6 @@
+var class_l_d_client_1_1detection_1_1_process_detection =
+[
+    [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679", null ],
+    [ "RunPeriodicDetection", "class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8", null ],
+    [ "DetectionRunning", "class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html
new file mode 100644
index 0000000..ab49597
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils-members.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.detection.ProcessUtils Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">ExecuteNewProcess</a>(string fileName, string argument, int timeout, int desiredExitCode)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">IsProcessRunning</a>(string name)</td><td class="entry"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">LDClient.detection.ProcessUtils</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
new file mode 100644
index 0000000..5bbf1df
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
@@ -0,0 +1,210 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection.ProcessUtils Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1detection_1_1_process_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="class_l_d_client_1_1detection_1_1_process_utils-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection.ProcessUtils Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes.  
+ <a href="class_l_d_client_1_1detection_1_1_process_utils.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a851a0af6188cf17614870a94ddb87fc4"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">IsProcessRunning</a> (string name)</td></tr>
+<tr class="memdesc:a851a0af6188cf17614870a94ddb87fc4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks if a process is running or not.  <a href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">More...</a><br /></td></tr>
+<tr class="separator:a851a0af6188cf17614870a94ddb87fc4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a863da05a6d25ead94a6eb0bd00f91557"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr>
+<tr class="memdesc:a863da05a6d25ead94a6eb0bd00f91557"><td class="mdescLeft">&#160;</td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method.  <a href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">More...</a><br /></td></tr>
+<tr class="separator:a863da05a6d25ead94a6eb0bd00f91557"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a> (string name)</td></tr>
+<tr class="memdesc:ad86c09b9bd71f7087ada92851b07e1a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks if a process is running or not.  <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">More...</a><br /></td></tr>
+<tr class="separator:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ab7e48a228ebaf7dddc671e5af2325662"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr>
+<tr class="memdesc:ab7e48a228ebaf7dddc671e5af2325662"><td class="mdescLeft">&#160;</td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method.  <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">More...</a><br /></td></tr>
+<tr class="separator:ab7e48a228ebaf7dddc671e5af2325662"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a863da05a6d25ead94a6eb0bd00f91557" name="a863da05a6d25ead94a6eb0bd00f91557"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a863da05a6d25ead94a6eb0bd00f91557">&#9670;&nbsp;</a></span>ExecuteNewProcess()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool LDClient.detection.ProcessUtils.ExecuteNewProcess </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>fileName</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>argument</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>timeout</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>desiredExitCode</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">fileName</td><td>Path to the .exe file</td></tr>
+    <tr><td class="paramname">argument</td><td>Arguments passed into the .exe file</td></tr>
+    <tr><td class="paramname">timeout</td><td>Timeout used when waiting for the process to terminate</td></tr>
+    <tr><td class="paramname">desiredExitCode</td><td>Status code indicating a successful termination of the process.</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>True, if the command was executed successfully. False otherwise.</dd></dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>.</p>
+
+</div>
+</div>
+<a id="a851a0af6188cf17614870a94ddb87fc4" name="a851a0af6188cf17614870a94ddb87fc4"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a851a0af6188cf17614870a94ddb87fc4">&#9670;&nbsp;</a></span>IsProcessRunning()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool LDClient.detection.ProcessUtils.IsProcessRunning </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>name</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Checks if a process is running or not. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">name</td><td>Name of the process</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>True, if the process is running. False otherwise.</dd></dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>detection/ProcessUtils.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js
new file mode 100644
index 0000000..9f2bdb9
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.js
@@ -0,0 +1,5 @@
+var class_l_d_client_1_1detection_1_1_process_utils =
+[
+    [ "ExecuteNewProcess", "class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557", null ],
+    [ "IsProcessRunning", "class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html
new file mode 100644
index 0000000..08956ca
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client-members.html
@@ -0,0 +1,106 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_api_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.ApiClient Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">_client</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">ApiClient</a>(string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">ClientRunning</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">Run</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">SendPayloadAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">LDClient.network.ApiClient</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
new file mode 100644
index 0000000..e8d1ec5
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
@@ -0,0 +1,264 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.ApiClient Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_api_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pub-attribs">Public Attributes</a> &#124;
+<a href="class_l_d_client_1_1network_1_1_api_client-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.ApiClient Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client.  
+ <a href="class_l_d_client_1_1network_1_1_api_client.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a9dc8bd923651fcbac08b72ae6165aa73"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">ApiClient</a> (string url, uint port, string path, uint retryPeriod, uint maxEntries, uint maxRetries, IPersistentQueue cache)</td></tr>
+<tr class="memdesc:a9dc8bd923651fcbac08b72ae6165aa73"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates an instance of the class.  <a href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">More...</a><br /></td></tr>
+<tr class="separator:a9dc8bd923651fcbac08b72ae6165aa73"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8e78939c5ab5b2f2f417ba280584cb55"><td class="memItemLeft" align="right" valign="top">async Task&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a8e78939c5ab5b2f2f417ba280584cb55"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sends a payload to the server (API).  <a href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">More...</a><br /></td></tr>
+<tr class="separator:a8e78939c5ab5b2f2f417ba280584cb55"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ade3b671e7561fbc4c560d3e3a7a79979"><td class="memItemLeft" align="right" valign="top">async void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">Run</a> ()</td></tr>
+<tr class="memdesc:ade3b671e7561fbc4c560d3e3a7a79979"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread.  <a href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">More...</a><br /></td></tr>
+<tr class="separator:ade3b671e7561fbc4c560d3e3a7a79979"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memItemLeft" align="right" valign="top">Task&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sends a payload to the server (API).  <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">More...</a><br /></td></tr>
+<tr class="separator:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a> ()</td></tr>
+<tr class="memdesc:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread.  <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">More...</a><br /></td></tr>
+<tr class="separator:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-attribs" name="pub-attribs"></a>
+Public Attributes</h2></td></tr>
+<tr class="memitem:a052df6039a9aed754761e3c62209f37d"><td class="memItemLeft" align="right" valign="top"><a id="a052df6039a9aed754761e3c62209f37d" name="a052df6039a9aed754761e3c62209f37d"></a>
+<a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a>&#160;</td><td class="memItemRight" valign="bottom"><b>_client</b></td></tr>
+<tr class="memdesc:a052df6039a9aed754761e3c62209f37d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Instance of an HTTP client the is used to send data off to the server <br /></td></tr>
+<tr class="separator:a052df6039a9aed754761e3c62209f37d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a5ea6642309925c666e39db7f3ac103c1"><td class="memItemLeft" align="right" valign="top"><a id="a5ea6642309925c666e39db7f3ac103c1" name="a5ea6642309925c666e39db7f3ac103c1"></a>
+bool&#160;</td><td class="memItemRight" valign="bottom"><b>ClientRunning</b></td></tr>
+<tr class="memdesc:a5ea6642309925c666e39db7f3ac103c1"><td class="mdescLeft">&#160;</td><td class="mdescRight">Flag used to stop the client (periodical retrieval from the cache) <br /></td></tr>
+<tr class="separator:a5ea6642309925c666e39db7f3ac103c1"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </p>
+</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
+<a id="a9dc8bd923651fcbac08b72ae6165aa73" name="a9dc8bd923651fcbac08b72ae6165aa73"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a9dc8bd923651fcbac08b72ae6165aa73">&#9670;&nbsp;</a></span>ApiClient()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">LDClient.network.ApiClient.ApiClient </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>url</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>port</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>path</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>retryPeriod</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>maxEntries</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">uint&#160;</td>
+          <td class="paramname"><em>maxRetries</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">IPersistentQueue&#160;</td>
+          <td class="paramname"><em>cache</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates an instance of the class. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">url</td><td>IP address of the server (url in case a DNS server is being used)</td></tr>
+    <tr><td class="paramname">port</td><td>port that the API is running on</td></tr>
+    <tr><td class="paramname">path</td><td>path of the API e.g. /api/v1/lg-logs</td></tr>
+    <tr><td class="paramname">retryPeriod</td><td>number of milliseconds after which the class tries to resend failed payloads to the server</td></tr>
+    <tr><td class="paramname">maxEntries</td><td>maximum number of entries (payloads) that can be sent to the server within one period</td></tr>
+    <tr><td class="paramname">maxRetries</td><td>maximum number of failed payloads to be kept in the file-based cache</td></tr>
+    <tr><td class="paramname">cache</td><td>instance of a persistent cache for storing failed payloads</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="ade3b671e7561fbc4c560d3e3a7a79979" name="ade3b671e7561fbc4c560d3e3a7a79979"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ade3b671e7561fbc4c560d3e3a7a79979">&#9670;&nbsp;</a></span>Run()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">async void LDClient.network.ApiClient.Run </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. </p>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a>.</p>
+
+</div>
+</div>
+<a id="a8e78939c5ab5b2f2f417ba280584cb55" name="a8e78939c5ab5b2f2f417ba280584cb55"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a8e78939c5ab5b2f2f417ba280584cb55">&#9670;&nbsp;</a></span>SendPayloadAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">async Task LDClient.network.ApiClient.SendPayloadAsync </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a>&#160;</td>
+          <td class="paramname"><em>payload</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Sends a payload to the server (API). </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">payload</td><td>instance of a payload to be sent off to the server</td></tr>
+  </table>
+  </dd>
+</dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>network/ApiClient.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js
new file mode 100644
index 0000000..6fde476
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.js
@@ -0,0 +1,8 @@
+var class_l_d_client_1_1network_1_1_api_client =
+[
+    [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73", null ],
+    [ "Run", "class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979", null ],
+    [ "SendPayloadAsync", "class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55", null ],
+    [ "_client", "class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d", null ],
+    [ "ClientRunning", "class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html
new file mode 100644
index 0000000..09e6545
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client-members.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_http_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.HttpClient Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">HttpClient</a>(string uri)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">PostAsJsonAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">LDClient.network.HttpClient</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
new file mode 100644
index 0000000..f885623
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
@@ -0,0 +1,180 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.HttpClient Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1_http_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="class_l_d_client_1_1network_1_1_http_client-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.HttpClient Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server.  
+ <a href="class_l_d_client_1_1network_1_1_http_client.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a7ec70d89410863e423ea2bcabaedc9a3"><td class="memItemLeft" align="right" valign="top">&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">HttpClient</a> (string uri)</td></tr>
+<tr class="memdesc:a7ec70d89410863e423ea2bcabaedc9a3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates an instance of the class  <a href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">More...</a><br /></td></tr>
+<tr class="separator:a7ec70d89410863e423ea2bcabaedc9a3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a553187973e0f43053af43bdae239ef4d"><td class="memItemLeft" align="right" valign="top">Task&lt; HttpResponseMessage &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a553187973e0f43053af43bdae239ef4d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Asynchronically sends data in JSON format to the server.  <a href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">More...</a><br /></td></tr>
+<tr class="separator:a553187973e0f43053af43bdae239ef4d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a241d7baceaf176b341c46844e235bd0f"><td class="memItemLeft" align="right" valign="top">Task&lt; HttpResponseMessage &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a241d7baceaf176b341c46844e235bd0f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Asynchronically sends data in JSON format to the server.  <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">More...</a><br /></td></tr>
+<tr class="separator:a241d7baceaf176b341c46844e235bd0f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </p>
+</div><h2 class="groupheader">Constructor &amp; Destructor Documentation</h2>
+<a id="a7ec70d89410863e423ea2bcabaedc9a3" name="a7ec70d89410863e423ea2bcabaedc9a3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a7ec70d89410863e423ea2bcabaedc9a3">&#9670;&nbsp;</a></span>HttpClient()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">LDClient.network.HttpClient.HttpClient </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>uri</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates an instance of the class </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">uri</td><td>URL to which the HTTP client will connect</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="a553187973e0f43053af43bdae239ef4d" name="a553187973e0f43053af43bdae239ef4d"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a553187973e0f43053af43bdae239ef4d">&#9670;&nbsp;</a></span>PostAsJsonAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">Task&lt; HttpResponseMessage &gt; LDClient.network.HttpClient.PostAsJsonAsync </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a>&#160;</td>
+          <td class="paramname"><em>payload</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Asynchronically sends data in JSON format to the server. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">payload</td><td>Payload to be sent to the server</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>network/HttpClient.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js
new file mode 100644
index 0000000..42b38f6
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.js
@@ -0,0 +1,5 @@
+var class_l_d_client_1_1network_1_1_http_client =
+[
+    [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3", null ],
+    [ "PostAsJsonAsync", "class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html
new file mode 100644
index 0000000..72fbec1
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.data.DebuggerInfo Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">LDClient.network.data.DebuggerInfo</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">SerialNumber</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">LDClient.network.data.DebuggerInfo</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
new file mode 100644
index 0000000..f51c123
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
@@ -0,0 +1,118 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.data.DebuggerInfo Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#properties">Properties</a> &#124;
+<a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.data.DebuggerInfo Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class holds all the information about a specific part of a debugger (head/body).  
+ <a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a>
+Properties</h2></td></tr>
+<tr class="memitem:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="memItemLeft" align="right" valign="top"><a id="acb364e62b03d8eea272ad6bed3dc9cdb" name="acb364e62b03d8eea272ad6bed3dc9cdb"></a>
+string?&#160;</td><td class="memItemRight" valign="bottom"><b>SerialNumber</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Serial number of the part of a debugger. <br /></td></tr>
+<tr class="separator:acb364e62b03d8eea272ad6bed3dc9cdb"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class holds all the information about a specific part of a debugger (head/body). </p>
+</div><hr/>The documentation for this class was generated from the following file:<ul>
+<li>network/data/DebuggerInfo.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js
new file mode 100644
index 0000000..ca56176
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.js
@@ -0,0 +1,4 @@
+var class_l_d_client_1_1network_1_1data_1_1_debugger_info =
+[
+    [ "SerialNumber", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html
new file mode 100644
index 0000000..f7c9fd4
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload-members.html
@@ -0,0 +1,110 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_payload.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.data.Payload Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">BodyDevice</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">HeadDevice</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">HostName</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">ParseToJson</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">ParseToJson</a>(Payload payload)</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">Status</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">TimeStamp</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">UserName</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">LDClient.network.data.Payload</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
new file mode 100644
index 0000000..617cfb5
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
@@ -0,0 +1,231 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.data.Payload Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1network_1_1data_1_1_payload.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pub-static-methods">Static Public Member Functions</a> &#124;
+<a href="#properties">Properties</a> &#124;
+<a href="class_l_d_client_1_1network_1_1data_1_1_payload-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.data.Payload Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class represents a single payload that is sent to the server.  
+ <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="memItemLeft" align="right" valign="top">override string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">ToString</a> ()</td></tr>
+<tr class="memdesc:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns a string representation of the payload.  <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">More...</a><br /></td></tr>
+<tr class="separator:ad81cd8c8c44f80a75d0fbea3aa8d0148"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:acd1a2d92945c91d22c262ce7b5a75d57"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">ParseToJson</a> ()</td></tr>
+<tr class="memdesc:acd1a2d92945c91d22c262ce7b5a75d57"><td class="mdescLeft">&#160;</td><td class="mdescRight">Parses (converts) the payload into JSON format.  <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">More...</a><br /></td></tr>
+<tr class="separator:acd1a2d92945c91d22c262ce7b5a75d57"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-static-methods" name="pub-static-methods"></a>
+Static Public Member Functions</h2></td></tr>
+<tr class="memitem:a481fbe5952888d2dd7b6df0ff67ef056"><td class="memItemLeft" align="right" valign="top">static string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">ParseToJson</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a481fbe5952888d2dd7b6df0ff67ef056"><td class="mdescLeft">&#160;</td><td class="mdescRight">Serializes a given payload into JSON format.  <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056">More...</a><br /></td></tr>
+<tr class="separator:a481fbe5952888d2dd7b6df0ff67ef056"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a>
+Properties</h2></td></tr>
+<tr class="memitem:ab1d3b30416e011f29b7e82f284495f65"><td class="memItemLeft" align="right" valign="top"><a id="ab1d3b30416e011f29b7e82f284495f65" name="ab1d3b30416e011f29b7e82f284495f65"></a>
+string?&#160;</td><td class="memItemRight" valign="bottom"><b>UserName</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:ab1d3b30416e011f29b7e82f284495f65"><td class="mdescLeft">&#160;</td><td class="mdescRight">Username of the currently logged user. <br /></td></tr>
+<tr class="separator:ab1d3b30416e011f29b7e82f284495f65"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="memItemLeft" align="right" valign="top"><a id="acbcdcd13f4cfd6074cabcbe1f39e9b72" name="acbcdcd13f4cfd6074cabcbe1f39e9b72"></a>
+string?&#160;</td><td class="memItemRight" valign="bottom"><b>HostName</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="mdescLeft">&#160;</td><td class="mdescRight">Hostname of the pc. <br /></td></tr>
+<tr class="separator:acbcdcd13f4cfd6074cabcbe1f39e9b72"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ad79e14f0c9936a6e6581d72fca767297"><td class="memItemLeft" align="right" valign="top"><a id="ad79e14f0c9936a6e6581d72fca767297" name="ad79e14f0c9936a6e6581d72fca767297"></a>
+string?&#160;</td><td class="memItemRight" valign="bottom"><b>TimeStamp</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:ad79e14f0c9936a6e6581d72fca767297"><td class="mdescLeft">&#160;</td><td class="mdescRight">Timestamp (when a debugger was plugged/unplugged). <br /></td></tr>
+<tr class="separator:ad79e14f0c9936a6e6581d72fca767297"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ad8926696e666228bfb9164fcbf430da5"><td class="memItemLeft" align="right" valign="top"><a id="ad8926696e666228bfb9164fcbf430da5" name="ad8926696e666228bfb9164fcbf430da5"></a>
+<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a>?&#160;</td><td class="memItemRight" valign="bottom"><b>HeadDevice</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:ad8926696e666228bfb9164fcbf430da5"><td class="mdescLeft">&#160;</td><td class="mdescRight">Information about the head of the debugger. <br /></td></tr>
+<tr class="separator:ad8926696e666228bfb9164fcbf430da5"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a82af1fdf887d86f81acfec3b51936208"><td class="memItemLeft" align="right" valign="top"><a id="a82af1fdf887d86f81acfec3b51936208" name="a82af1fdf887d86f81acfec3b51936208"></a>
+<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a>?&#160;</td><td class="memItemRight" valign="bottom"><b>BodyDevice</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:a82af1fdf887d86f81acfec3b51936208"><td class="mdescLeft">&#160;</td><td class="mdescRight">Information about the body of the debugger. <br /></td></tr>
+<tr class="separator:a82af1fdf887d86f81acfec3b51936208"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a47489fcc58ebc325d36de38db4d4e481"><td class="memItemLeft" align="right" valign="top"><a id="a47489fcc58ebc325d36de38db4d4e481" name="a47489fcc58ebc325d36de38db4d4e481"></a>
+<a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">ConnectionStatus</a>&#160;</td><td class="memItemRight" valign="bottom"><b>Status</b><code> [get, set]</code></td></tr>
+<tr class="memdesc:a47489fcc58ebc325d36de38db4d4e481"><td class="mdescLeft">&#160;</td><td class="mdescRight">Status of the debugger (connected/disconnected). <br /></td></tr>
+<tr class="separator:a47489fcc58ebc325d36de38db4d4e481"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class represents a single payload that is sent to the server. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="acd1a2d92945c91d22c262ce7b5a75d57" name="acd1a2d92945c91d22c262ce7b5a75d57"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#acd1a2d92945c91d22c262ce7b5a75d57">&#9670;&nbsp;</a></span>ParseToJson() <span class="overload">[1/2]</span></h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">string LDClient.network.data.Payload.ParseToJson </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Parses (converts) the payload into JSON format. </p>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<a id="a481fbe5952888d2dd7b6df0ff67ef056" name="a481fbe5952888d2dd7b6df0ff67ef056"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a481fbe5952888d2dd7b6df0ff67ef056">&#9670;&nbsp;</a></span>ParseToJson() <span class="overload">[2/2]</span></h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">static string LDClient.network.data.Payload.ParseToJson </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a>&#160;</td>
+          <td class="paramname"><em>payload</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">static</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Serializes a given payload into JSON format. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">payload</td><td>payload to be serialized into JSON</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<a id="ad81cd8c8c44f80a75d0fbea3aa8d0148" name="ad81cd8c8c44f80a75d0fbea3aa8d0148"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad81cd8c8c44f80a75d0fbea3aa8d0148">&#9670;&nbsp;</a></span>ToString()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">override string LDClient.network.data.Payload.ToString </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Returns a string representation of the payload. </p>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>network/data/Payload.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js
new file mode 100644
index 0000000..f224ff5
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.js
@@ -0,0 +1,11 @@
+var class_l_d_client_1_1network_1_1data_1_1_payload =
+[
+    [ "ParseToJson", "class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57", null ],
+    [ "ToString", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148", null ],
+    [ "BodyDevice", "class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208", null ],
+    [ "HeadDevice", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5", null ],
+    [ "HostName", "class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72", null ],
+    [ "Status", "class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481", null ],
+    [ "TimeStamp", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297", null ],
+    [ "UserName", "class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html
new file mode 100644
index 0000000..335832e
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils-members.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1_file_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.utils.FileUtils Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">LDClient.utils.FileUtils</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">ReadFileAllLines</a>(string file)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">LDClient.utils.FileUtils</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
new file mode 100644
index 0000000..1d00aa1
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
@@ -0,0 +1,150 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils.FileUtils Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1_file_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="class_l_d_client_1_1utils_1_1_file_utils-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils.FileUtils Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations.  
+ <a href="class_l_d_client_1_1utils_1_1_file_utils.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a411ef16d3be50fea59473b160d801737"><td class="memItemLeft" align="right" valign="top">string[]&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">ReadFileAllLines</a> (string file)</td></tr>
+<tr class="memdesc:a411ef16d3be50fea59473b160d801737"><td class="mdescLeft">&#160;</td><td class="mdescRight">Reads all lines of a files and returns them as a array.  <a href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">More...</a><br /></td></tr>
+<tr class="separator:a411ef16d3be50fea59473b160d801737"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ae4d668d0e5850831680c8793cecd89a3"><td class="memItemLeft" align="right" valign="top">string[]&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a> (string file)</td></tr>
+<tr class="memdesc:ae4d668d0e5850831680c8793cecd89a3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Reads all lines of a files and returns them as a array.  <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">More...</a><br /></td></tr>
+<tr class="separator:ae4d668d0e5850831680c8793cecd89a3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a411ef16d3be50fea59473b160d801737" name="a411ef16d3be50fea59473b160d801737"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a411ef16d3be50fea59473b160d801737">&#9670;&nbsp;</a></span>ReadFileAllLines()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">string[] LDClient.utils.FileUtils.ReadFileAllLines </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>file</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Reads all lines of a files and returns them as a array. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">file</td><td>path to the file</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>all the lines of the file (as an array)</dd></dl>
+
+<p>Implements <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>utils/FileUtils.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js
new file mode 100644
index 0000000..5df8573
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.js
@@ -0,0 +1,4 @@
+var class_l_d_client_1_1utils_1_1_file_utils =
+[
+    [ "ReadFileAllLines", "class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html
new file mode 100644
index 0000000..db6df3e
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.utils.loggers.ALogger Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">ALogger</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a>(string message, LogType logType)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr bgcolor="#f0f0f0" class="even"><td class="entry"><b>CreateLog</b>(string message) (defined in <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">pure virtual</span></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">Current</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">Dispose</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a>(Exception e)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">Flush</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a>(Exception? ex)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
new file mode 100644
index 0000000..09a6a5e
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
@@ -0,0 +1,395 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils.loggers.ALogger Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#pro-methods">Protected Member Functions</a> &#124;
+<a href="#properties">Properties</a> &#124;
+<a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils.loggers.ALogger Class Reference<span class="mlabels"><span class="mlabel">abstract</span></span></div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern  
+ <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:ac8f52ab4e431a47107d30db51615237e"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a> (string message)</td></tr>
+<tr class="memdesc:ac8f52ab4e431a47107d30db51615237e"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Info identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">More...</a><br /></td></tr>
+<tr class="separator:ac8f52ab4e431a47107d30db51615237e"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a5c626205a03a7829c6dd195ee18d8e81"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a> (string message)</td></tr>
+<tr class="memdesc:a5c626205a03a7829c6dd195ee18d8e81"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Debug identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">More...</a><br /></td></tr>
+<tr class="separator:a5c626205a03a7829c6dd195ee18d8e81"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a7f041d300e6d06dc58f969c4c0afd504"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a> (string message)</td></tr>
+<tr class="memdesc:a7f041d300e6d06dc58f969c4c0afd504"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Error identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">More...</a><br /></td></tr>
+<tr class="separator:a7f041d300e6d06dc58f969c4c0afd504"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8be19175b75b9e09ce307a251a0358f2"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a> (Exception e)</td></tr>
+<tr class="memdesc:a8be19175b75b9e09ce307a251a0358f2"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log from the catched exception  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">More...</a><br /></td></tr>
+<tr class="separator:a8be19175b75b9e09ce307a251a0358f2"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a08558ed797aa0cf2efbba7ff6c868453"><td class="memItemLeft" align="right" valign="top">override string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a> ()</td></tr>
+<tr class="memdesc:a08558ed797aa0cf2efbba7ff6c868453"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new string info about current logger configuration  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">More...</a><br /></td></tr>
+<tr class="separator:a08558ed797aa0cf2efbba7ff6c868453"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8cb167cc304b1fb7fc581271f1465ca4"><td class="memItemLeft" align="right" valign="top"><a id="a8cb167cc304b1fb7fc581271f1465ca4" name="a8cb167cc304b1fb7fc581271f1465ca4"></a>
+void&#160;</td><td class="memItemRight" valign="bottom"><b>Flush</b> ()</td></tr>
+<tr class="memdesc:a8cb167cc304b1fb7fc581271f1465ca4"><td class="mdescLeft">&#160;</td><td class="mdescRight">Waits for the logger to finish the logging <br /></td></tr>
+<tr class="separator:a8cb167cc304b1fb7fc581271f1465ca4"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a60bb1691cc7cc543d94a34da86b91433"><td class="memItemLeft" align="right" valign="top"><a id="a60bb1691cc7cc543d94a34da86b91433" name="a60bb1691cc7cc543d94a34da86b91433"></a>
+void&#160;</td><td class="memItemRight" valign="bottom"><b>Dispose</b> ()</td></tr>
+<tr class="memdesc:a60bb1691cc7cc543d94a34da86b91433"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function stops the logger thread <br /></td></tr>
+<tr class="separator:a60bb1691cc7cc543d94a34da86b91433"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a>
+Protected Member Functions</h2></td></tr>
+<tr class="memitem:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="memItemLeft" align="right" valign="top"><a id="a0a42ccc73ba8693a90da6a3a9bfca8f3" name="a0a42ccc73ba8693a90da6a3a9bfca8f3"></a>
+&#160;</td><td class="memItemRight" valign="bottom"><b>ALogger</b> ()</td></tr>
+<tr class="memdesc:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Singleton constructor that initialized and starts the logger with arguments parsed by the config loader <br /></td></tr>
+<tr class="separator:a0a42ccc73ba8693a90da6a3a9bfca8f3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a0af186e371cd3325a1013bf219c8802e"><td class="memItemLeft" align="right" valign="top">abstract void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0af186e371cd3325a1013bf219c8802e">CreateLog</a> (string message)</td></tr>
+<tr class="separator:a0af186e371cd3325a1013bf219c8802e"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a06814df4864ce7784647d15966eb1b4b"><td class="memItemLeft" align="right" valign="top">virtual string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a> (string message, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> logType)</td></tr>
+<tr class="memdesc:a06814df4864ce7784647d15966eb1b4b"><td class="mdescLeft">&#160;</td><td class="mdescRight">Composes the log with actual timestamp, log type and its main message  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">More...</a><br /></td></tr>
+<tr class="separator:a06814df4864ce7784647d15966eb1b4b"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6bcc70a878ba68230afcdcac45855eea"><td class="memItemLeft" align="right" valign="top">virtual string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a> (Exception? ex)</td></tr>
+<tr class="memdesc:a6bcc70a878ba68230afcdcac45855eea"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function creates log from the catched exception  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">More...</a><br /></td></tr>
+<tr class="separator:a6bcc70a878ba68230afcdcac45855eea"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a>
+Properties</h2></td></tr>
+<tr class="memitem:a614d0574928fa3f08452e753a263236f"><td class="memItemLeft" align="right" valign="top"><a id="a614d0574928fa3f08452e753a263236f" name="a614d0574928fa3f08452e753a263236f"></a>
+static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a>&#160;</td><td class="memItemRight" valign="bottom"><b>Current</b><code> [get]</code></td></tr>
+<tr class="memdesc:a614d0574928fa3f08452e753a263236f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Instance of the current logger type <br /></td></tr>
+<tr class="separator:a614d0574928fa3f08452e753a263236f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a06814df4864ce7784647d15966eb1b4b" name="a06814df4864ce7784647d15966eb1b4b"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a06814df4864ce7784647d15966eb1b4b">&#9670;&nbsp;</a></span>ComposeLogRow()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual string LDClient.utils.loggers.ALogger.ComposeLogRow </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a>&#160;</td>
+          <td class="paramname"><em>logType</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Composes the log with actual timestamp, log type and its main message </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>main message of the log</td></tr>
+    <tr><td class="paramname">logType</td><td>Type of the logged message</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<a id="a0af186e371cd3325a1013bf219c8802e" name="a0af186e371cd3325a1013bf219c8802e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a0af186e371cd3325a1013bf219c8802e">&#9670;&nbsp;</a></span>CreateLog()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">abstract void LDClient.utils.loggers.ALogger.CreateLog </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">pure virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a>.</p>
+
+</div>
+</div>
+<a id="a5c626205a03a7829c6dd195ee18d8e81" name="a5c626205a03a7829c6dd195ee18d8e81"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a5c626205a03a7829c6dd195ee18d8e81">&#9670;&nbsp;</a></span>Debug()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void LDClient.utils.loggers.ALogger.Debug </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates new log with Debug identifier </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<a id="a8be19175b75b9e09ce307a251a0358f2" name="a8be19175b75b9e09ce307a251a0358f2"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a8be19175b75b9e09ce307a251a0358f2">&#9670;&nbsp;</a></span>Error() <span class="overload">[1/2]</span></h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void LDClient.utils.loggers.ALogger.Error </td>
+          <td>(</td>
+          <td class="paramtype">Exception&#160;</td>
+          <td class="paramname"><em>e</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates new log from the catched exception </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">e</td><td>catched exception tha should be logged</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<a id="a7f041d300e6d06dc58f969c4c0afd504" name="a7f041d300e6d06dc58f969c4c0afd504"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a7f041d300e6d06dc58f969c4c0afd504">&#9670;&nbsp;</a></span>Error() <span class="overload">[2/2]</span></h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void LDClient.utils.loggers.ALogger.Error </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates new log with Error identifier </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<a id="ac8f52ab4e431a47107d30db51615237e" name="ac8f52ab4e431a47107d30db51615237e"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ac8f52ab4e431a47107d30db51615237e">&#9670;&nbsp;</a></span>Info()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void LDClient.utils.loggers.ALogger.Info </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates new log with Info identifier </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>Desired message to be logged</td></tr>
+  </table>
+  </dd>
+</dl>
+
+</div>
+</div>
+<a id="a08558ed797aa0cf2efbba7ff6c868453" name="a08558ed797aa0cf2efbba7ff6c868453"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a08558ed797aa0cf2efbba7ff6c868453">&#9670;&nbsp;</a></span>ToString()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">override string LDClient.utils.loggers.ALogger.ToString </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Creates new string info about current logger configuration </p>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<a id="a6bcc70a878ba68230afcdcac45855eea" name="a6bcc70a878ba68230afcdcac45855eea"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a6bcc70a878ba68230afcdcac45855eea">&#9670;&nbsp;</a></span>UnwrapExceptionMessages()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">virtual string LDClient.utils.loggers.ALogger.UnwrapExceptionMessages </td>
+          <td>(</td>
+          <td class="paramtype">Exception?&#160;</td>
+          <td class="paramname"><em>ex</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Function creates log from the catched exception </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">ex</td><td>catched exception tha should be logged</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>utils/loggers/ALogger.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js
new file mode 100644
index 0000000..5a17264
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.js
@@ -0,0 +1,13 @@
+var class_l_d_client_1_1utils_1_1loggers_1_1_a_logger =
+[
+    [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3", null ],
+    [ "ComposeLogRow", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b", null ],
+    [ "Debug", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81", null ],
+    [ "Dispose", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433", null ],
+    [ "Error", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2", null ],
+    [ "Error", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504", null ],
+    [ "Flush", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4", null ],
+    [ "Info", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e", null ],
+    [ "ToString", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453", null ],
+    [ "UnwrapExceptionMessages", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html
new file mode 100644
index 0000000..010d1a1
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html
@@ -0,0 +1,113 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.utils.loggers.ConsoleLogger Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">LDClient.utils.loggers.ConsoleLogger</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">ALogger</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a>(string message, LogType logType)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">CreateLog</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">LDClient.utils.loggers.ConsoleLogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">Current</a></td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">static</span></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">Dispose</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a>(Exception e)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">Flush</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a>(string message)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a>()</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a>(Exception? ex)</td><td class="entry"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td><td class="entry"><span class="mlabel">protected</span><span class="mlabel">virtual</span></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
new file mode 100644
index 0000000..05a15b8
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
@@ -0,0 +1,194 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils.loggers.ConsoleLogger Class Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pro-methods">Protected Member Functions</a> &#124;
+<a href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils.loggers.ConsoleLogger Class Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pro-methods" name="pro-methods"></a>
+Protected Member Functions</h2></td></tr>
+<tr class="memitem:aca7d10ea902e782733adaa53713f66b7"><td class="memItemLeft" align="right" valign="top">override void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">CreateLog</a> (string message)</td></tr>
+<tr class="memdesc:aca7d10ea902e782733adaa53713f66b7"><td class="mdescLeft">&#160;</td><td class="mdescRight">CreateLog function for the <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> prints the desired message to the console  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">More...</a><br /></td></tr>
+<tr class="separator:aca7d10ea902e782733adaa53713f66b7"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/>&#160;Protected Member Functions inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr>
+<tr class="memitem:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a0a42ccc73ba8693a90da6a3a9bfca8f3" name="a0a42ccc73ba8693a90da6a3a9bfca8f3"></a>
+&#160;</td><td class="memItemRight" valign="bottom"><b>ALogger</b> ()</td></tr>
+<tr class="memdesc:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Singleton constructor that initialized and starts the logger with arguments parsed by the config loader <br /></td></tr>
+<tr class="separator:a0a42ccc73ba8693a90da6a3a9bfca8f3 inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a0af186e371cd3325a1013bf219c8802e inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">abstract void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0af186e371cd3325a1013bf219c8802e">CreateLog</a> (string message)</td></tr>
+<tr class="separator:a0af186e371cd3325a1013bf219c8802e inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">virtual string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">ComposeLogRow</a> (string message, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> logType)</td></tr>
+<tr class="memdesc:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Composes the log with actual timestamp, log type and its main message  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">More...</a><br /></td></tr>
+<tr class="separator:a06814df4864ce7784647d15966eb1b4b inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">virtual string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">UnwrapExceptionMessages</a> (Exception? ex)</td></tr>
+<tr class="memdesc:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function creates log from the catched exception  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">More...</a><br /></td></tr>
+<tr class="separator:a6bcc70a878ba68230afcdcac45855eea inherit pro_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="inherited" name="inherited"></a>
+Additional Inherited Members</h2></td></tr>
+<tr class="inherit_header pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/>&#160;Public Member Functions inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr>
+<tr class="memitem:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">Info</a> (string message)</td></tr>
+<tr class="memdesc:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Info identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">More...</a><br /></td></tr>
+<tr class="separator:ac8f52ab4e431a47107d30db51615237e inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">Debug</a> (string message)</td></tr>
+<tr class="memdesc:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Debug identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">More...</a><br /></td></tr>
+<tr class="separator:a5c626205a03a7829c6dd195ee18d8e81 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">Error</a> (string message)</td></tr>
+<tr class="memdesc:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log with Error identifier  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">More...</a><br /></td></tr>
+<tr class="separator:a7f041d300e6d06dc58f969c4c0afd504 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">Error</a> (Exception e)</td></tr>
+<tr class="memdesc:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new log from the catched exception  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2">More...</a><br /></td></tr>
+<tr class="separator:a8be19175b75b9e09ce307a251a0358f2 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top">override string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">ToString</a> ()</td></tr>
+<tr class="memdesc:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Creates new string info about current logger configuration  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">More...</a><br /></td></tr>
+<tr class="separator:a08558ed797aa0cf2efbba7ff6c868453 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a8cb167cc304b1fb7fc581271f1465ca4" name="a8cb167cc304b1fb7fc581271f1465ca4"></a>
+void&#160;</td><td class="memItemRight" valign="bottom"><b>Flush</b> ()</td></tr>
+<tr class="memdesc:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Waits for the logger to finish the logging <br /></td></tr>
+<tr class="separator:a8cb167cc304b1fb7fc581271f1465ca4 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a60bb1691cc7cc543d94a34da86b91433" name="a60bb1691cc7cc543d94a34da86b91433"></a>
+void&#160;</td><td class="memItemRight" valign="bottom"><b>Dispose</b> ()</td></tr>
+<tr class="memdesc:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Function stops the logger thread <br /></td></tr>
+<tr class="separator:a60bb1691cc7cc543d94a34da86b91433 inherit pub_methods_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="inherit_header properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td colspan="2" onclick="javascript:toggleInherit('properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger')"><img src="closed.png" alt="-"/>&#160;Properties inherited from <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a></td></tr>
+<tr class="memitem:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memItemLeft" align="right" valign="top"><a id="a614d0574928fa3f08452e753a263236f" name="a614d0574928fa3f08452e753a263236f"></a>
+static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a>&#160;</td><td class="memItemRight" valign="bottom"><b>Current</b><code> [get]</code></td></tr>
+<tr class="memdesc:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="mdescLeft">&#160;</td><td class="mdescRight">Instance of the current logger type <br /></td></tr>
+<tr class="separator:a614d0574928fa3f08452e753a263236f inherit properties_class_l_d_client_1_1utils_1_1loggers_1_1_a_logger"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<h2 class="groupheader">Member Function Documentation</h2>
+<a id="aca7d10ea902e782733adaa53713f66b7" name="aca7d10ea902e782733adaa53713f66b7"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#aca7d10ea902e782733adaa53713f66b7">&#9670;&nbsp;</a></span>CreateLog()</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">override void LDClient.utils.loggers.ConsoleLogger.CreateLog </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>message</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">protected</span><span class="mlabel">virtual</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>CreateLog function for the <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> prints the desired message to the console </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">message</td><td>Desired message to be printed</td></tr>
+  </table>
+  </dd>
+</dl>
+
+<p>Implements <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">LDClient.utils.loggers.ALogger</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this class was generated from the following file:<ul>
+<li>utils/loggers/ConsoleLogger.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li><li class="navelem"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js
new file mode 100644
index 0000000..ba870f6
--- /dev/null
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.js
@@ -0,0 +1,4 @@
+var class_l_d_client_1_1utils_1_1loggers_1_1_console_logger =
+[
+    [ "CreateLog", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/classes.html b/ld_client/doc/pdoc/classes.html
new file mode 100644
index 0000000..68fd64c
--- /dev/null
+++ b/ld_client/doc/pdoc/classes.html
@@ -0,0 +1,122 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Index</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('classes.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Class Index</div></div>
+</div><!--header-->
+<div class="contents">
+<div class="qindex"><a class="qindex" href="#letter_A">A</a>&#160;|&#160;<a class="qindex" href="#letter_C">C</a>&#160;|&#160;<a class="qindex" href="#letter_D">D</a>&#160;|&#160;<a class="qindex" href="#letter_F">F</a>&#160;|&#160;<a class="qindex" href="#letter_H">H</a>&#160;|&#160;<a class="qindex" href="#letter_I">I</a>&#160;|&#160;<a class="qindex" href="#letter_P">P</a></div>
+<div class="classindex">
+<dl class="classindex even">
+<dt class="alphachar"><a id="letter_A" name="letter_A">A</a></dt>
+<dd><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a> (<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">LDClient.utils.loggers</a>)</dd><dd><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd></dl>
+<dl class="classindex odd">
+<dt class="alphachar"><a id="letter_C" name="letter_C">C</a></dt>
+<dd><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a> (<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">LDClient.utils.loggers</a>)</dd></dl>
+<dl class="classindex even">
+<dt class="alphachar"><a id="letter_D" name="letter_D">D</a></dt>
+<dd><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a> (<a class="el" href="namespace_l_d_client_1_1network_1_1data.html">LDClient.network.data</a>)</dd></dl>
+<dl class="classindex odd">
+<dt class="alphachar"><a id="letter_F" name="letter_F">F</a></dt>
+<dd><a class="el" href="class_file_logger.html">FileLogger</a></dd><dd><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a> (<a class="el" href="namespace_l_d_client_1_1utils.html">LDClient.utils</a>)</dd></dl>
+<dl class="classindex even">
+<dt class="alphachar"><a id="letter_H" name="letter_H">H</a></dt>
+<dd><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd></dl>
+<dl class="classindex odd">
+<dt class="alphachar"><a id="letter_I" name="letter_I">I</a></dt>
+<dd><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a> (<a class="el" href="namespace_l_d_client_1_1utils.html">LDClient.utils</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a> (<a class="el" href="namespace_l_d_client_1_1network.html">LDClient.network</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd></dl>
+<dl class="classindex even">
+<dt class="alphachar"><a id="letter_P" name="letter_P">P</a></dt>
+<dd><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> (<a class="el" href="namespace_l_d_client_1_1network_1_1data.html">LDClient.network.data</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd><dd><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a> (<a class="el" href="namespace_l_d_client_1_1detection.html">LDClient.detection</a>)</dd></dl>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/closed.png b/ld_client/doc/pdoc/closed.png
new file mode 100644
index 0000000000000000000000000000000000000000..98cc2c909da37a6df914fbf67780eebd99c597f5
GIT binary patch
literal 132
zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{V-kvUwAr*{o@8<G4C~~x2bkCl7
zlF9slZh~6z%aUT|WfKm3{P*dDAfv<6>{^CZMh(5KoB^r_<4^zF@3)Cp&&t3hdujKf
f*?bjBoY!V+E))@{xMcbjXe@)LtDnm{r-UW|*e5JT

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html b/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html
new file mode 100644
index 0000000..747f241
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_08b4fbe3d60d6d41472a6a22c750d4c7.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: network/data Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_08b4fbe3d60d6d41472a6a22c750d4c7.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">data Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_c901c14b65aa229498a52b725b3d4a2c.html">network</a></li><li class="navelem"><a class="el" href="dir_08b4fbe3d60d6d41472a6a22c750d4c7.html">data</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html b/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html
new file mode 100644
index 0000000..779f3da
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_43724e81dd40e09f32417973865cdd64.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: obj Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_43724e81dd40e09f32417973865cdd64.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">obj Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html b/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html
new file mode 100644
index 0000000..b05309c
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_7212c827820ef56532d3599ed27e3aff.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: obj/Debug/net6.0 Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_7212c827820ef56532d3599ed27e3aff.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">net6.0 Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li><li class="navelem"><a class="el" href="dir_a71c3b2ad23b9ff58220dd012d201987.html">Debug</a></li><li class="navelem"><a class="el" href="dir_7212c827820ef56532d3599ed27e3aff.html">net6.0</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html b/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html
new file mode 100644
index 0000000..9c95957
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_754926843367c7eee8b48719e3f14adf.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: utils/loggers Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_754926843367c7eee8b48719e3f14adf.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">loggers Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html">utils</a></li><li class="navelem"><a class="el" href="dir_754926843367c7eee8b48719e3f14adf.html">loggers</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html b/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html
new file mode 100644
index 0000000..3703383
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_a71c3b2ad23b9ff58220dd012d201987.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: obj/Debug Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_a71c3b2ad23b9ff58220dd012d201987.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Debug Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_7212c827820ef56532d3599ed27e3aff.html">net6.0</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_43724e81dd40e09f32417973865cdd64.html">obj</a></li><li class="navelem"><a class="el" href="dir_a71c3b2ad23b9ff58220dd012d201987.html">Debug</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html b/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html
new file mode 100644
index 0000000..58822f4
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: detection Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">detection Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_ac890e7e6f46de9885ef93d0f3a1cb4b.html">detection</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html b/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html
new file mode 100644
index 0000000..ae982de
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_c901c14b65aa229498a52b725b3d4a2c.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: network Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_c901c14b65aa229498a52b725b3d4a2c.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">network Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_08b4fbe3d60d6d41472a6a22c750d4c7.html">data</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_c901c14b65aa229498a52b725b3d4a2c.html">network</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html b/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html
new file mode 100644
index 0000000..fb7a76a
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: utils Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">utils Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_754926843367c7eee8b48719e3f14adf.html">loggers</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_cbdb8362360e11eafe2fa3bc74cf0ffd.html">utils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/doc.png b/ld_client/doc/pdoc/doc.png
new file mode 100644
index 0000000000000000000000000000000000000000..17edabff95f7b8da13c9516a04efe05493c29501
GIT binary patch
literal 746
zcmV<G0u}v<P)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz00089Nkl<ZcmeI5
zO;1x>7=@pnbNXRFEm&G8P!&WHG=d)>K?YZ1bzou)2{$))<VZ%w8AHp|fq%mP;4ffy
zZ-fC6h(S;T@^On$pg;?)``rZ-=s7qr4DR5hE4!!NdDmX=TJJeiSGimUI5QXkXNfZ>
zumDct!>4SyxL;zgaG>wy`^Hv*+}0kUfCrz~BCOViSb$_*&;{TGGn2^x9K*!Sf0=lV
zpP=7O;GA0*Jm*tTYj$IoXvimpnV4S1Z5f$p*f$Db2iq2zrVGQUz~yq`ahn7ck(|CE
z7Gz;%OP~J6)tEZWDzjhL9h2hdfoU2)Nd%T<5Kt;Y0XLt&<@6pQx!n<GayH9yHg8K}
z>w*5`@bq#?l*?3z{Hlzoc=Pr>oB5(9i6~_&-}A(4{Q$>c>%rV&E|a(r&;?i5cQB=}
zYSDU5nXG)NS4HEs0it2AHe2>shCyr7`6@4*6{r@8fXR<pt)Tx_l7FX`b+T&0J~3Ac
zDisC2f48s?Pz6U1j(Y#7FGXj244=p1VQ-4TfmZrD8|c58q%jdB67*815?3si0IJ}q
zK#I#XHom~r+!`&75xy*K>bTA?=IFVWAQJL&H5H{)DpM#{W(GL+Idzf^)uRV@oB8u$
z8v{MfJbTiiRg4bza<41N<zz(9MkMF~u!W-n>Azrl{=3fl_D+$t+^!xlQ8S}{UtY`e
z;;&9UhyZqQRN%2pot{*Ei0*4~hSF_3AH2@fKU!$NSflS>{@tZpDT4`M2WRTTVH+D?
z)GFlEGGHe?koB}i|1w45!BF}N_q&^HJ&-tyR{(afC6H7|aml|tBBbv}55C5DNP8p3
z)~jLEO4Z&2hZmP^i-e%(@d!(E|KRafiU8Q5u(wU((j8un3<FfbmLT1ma;4wB2Ka6K
c|6iFu0IFBSu=gW%4*&oF07*qoM6N<$f>OR*Hvj+t

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/doxygen.css b/ld_client/doc/pdoc/doxygen.css
new file mode 100644
index 0000000..2010785
--- /dev/null
+++ b/ld_client/doc/pdoc/doxygen.css
@@ -0,0 +1,1841 @@
+/* The standard CSS for doxygen 1.9.4 */
+
+body, table, div, p, dl {
+	font: 400 14px/22px Roboto,sans-serif;
+}
+
+p.reference, p.definition {
+	font: 400 14px/22px Roboto,sans-serif;
+}
+
+/* @group Heading Levels */
+
+h1.groupheader {
+	font-size: 150%;
+}
+
+.title {
+	font: 400 14px/28px Roboto,sans-serif;
+	font-size: 150%;
+	font-weight: bold;
+	margin: 10px 2px;
+}
+
+h2.groupheader {
+	border-bottom: 1px solid #879ECB;
+	color: #354C7B;
+	font-size: 150%;
+	font-weight: normal;
+	margin-top: 1.75em;
+	padding-top: 8px;
+	padding-bottom: 4px;
+	width: 100%;
+}
+
+h3.groupheader {
+	font-size: 100%;
+}
+
+h1, h2, h3, h4, h5, h6 {
+	-webkit-transition: text-shadow 0.5s linear;
+	-moz-transition: text-shadow 0.5s linear;
+	-ms-transition: text-shadow 0.5s linear;
+	-o-transition: text-shadow 0.5s linear;
+	transition: text-shadow 0.5s linear;
+	margin-right: 15px;
+}
+
+h1.glow, h2.glow, h3.glow, h4.glow, h5.glow, h6.glow {
+	text-shadow: 0 0 15px cyan;
+}
+
+dt {
+	font-weight: bold;
+}
+
+ul.multicol {
+	-moz-column-gap: 1em;
+	-webkit-column-gap: 1em;
+	column-gap: 1em;
+	-moz-column-count: 3;
+	-webkit-column-count: 3;
+	column-count: 3;
+}
+
+p.startli, p.startdd {
+	margin-top: 2px;
+}
+
+th p.starttd, th p.intertd, th p.endtd {
+        font-size: 100%;
+        font-weight: 700;
+}
+
+p.starttd {
+	margin-top: 0px;
+}
+
+p.endli {
+	margin-bottom: 0px;
+}
+
+p.enddd {
+	margin-bottom: 4px;
+}
+
+p.endtd {
+	margin-bottom: 2px;
+}
+
+p.interli {
+}
+
+p.interdd {
+}
+
+p.intertd {
+}
+
+/* @end */
+
+caption {
+	font-weight: bold;
+}
+
+span.legend {
+	font-size: 70%;
+	text-align: center;
+}
+
+h3.version {
+	font-size: 90%;
+	text-align: center;
+}
+
+div.navtab {
+	border-right: 1px solid #A3B4D7;
+	padding-right: 15px;
+	text-align: right;
+	line-height: 110%;
+}
+
+div.navtab table {
+	border-spacing: 0;
+}
+
+td.navtab {
+	padding-right: 6px;
+	padding-left: 6px;
+}
+td.navtabHL {
+	background-image: url('tab_a.png');
+	background-repeat:repeat-x;
+	padding-right: 6px;
+	padding-left: 6px;
+}
+
+td.navtabHL a, td.navtabHL a:visited {
+	color: #fff;
+	text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+a.navtab {
+	font-weight: bold;
+}
+
+div.qindex{
+	text-align: center;
+	width: 100%;
+	line-height: 140%;
+	font-size: 130%;
+	color: #A0A0A0;
+}
+
+dt.alphachar{
+	font-size: 180%;
+	font-weight: bold;
+}
+
+.alphachar a{
+	color: black;
+}
+
+.alphachar a:hover, .alphachar a:visited{
+	text-decoration: none;
+}
+
+.classindex dl {
+	padding: 25px;
+	column-count:1
+}
+
+.classindex dd {
+	display:inline-block;
+	margin-left: 50px;
+	width: 90%;
+	line-height: 1.15em;
+}
+
+.classindex dl.odd {
+	background-color: #F8F9FC;
+}
+
+@media(min-width: 1120px) {
+	.classindex dl {
+		column-count:2
+	}
+}
+
+@media(min-width: 1320px) {
+	.classindex dl {
+		column-count:3
+	}
+}
+
+
+/* @group Link Styling */
+
+a {
+	color: #3D578C;
+	font-weight: normal;
+	text-decoration: none;
+}
+
+.contents a:visited {
+	color: #4665A2;
+}
+
+a:hover {
+	text-decoration: underline;
+}
+
+.contents a.qindexHL:visited {
+        color: #FFFFFF;
+}
+
+a.el {
+	font-weight: bold;
+}
+
+a.elRef {
+}
+
+a.code, a.code:visited, a.line, a.line:visited {
+	color: #4665A2; 
+}
+
+a.codeRef, a.codeRef:visited, a.lineRef, a.lineRef:visited {
+	color: #4665A2; 
+}
+
+a.code.hl_class { /* style for links to class names in code snippets */ }
+a.code.hl_struct { /* style for links to struct names in code snippets */ }
+a.code.hl_union { /* style for links to union names in code snippets */ }
+a.code.hl_interface { /* style for links to interface names in code snippets */ }
+a.code.hl_protocol { /* style for links to protocol names in code snippets */ }
+a.code.hl_category { /* style for links to category names in code snippets */ }
+a.code.hl_exception { /* style for links to exception names in code snippets */ }
+a.code.hl_service { /* style for links to service names in code snippets */ }
+a.code.hl_singleton { /* style for links to singleton names in code snippets */ }
+a.code.hl_concept { /* style for links to concept names in code snippets */ }
+a.code.hl_namespace { /* style for links to namespace names in code snippets */ }
+a.code.hl_package { /* style for links to package names in code snippets */ }
+a.code.hl_define { /* style for links to macro names in code snippets */ }
+a.code.hl_function { /* style for links to function names in code snippets */ }
+a.code.hl_variable { /* style for links to variable names in code snippets */ }
+a.code.hl_typedef { /* style for links to typedef names in code snippets */ }
+a.code.hl_enumvalue { /* style for links to enum value names in code snippets */ }
+a.code.hl_enumeration { /* style for links to enumeration names in code snippets */ }
+a.code.hl_signal { /* style for links to Qt signal names in code snippets */ }
+a.code.hl_slot { /* style for links to Qt slot names in code snippets */ }
+a.code.hl_friend { /* style for links to friend names in code snippets */ }
+a.code.hl_dcop { /* style for links to KDE3 DCOP names in code snippets */ }
+a.code.hl_property { /* style for links to property names in code snippets */ }
+a.code.hl_event { /* style for links to event names in code snippets */ }
+a.code.hl_sequence { /* style for links to sequence names in code snippets */ }
+a.code.hl_dictionary { /* style for links to dictionary names in code snippets */ }
+
+/* @end */
+
+dl.el {
+	margin-left: -1cm;
+}
+
+ul {
+  overflow: visible;
+}
+
+#side-nav ul {
+  overflow: visible; /* reset ul rule for scroll bar in GENERATE_TREEVIEW window */
+}
+
+#main-nav ul {
+  overflow: visible; /* reset ul rule for the navigation bar drop down lists */
+}
+
+.fragment {
+  text-align: left;
+  direction: ltr;
+  overflow-x: auto; /*Fixed: fragment lines overlap floating elements*/
+  overflow-y: hidden;
+}
+
+pre.fragment {
+        border: 1px solid #C4CFE5;
+        background-color: #FBFCFD;
+        padding: 4px 6px;
+        margin: 4px 8px 4px 2px;
+        overflow: auto;
+        word-wrap: break-word;
+        font-size:  9pt;
+        line-height: 125%;
+        font-family: monospace, fixed;
+        font-size: 105%;
+}
+
+div.fragment {
+  padding: 0 0 1px 0; /*Fixed: last line underline overlap border*/
+  margin: 4px 8px 4px 2px;
+	background-color: #FBFCFD;
+	border: 1px solid #C4CFE5;
+}
+
+div.line {
+	font-family: monospace, fixed;
+        font-size: 13px;
+	min-height: 13px;
+	line-height: 1.0;
+	text-wrap: unrestricted;
+	white-space: -moz-pre-wrap; /* Moz */
+	white-space: -pre-wrap;     /* Opera 4-6 */
+	white-space: -o-pre-wrap;   /* Opera 7 */
+	white-space: pre-wrap;      /* CSS3  */
+	word-wrap: break-word;      /* IE 5.5+ */
+	text-indent: -53px;
+	padding-left: 53px;
+	padding-bottom: 0px;
+	margin: 0px;
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+div.line:after {
+    content:"\000A";
+    white-space: pre;
+}
+
+div.line.glow {
+	background-color: cyan;
+	box-shadow: 0 0 10px cyan;
+}
+
+
+span.lineno {
+	padding-right: 4px;
+        margin-right: 9px;
+	text-align: right;
+	border-right: 2px solid #0F0;
+	background-color: #E8E8E8;
+        white-space: pre;
+}
+span.lineno a {
+	background-color: #D8D8D8;
+}
+
+span.lineno a:hover {
+	background-color: #C8C8C8;
+}
+
+.lineno {
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+div.ah, span.ah {
+	background-color: black;
+	font-weight: bold;
+	color: #FFFFFF;
+	margin-bottom: 3px;
+	margin-top: 3px;
+	padding: 0.2em;
+	border: solid thin #333;
+	border-radius: 0.5em;
+	-webkit-border-radius: .5em;
+	-moz-border-radius: .5em;
+	box-shadow: 2px 2px 3px #999;
+	-webkit-box-shadow: 2px 2px 3px #999;
+	-moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+	background-image: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#000),color-stop(0.3, #444));
+	background-image: -moz-linear-gradient(center top, #eee 0%, #444 40%, #000 110%);
+}
+
+div.classindex ul {
+        list-style: none;
+        padding-left: 0;
+}
+
+div.classindex span.ai {
+        display: inline-block;
+}
+
+div.groupHeader {
+	margin-left: 16px;
+	margin-top: 12px;
+	font-weight: bold;
+}
+
+div.groupText {
+	margin-left: 16px;
+	font-style: italic;
+}
+
+body {
+	background-color: white;
+	color: black;
+        margin: 0;
+}
+
+div.contents {
+	margin-top: 10px;
+	margin-left: 12px;
+	margin-right: 8px;
+}
+
+td.indexkey {
+	background-color: #EBEFF6;
+	font-weight: bold;
+	border: 1px solid #C4CFE5;
+	margin: 2px 0px 2px 0;
+	padding: 2px 10px;
+        white-space: nowrap;
+        vertical-align: top;
+}
+
+td.indexvalue {
+	background-color: #EBEFF6;
+	border: 1px solid #C4CFE5;
+	padding: 2px 10px;
+	margin: 2px 0px;
+}
+
+tr.memlist {
+	background-color: #EEF1F7;
+}
+
+p.formulaDsp {
+	text-align: center;
+}
+
+img.formulaDsp {
+	
+}
+
+img.formulaInl, img.inline {
+	vertical-align: middle;
+}
+
+div.center {
+	text-align: center;
+        margin-top: 0px;
+        margin-bottom: 0px;
+        padding: 0px;
+}
+
+div.center img {
+	border: 0px;
+}
+
+address.footer {
+	text-align: right;
+	padding-right: 12px;
+}
+
+img.footer {
+	border: 0px;
+	vertical-align: middle;
+}
+
+.compoundTemplParams {
+	color: #4665A2;
+	font-size: 80%;
+	line-height: 120%;
+}
+
+/* @group Code Colorization */
+
+span.keyword {
+	color: #008000
+}
+
+span.keywordtype {
+	color: #604020
+}
+
+span.keywordflow {
+	color: #e08000
+}
+
+span.comment {
+	color: #800000
+}
+
+span.preprocessor {
+	color: #806020
+}
+
+span.stringliteral {
+	color: #002080
+}
+
+span.charliteral {
+	color: #008080
+}
+
+span.vhdldigit { 
+	color: #ff00ff 
+}
+
+span.vhdlchar { 
+	color: #000000 
+}
+
+span.vhdlkeyword { 
+	color: #700070 
+}
+
+span.vhdllogic { 
+	color: #ff0000 
+}
+
+blockquote {
+        background-color: #F7F8FB;
+        border-left: 2px solid #9CAFD4;
+        margin: 0 24px 0 4px;
+        padding: 0 12px 0 16px;
+}
+
+blockquote.DocNodeRTL {
+   border-left: 0;
+   border-right: 2px solid #9CAFD4;
+   margin: 0 4px 0 24px;
+   padding: 0 16px 0 12px;
+}
+
+/* @end */
+
+/*
+.search {
+	color: #003399;
+	font-weight: bold;
+}
+
+form.search {
+	margin-bottom: 0px;
+	margin-top: 0px;
+}
+
+input.search {
+	font-size: 75%;
+	color: #000080;
+	font-weight: normal;
+	background-color: #e8eef2;
+}
+*/
+
+td.tiny {
+	font-size: 75%;
+}
+
+.dirtab {
+	padding: 4px;
+	border-collapse: collapse;
+	border: 1px solid #A3B4D7;
+}
+
+th.dirtab {
+	background: #EBEFF6;
+	font-weight: bold;
+}
+
+hr {
+	height: 0px;
+	border: none;
+	border-top: 1px solid #4A6AAA;
+}
+
+hr.footer {
+	height: 1px;
+}
+
+/* @group Member Descriptions */
+
+table.memberdecls {
+	border-spacing: 0px;
+	padding: 0px;
+}
+
+.memberdecls td, .fieldtable tr {
+	-webkit-transition-property: background-color, box-shadow;
+	-webkit-transition-duration: 0.5s;
+	-moz-transition-property: background-color, box-shadow;
+	-moz-transition-duration: 0.5s;
+	-ms-transition-property: background-color, box-shadow;
+	-ms-transition-duration: 0.5s;
+	-o-transition-property: background-color, box-shadow;
+	-o-transition-duration: 0.5s;
+	transition-property: background-color, box-shadow;
+	transition-duration: 0.5s;
+}
+
+.memberdecls td.glow, .fieldtable tr.glow {
+	background-color: cyan;
+	box-shadow: 0 0 15px cyan;
+}
+
+.mdescLeft, .mdescRight,
+.memItemLeft, .memItemRight,
+.memTemplItemLeft, .memTemplItemRight, .memTemplParams {
+	background-color: #F9FAFC;
+	border: none;
+	margin: 4px;
+	padding: 1px 0 0 8px;
+}
+
+.mdescLeft, .mdescRight {
+	padding: 0px 8px 4px 8px;
+	color: #555;
+}
+
+.memSeparator {
+        border-bottom: 1px solid #DEE4F0;
+        line-height: 1px;
+        margin: 0px;
+        padding: 0px;
+}
+
+.memItemLeft, .memTemplItemLeft {
+        white-space: nowrap;
+}
+
+.memItemRight, .memTemplItemRight {
+	width: 100%;
+}
+
+.memTemplParams {
+	color: #4665A2;
+        white-space: nowrap;
+	font-size: 80%;
+}
+
+/* @end */
+
+/* @group Member Details */
+
+/* Styles for detailed member documentation */
+
+.memtitle {
+	padding: 8px;
+	border-top: 1px solid #A8B8D9;
+	border-left: 1px solid #A8B8D9;
+	border-right: 1px solid #A8B8D9;
+	border-top-right-radius: 4px;
+	border-top-left-radius: 4px;
+	margin-bottom: -1px;
+	background-image: url('nav_f.png');
+	background-repeat: repeat-x;
+	background-color: #E2E8F2;
+	line-height: 1.25;
+	font-weight: 300;
+	float:left;
+}
+
+.permalink
+{
+        font-size: 65%;
+        display: inline-block;
+        vertical-align: middle;
+}
+
+.memtemplate {
+	font-size: 80%;
+	color: #4665A2;
+	font-weight: normal;
+	margin-left: 9px;
+}
+
+.memnav {
+	background-color: #EBEFF6;
+	border: 1px solid #A3B4D7;
+	text-align: center;
+	margin: 2px;
+	margin-right: 15px;
+	padding: 2px;
+}
+
+.mempage {
+	width: 100%;
+}
+
+.memitem {
+	padding: 0;
+	margin-bottom: 10px;
+	margin-right: 5px;
+        -webkit-transition: box-shadow 0.5s linear;
+        -moz-transition: box-shadow 0.5s linear;
+        -ms-transition: box-shadow 0.5s linear;
+        -o-transition: box-shadow 0.5s linear;
+        transition: box-shadow 0.5s linear;
+        display: table !important;
+        width: 100%;
+}
+
+.memitem.glow {
+         box-shadow: 0 0 15px cyan;
+}
+
+.memname {
+        font-weight: 400;
+        margin-left: 6px;
+}
+
+.memname td {
+	vertical-align: bottom;
+}
+
+.memproto, dl.reflist dt {
+        border-top: 1px solid #A8B8D9;
+        border-left: 1px solid #A8B8D9;
+        border-right: 1px solid #A8B8D9;
+        padding: 6px 0px 6px 0px;
+        color: #253555;
+        font-weight: bold;
+        text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+        background-color: #DFE5F1;
+        /* opera specific markup */
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        border-top-right-radius: 4px;
+        /* firefox specific markup */
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        -moz-border-radius-topright: 4px;
+        /* webkit specific markup */
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        -webkit-border-top-right-radius: 4px;
+
+}
+
+.overload {
+        font-family: "courier new",courier,monospace;
+	font-size: 65%;
+}
+
+.memdoc, dl.reflist dd {
+        border-bottom: 1px solid #A8B8D9;      
+        border-left: 1px solid #A8B8D9;      
+        border-right: 1px solid #A8B8D9; 
+        padding: 6px 10px 2px 10px;
+        background-color: #FBFCFD;
+        border-top-width: 0;
+        background-image:url('nav_g.png');
+        background-repeat:repeat-x;
+        background-color: #FFFFFF;
+        /* opera specific markup */
+        border-bottom-left-radius: 4px;
+        border-bottom-right-radius: 4px;
+        box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+        /* firefox specific markup */
+        -moz-border-radius-bottomleft: 4px;
+        -moz-border-radius-bottomright: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 5px 5px 5px;
+        /* webkit specific markup */
+        -webkit-border-bottom-left-radius: 4px;
+        -webkit-border-bottom-right-radius: 4px;
+        -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+dl.reflist dt {
+        padding: 5px;
+}
+
+dl.reflist dd {
+        margin: 0px 0px 10px 0px;
+        padding: 5px;
+}
+
+.paramkey {
+	text-align: right;
+}
+
+.paramtype {
+	white-space: nowrap;
+}
+
+.paramname {
+	color: #602020;
+	white-space: nowrap;
+}
+.paramname em {
+	font-style: normal;
+}
+.paramname code {
+        line-height: 14px;
+}
+
+.params, .retval, .exception, .tparams {
+        margin-left: 0px;
+        padding-left: 0px;
+}       
+
+.params .paramname, .retval .paramname, .tparams .paramname, .exception .paramname {
+        font-weight: bold;
+        vertical-align: top;
+}
+        
+.params .paramtype, .tparams .paramtype {
+        font-style: italic;
+        vertical-align: top;
+}       
+        
+.params .paramdir, .tparams .paramdir {
+        font-family: "courier new",courier,monospace;
+        vertical-align: top;
+}
+
+table.mlabels {
+	border-spacing: 0px;
+}
+
+td.mlabels-left {
+	width: 100%;
+	padding: 0px;
+}
+
+td.mlabels-right {
+	vertical-align: bottom;
+	padding: 0px;
+	white-space: nowrap;
+}
+
+span.mlabels {
+        margin-left: 8px;
+}
+
+span.mlabel {
+        background-color: #728DC1;
+        border-top:1px solid #5373B4;
+        border-left:1px solid #5373B4;
+        border-right:1px solid #C4CFE5;
+        border-bottom:1px solid #C4CFE5;
+	text-shadow: none;
+	color: white;
+	margin-right: 4px;
+	padding: 2px 3px;
+	border-radius: 3px;
+	font-size: 7pt;
+	white-space: nowrap;
+	vertical-align: middle;
+}
+
+
+
+/* @end */
+
+/* these are for tree view inside a (index) page */
+
+div.directory {
+        margin: 10px 0px;
+        border-top: 1px solid #9CAFD4;
+        border-bottom: 1px solid #9CAFD4;
+        width: 100%;
+}
+
+.directory table {
+        border-collapse:collapse;
+}
+
+.directory td {
+        margin: 0px;
+        padding: 0px;
+	vertical-align: top;
+}
+
+.directory td.entry {
+        white-space: nowrap;
+        padding-right: 6px;
+	padding-top: 3px;
+}
+
+.directory td.entry a {
+        outline:none;
+}
+
+.directory td.entry a img {
+        border: none;
+}
+
+.directory td.desc {
+        width: 100%;
+        padding-left: 6px;
+	padding-right: 6px;
+	padding-top: 3px;
+	border-left: 1px solid rgba(0,0,0,0.05);
+}
+
+.directory tr.even {
+	padding-left: 6px;
+	background-color: #F7F8FB;
+}
+
+.directory img {
+	vertical-align: -30%;
+}
+
+.directory .levels {
+        white-space: nowrap;
+        width: 100%;
+        text-align: right;
+        font-size: 9pt;
+}
+
+.directory .levels span {
+        cursor: pointer;
+        padding-left: 2px;
+        padding-right: 2px;
+	color: #3D578C;
+}
+
+.arrow {
+    color: #9CAFD4;
+    -webkit-user-select: none;
+    -khtml-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+    cursor: pointer;
+    font-size: 80%;
+    display: inline-block;
+    width: 16px;
+    height: 22px;
+}
+
+.icon {
+    font-family: Arial, Helvetica;
+    font-weight: bold;
+    font-size: 12px;
+    height: 14px;
+    width: 16px;
+    display: inline-block;
+    background-color: #728DC1;
+    color: white;
+    text-align: center;
+    border-radius: 4px;
+    margin-left: 2px;
+    margin-right: 2px;
+}
+
+.icona {
+    width: 24px;
+    height: 22px;
+    display: inline-block;
+}
+
+.iconfopen {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('folderopen.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.iconfclosed {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('folderclosed.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+.icondoc {
+    width: 24px;
+    height: 18px;
+    margin-bottom: 4px;
+    background-image:url('doc.png');
+    background-position: 0px -4px;
+    background-repeat: repeat-y;
+    vertical-align:top;
+    display: inline-block;
+}
+
+table.directory {
+    font: 400 14px Roboto,sans-serif;
+}
+
+/* @end */
+
+div.dynheader {
+        margin-top: 8px;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+address {
+	font-style: normal;
+	color: #2A3D61;
+}
+
+table.doxtable caption {
+	caption-side: top;
+}
+
+table.doxtable {
+	border-collapse:collapse;
+        margin-top: 4px;
+        margin-bottom: 4px;
+}
+
+table.doxtable td, table.doxtable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.doxtable th {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+}
+
+table.fieldtable {
+        /*width: 100%;*/
+        margin-bottom: 10px;
+        border: 1px solid #A8B8D9;
+        border-spacing: 0px;
+        -moz-border-radius: 4px;
+        -webkit-border-radius: 4px;
+        border-radius: 4px;
+        -moz-box-shadow: rgba(0, 0, 0, 0.15) 2px 2px 2px;
+        -webkit-box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+        box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.15);
+}
+
+.fieldtable td, .fieldtable th {
+        padding: 3px 7px 2px;
+}
+
+.fieldtable td.fieldtype, .fieldtable td.fieldname {
+        white-space: nowrap;
+        border-right: 1px solid #A8B8D9;
+        border-bottom: 1px solid #A8B8D9;
+        vertical-align: top;
+}
+
+.fieldtable td.fieldname {
+        padding-top: 3px;
+}
+
+.fieldtable td.fielddoc {
+        border-bottom: 1px solid #A8B8D9;
+        /*width: 100%;*/
+}
+
+.fieldtable td.fielddoc p:first-child {
+        margin-top: 0px;
+}       
+        
+.fieldtable td.fielddoc p:last-child {
+        margin-bottom: 2px;
+}
+
+.fieldtable tr:last-child td {
+        border-bottom: none;
+}
+
+.fieldtable th {
+        background-image:url('nav_f.png');
+        background-repeat:repeat-x;
+        background-color: #E2E8F2;
+        font-size: 90%;
+        color: #253555;
+        padding-bottom: 4px;
+        padding-top: 5px;
+        text-align:left;
+        font-weight: 400;
+        -moz-border-radius-topleft: 4px;
+        -moz-border-radius-topright: 4px;
+        -webkit-border-top-left-radius: 4px;
+        -webkit-border-top-right-radius: 4px;
+        border-top-left-radius: 4px;
+        border-top-right-radius: 4px;
+        border-bottom: 1px solid #A8B8D9;
+}
+
+
+.tabsearch {
+	top: 0px;
+	left: 10px;
+	height: 36px;
+	background-image: url('tab_b.png');
+	z-index: 101;
+	overflow: hidden;
+	font-size: 13px;
+}
+
+.navpath ul
+{
+	font-size: 11px;
+	background-image:url('tab_b.png');
+	background-repeat:repeat-x;
+	background-position: 0 -5px;
+	height:30px;
+	line-height:30px;
+	color:#8AA0CC;
+	border:solid 1px #C2CDE4;
+	overflow:hidden;
+	margin:0px;
+	padding:0px;
+}
+
+.navpath li
+{
+	list-style-type:none;
+	float:left;
+	padding-left:10px;
+	padding-right:15px;
+	background-image:url('bc_s.png');
+	background-repeat:no-repeat;
+	background-position:right;
+	color:#364D7C;
+}
+
+.navpath li.navelem a
+{
+	height:32px;
+	display:block;
+	text-decoration: none;
+	outline: none;
+	color: #283A5D;
+	font-family: 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+	text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);
+	text-decoration: none;        
+}
+
+.navpath li.navelem a:hover
+{
+	color:#6884BD;
+}
+
+.navpath li.footer
+{
+        list-style-type:none;
+        float:right;
+        padding-left:10px;
+        padding-right:15px;
+        background-image:none;
+        background-repeat:no-repeat;
+        background-position:right;
+        color:#364D7C;
+        font-size: 8pt;
+}
+
+
+div.summary
+{
+	float: right;
+	font-size: 8pt;
+	padding-right: 5px;
+	width: 50%;
+	text-align: right;
+}       
+
+div.summary a
+{
+	white-space: nowrap;
+}
+
+table.classindex
+{
+        margin: 10px;
+        white-space: nowrap;
+        margin-left: 3%;
+        margin-right: 3%;
+        width: 94%;
+        border: 0;
+        border-spacing: 0; 
+        padding: 0;
+}
+
+div.ingroups
+{
+	font-size: 8pt;
+	width: 50%;
+	text-align: left;
+}
+
+div.ingroups a
+{
+	white-space: nowrap;
+}
+
+div.header
+{
+        background-image:url('nav_h.png');
+        background-repeat:repeat-x;
+	background-color: #F9FAFC;
+	margin:  0px;
+	border-bottom: 1px solid #C4CFE5;
+}
+
+div.headertitle
+{
+	padding: 5px 5px 5px 10px;
+}
+
+.PageDocRTL-title div.headertitle {
+  text-align: right;
+  direction: rtl;
+}
+
+dl {
+        padding: 0 0 0 0;
+}
+
+/* dl.note, dl.warning, dl.attention, dl.pre, dl.post, dl.invariant, dl.deprecated, dl.todo, dl.test, dl.bug, dl.examples */
+dl.section {
+	margin-left: 0px;
+	padding-left: 0px;
+}
+
+dl.section.DocNodeRTL {
+  margin-right: 0px;
+  padding-right: 0px;
+}
+
+dl.note {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #D0C000;
+}
+
+dl.note.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #D0C000;
+}
+
+dl.warning, dl.attention {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #FF0000;
+}
+
+dl.warning.DocNodeRTL, dl.attention.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #FF0000;
+}
+
+dl.pre, dl.post, dl.invariant {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #00D000;
+}
+
+dl.pre.DocNodeRTL, dl.post.DocNodeRTL, dl.invariant.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #00D000;
+}
+
+dl.deprecated {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #505050;
+}
+
+dl.deprecated.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #505050;
+}
+
+dl.todo {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #00C0E0;
+}
+
+dl.todo.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #00C0E0;
+}
+
+dl.test {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #3030E0;
+}
+
+dl.test.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #3030E0;
+}
+
+dl.bug {
+  margin-left: -7px;
+  padding-left: 3px;
+  border-left: 4px solid;
+  border-color: #C08050;
+}
+
+dl.bug.DocNodeRTL {
+  margin-left: 0;
+  padding-left: 0;
+  border-left: 0;
+  margin-right: -7px;
+  padding-right: 3px;
+  border-right: 4px solid;
+  border-color: #C08050;
+}
+
+dl.section dd {
+	margin-bottom: 6px;
+}
+
+
+#projectrow
+{
+	height: 56px;
+}
+
+#projectlogo
+{
+	text-align: center;
+	vertical-align: bottom;
+	border-collapse: separate;
+}
+ 
+#projectlogo img
+{ 
+	border: 0px none;
+}
+ 
+#projectalign
+{
+        vertical-align: middle;
+        padding-left: 0.5em;
+}
+
+#projectname
+{
+	font: 200% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 2px 0px;
+}
+    
+#projectbrief
+{
+	font: 90% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#projectnumber
+{
+	font: 50% Tahoma, Arial,sans-serif;
+	margin: 0px;
+	padding: 0px;
+}
+
+#titlearea
+{
+	padding: 0px;
+	margin: 0px;
+	width: 100%;
+	border-bottom: 1px solid #5373B4;
+}
+
+.image
+{
+        text-align: center;
+}
+
+.dotgraph
+{
+        text-align: center;
+}
+
+.mscgraph
+{
+        text-align: center;
+}
+
+.plantumlgraph
+{
+        text-align: center;
+}
+
+.diagraph
+{
+        text-align: center;
+}
+
+.caption
+{
+	font-weight: bold;
+}
+
+div.zoom
+{
+	border: 1px solid #90A5CE;
+}
+
+dl.citelist {
+        margin-bottom:50px;
+}
+
+dl.citelist dt {
+        color:#334975;
+        float:left;
+        font-weight:bold;
+        margin-right:10px;
+        padding:5px;
+        text-align:right;
+        width:52px;
+}
+
+dl.citelist dd {
+        margin:2px 0 2px 72px;
+        padding:5px 0;
+}
+
+div.toc {
+        padding: 14px 25px;
+        background-color: #F4F6FA;
+        border: 1px solid #D8DFEE;
+        border-radius: 7px 7px 7px 7px;
+        float: right;
+        height: auto;
+        margin: 0 8px 10px 10px;
+        width: 200px;
+}
+
+.PageDocRTL-title div.toc {
+  float: left !important;
+  text-align: right;
+}
+
+div.toc li {
+        background: url("bdwn.png") no-repeat scroll 0 5px transparent;
+        font: 10px/1.2 Verdana,DejaVu Sans,Geneva,sans-serif;
+        margin-top: 5px;
+        padding-left: 10px;
+        padding-top: 2px;
+}
+
+.PageDocRTL-title div.toc li {
+  background-position-x: right !important;
+  padding-left: 0 !important;
+  padding-right: 10px;
+}
+
+div.toc h3 {
+        font: bold 12px/1.2 Arial,FreeSans,sans-serif;
+	color: #4665A2;
+        border-bottom: 0 none;
+        margin: 0;
+}
+
+div.toc ul {
+        list-style: none outside none;
+        border: medium none;
+        padding: 0px;
+}       
+
+div.toc li.level1 {
+        margin-left: 0px;
+}
+
+div.toc li.level2 {
+        margin-left: 15px;
+}
+
+div.toc li.level3 {
+        margin-left: 30px;
+}
+
+div.toc li.level4 {
+        margin-left: 45px;
+}
+
+span.emoji {
+        /* font family used at the site: https://unicode.org/emoji/charts/full-emoji-list.html
+         * font-family: "Noto Color Emoji", "Apple Color Emoji", "Segoe UI Emoji", Times, Symbola, Aegyptus, Code2000, Code2001, Code2002, Musica, serif, LastResort;
+         */
+}
+
+span.obfuscator {
+  display: none;
+}
+
+.PageDocRTL-title div.toc li.level1 {
+  margin-left: 0 !important;
+  margin-right: 0;
+}
+
+.PageDocRTL-title div.toc li.level2 {
+  margin-left: 0 !important;
+  margin-right: 15px;
+}
+
+.PageDocRTL-title div.toc li.level3 {
+  margin-left: 0 !important;
+  margin-right: 30px;
+}
+
+.PageDocRTL-title div.toc li.level4 {
+  margin-left: 0 !important;
+  margin-right: 45px;
+}
+
+.inherit_header {
+        font-weight: bold;
+        color: gray;
+        cursor: pointer;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.inherit_header td {
+        padding: 6px 0px 2px 5px;
+}
+
+.inherit {
+        display: none;
+}
+
+tr.heading h2 {
+        margin-top: 12px;
+        margin-bottom: 4px;
+}
+
+/* tooltip related style info */
+
+.ttc {
+        position: absolute;
+        display: none;
+}
+
+#powerTip {
+	cursor: default;
+	/*white-space: nowrap;*/
+	background-color: white;
+	border: 1px solid gray;
+	border-radius: 4px 4px 4px 4px;
+	box-shadow: 1px 1px 7px gray;
+	display: none;
+	font-size: smaller;
+	max-width: 80%;
+	opacity: 0.9;
+	padding: 1ex 1em 1em;
+	position: absolute;
+	z-index: 2147483647;
+}
+
+#powerTip div.ttdoc {
+        color: grey;
+	font-style: italic;
+}
+
+#powerTip div.ttname a {
+        font-weight: bold;
+}
+
+#powerTip div.ttname {
+        font-weight: bold;
+}
+
+#powerTip div.ttdeci {
+        color: #006318;
+}
+
+#powerTip div {
+        margin: 0px;
+        padding: 0px;
+        font: 12px/16px Roboto,sans-serif;
+}
+
+#powerTip:before, #powerTip:after {
+	content: "";
+	position: absolute;
+	margin: 0px;
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.w:after,  #powerTip.w:before,
+#powerTip.e:after,  #powerTip.e:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.nw:after, #powerTip.nw:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	border: solid transparent;
+	content: " ";
+	height: 0;
+	width: 0;
+	position: absolute;
+}
+
+#powerTip.n:after,  #powerTip.s:after,
+#powerTip.w:after,  #powerTip.e:after,
+#powerTip.nw:after, #powerTip.ne:after,
+#powerTip.sw:after, #powerTip.se:after {
+	border-color: rgba(255, 255, 255, 0);
+}
+
+#powerTip.n:before,  #powerTip.s:before,
+#powerTip.w:before,  #powerTip.e:before,
+#powerTip.nw:before, #powerTip.ne:before,
+#powerTip.sw:before, #powerTip.se:before {
+	border-color: rgba(128, 128, 128, 0);
+}
+
+#powerTip.n:after,  #powerTip.n:before,
+#powerTip.ne:after, #powerTip.ne:before,
+#powerTip.nw:after, #powerTip.nw:before {
+	top: 100%;
+}
+
+#powerTip.n:after, #powerTip.ne:after, #powerTip.nw:after {
+	border-top-color: #FFFFFF;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+#powerTip.n:before {
+	border-top-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+#powerTip.n:after, #powerTip.n:before {
+	left: 50%;
+}
+
+#powerTip.nw:after, #powerTip.nw:before {
+	right: 14px;
+}
+
+#powerTip.ne:after, #powerTip.ne:before {
+	left: 14px;
+}
+
+#powerTip.s:after,  #powerTip.s:before,
+#powerTip.se:after, #powerTip.se:before,
+#powerTip.sw:after, #powerTip.sw:before {
+	bottom: 100%;
+}
+
+#powerTip.s:after, #powerTip.se:after, #powerTip.sw:after {
+	border-bottom-color: #FFFFFF;
+	border-width: 10px;
+	margin: 0px -10px;
+}
+
+#powerTip.s:before, #powerTip.se:before, #powerTip.sw:before {
+	border-bottom-color: #808080;
+	border-width: 11px;
+	margin: 0px -11px;
+}
+
+#powerTip.s:after, #powerTip.s:before {
+	left: 50%;
+}
+
+#powerTip.sw:after, #powerTip.sw:before {
+	right: 14px;
+}
+
+#powerTip.se:after, #powerTip.se:before {
+	left: 14px;
+}
+
+#powerTip.e:after, #powerTip.e:before {
+	left: 100%;
+}
+#powerTip.e:after {
+	border-left-color: #FFFFFF;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.e:before {
+	border-left-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+#powerTip.w:after, #powerTip.w:before {
+	right: 100%;
+}
+#powerTip.w:after {
+	border-right-color: #FFFFFF;
+	border-width: 10px;
+	top: 50%;
+	margin-top: -10px;
+}
+#powerTip.w:before {
+	border-right-color: #808080;
+	border-width: 11px;
+	top: 50%;
+	margin-top: -11px;
+}
+
+@media print
+{
+  #top { display: none; }
+  #side-nav { display: none; }
+  #nav-path { display: none; }
+  body { overflow:visible; }
+  h1, h2, h3, h4, h5, h6 { page-break-after: avoid; }
+  .summary { display: none; }
+  .memitem { page-break-inside: avoid; }
+  #doc-content
+  {
+    margin-left:0 !important;
+    height:auto !important;
+    width:auto !important;
+    overflow:inherit;
+    display:inline;
+  }
+}
+
+/* @group Markdown */
+
+table.markdownTable {
+	border-collapse:collapse;
+        margin-top: 4px;
+        margin-bottom: 4px;
+}
+
+table.markdownTable td, table.markdownTable th {
+	border: 1px solid #2D4068;
+	padding: 3px 7px 2px;
+}
+
+table.markdownTable tr {
+}
+
+th.markdownTableHeadLeft, th.markdownTableHeadRight, th.markdownTableHeadCenter, th.markdownTableHeadNone {
+	background-color: #374F7F;
+	color: #FFFFFF;
+	font-size: 110%;
+	padding-bottom: 4px;
+	padding-top: 5px;
+}
+
+th.markdownTableHeadLeft, td.markdownTableBodyLeft {
+	text-align: left
+}
+
+th.markdownTableHeadRight, td.markdownTableBodyRight {
+	text-align: right
+}
+
+th.markdownTableHeadCenter, td.markdownTableBodyCenter {
+	text-align: center
+}
+
+.DocNodeRTL {
+  text-align: right;
+  direction: rtl;
+}
+
+.DocNodeLTR {
+  text-align: left;
+  direction: ltr;
+}
+
+table.DocNodeRTL {
+   width: auto;
+   margin-right: 0;
+   margin-left: auto;
+}
+
+table.DocNodeLTR {
+   width: auto;
+   margin-right: auto;
+   margin-left: 0;
+}
+
+code.JavaDocCode {
+  direction:ltr;
+}
+
+tt, code, kbd, samp
+{
+  display: inline-block;
+  direction:ltr; 
+}
+/* @end */
+
+u {
+	text-decoration: underline;
+}
+
diff --git a/ld_client/doc/pdoc/doxygen.svg b/ld_client/doc/pdoc/doxygen.svg
new file mode 100644
index 0000000..d42dad5
--- /dev/null
+++ b/ld_client/doc/pdoc/doxygen.svg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg version="1.1" viewBox="0 0 104 31" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+  <linearGradient id="a">
+   <stop stop-color="#5373B4" offset="0"/>
+   <stop stop-color="#7C95C6" offset="1"/>
+  </linearGradient>
+  <linearGradient id="d" x1="31.474" x2="31.474" y1="24.821" y2="26.773" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
+  <linearGradient id="c" x1="31.474" x2="31.474" y1="24.821" y2="26.773" gradientTransform="matrix(.6816 0 0 1.0248 72.391 -.91809)" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
+  <linearGradient id="b" x1="56.295" x2="56.295" y1="24.622" y2="26.574" gradientUnits="userSpaceOnUse" xlink:href="#a"/>
+  <linearGradient id="e" x1="49.067" x2="48.956" y1="19.719" y2="9.5227" gradientTransform="matrix(.97968 0 0 1.0207 -.25579 -.25579)" gradientUnits="userSpaceOnUse">
+   <stop stop-color="#C0CCE3" offset="0"/>
+   <stop stop-color="#EEF1F7" offset="1"/>
+  </linearGradient>
+  <filter id="f" x="-.010676" y="-.045304" width="1.0214" height="1.0906" color-interpolation-filters="sRGB">
+   <feGaussianBlur stdDeviation="0.45293203"/>
+  </filter>
+ </defs>
+ <g>
+  <path transform="translate(-2.5759 -27.848)" d="m13.609 32.203v6.8633h-0.05078c-0.40533-0.66867-0.96254-1.1715-1.6719-1.5059-0.69244-0.35193-1.4282-0.52734-2.2051-0.52734-0.96267 0-1.807 0.2027-2.5332 0.60742-0.72622 0.38713-1.3344 0.90556-1.8242 1.5566-0.47289 0.65108-0.83456 1.4092-1.0879 2.2715-0.23644 0.84464-0.35547 1.7236-0.35547 2.6387 0 0.95022 0.11902 1.8643 0.35547 2.7441 0.25333 0.87983 0.615 1.6633 1.0879 2.3496 0.48978 0.66867 1.1065 1.2066 1.8496 1.6113 0.74311 0.38713 1.6044 0.58008 2.584 0.58008 0.86133 0 1.6311-0.15787 2.3066-0.47461 0.69244-0.33434 1.2497-0.87227 1.6719-1.6113h0.05078v1.7422h3.4199v-18.846zm12.875 4.8301c-1.0302 0-1.9596 0.17541-2.7871 0.52734-0.82756 0.33434-1.5358 0.81965-2.127 1.4531-0.59111 0.61588-1.0483 1.3721-1.3691 2.2695-0.32089 0.87983-0.48047 1.866-0.48047 2.957s0.15958 2.0752 0.48047 2.9551c0.32089 0.87983 0.77803 1.6361 1.3691 2.2695 0.59111 0.61588 1.2994 1.0914 2.127 1.4258 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.0302 0 1.9596-0.16762 2.7871-0.50195 0.84444-0.33434 1.5612-0.8099 2.1523-1.4258 0.59111-0.63348 1.0483-1.3897 1.3691-2.2695 0.32089-0.87983 0.48047-1.8641 0.48047-2.9551s-0.15958-2.0772-0.48047-2.957c-0.32089-0.89743-0.77803-1.6536-1.3691-2.2695-0.59111-0.63348-1.3079-1.1188-2.1523-1.4531-0.82756-0.35193-1.7569-0.52734-2.7871-0.52734zm41.715 0c-0.912 0-1.7223 0.18516-2.4316 0.55469-0.69244 0.36953-1.2752 0.87043-1.748 1.5039-0.47289 0.61588-0.83651 1.337-1.0898 2.1641-0.23645 0.80944-0.35352 1.6553-0.35352 2.5352 0 0.93262 0.10007 1.8214 0.30273 2.666 0.21956 0.82704 0.55767 1.556 1.0137 2.1895 0.456 0.61588 1.0387 1.109 1.748 1.4785 0.70933 0.35193 1.5536 0.5293 2.5332 0.5293 0.79378 0 1.5446-0.16762 2.2539-0.50195 0.72622-0.35193 1.2834-0.88986 1.6719-1.6113h0.05078v1.7949c0.01689 0.96782-0.21071 1.7689-0.68359 2.4023-0.456 0.63348-1.1898 0.95117-2.2031 0.95117-0.64178 0-1.2075-0.14228-1.6973-0.42383-0.48978-0.26395-0.81939-0.74731-0.98828-1.4512h-3.5723c0.05067 0.77425 0.25276 1.435 0.60742 1.9805 0.37156 0.56309 0.8287 1.0192 1.3691 1.3711 0.55733 0.35193 1.1656 0.60726 1.8242 0.76562 0.67556 0.17597 1.3328 0.26562 1.9746 0.26562 1.5031 0 2.7025-0.21245 3.5977-0.63477 0.89511-0.42232 1.5798-0.94076 2.0527-1.5566 0.47289-0.59829 0.777-1.2493 0.91211-1.9531 0.152-0.70386 0.22656-1.3295 0.22656-1.875v-12.775h-3.4199v1.8223h-0.05078c-0.43911-0.79185-0.98782-1.3551-1.6465-1.6895-0.64178-0.33434-1.3926-0.50195-2.2539-0.50195zm16.523 0c-0.99644 0-1.9088 0.18516-2.7363 0.55469-0.81067 0.36953-1.5124 0.88018-2.1035 1.5312-0.59111 0.63348-1.0463 1.3897-1.3672 2.2695s-0.48047 1.831-0.48047 2.8516c0 1.0558 0.15108 2.0225 0.45508 2.9023 0.32089 0.87983 0.76758 1.6361 1.3418 2.2695 0.57422 0.63348 1.276 1.1266 2.1035 1.4785 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.4862 0 2.7517-0.35277 3.7988-1.0566 1.0471-0.70387 1.8254-1.8733 2.332-3.5098h-3.168c-0.11822 0.42232-0.43934 0.82772-0.96289 1.2148-0.52355 0.36953-1.1468 0.55274-1.873 0.55273-1.0133 0-1.7916-0.27286-2.332-0.81836-0.54044-0.5455-0.83605-1.4245-0.88672-2.6387h9.4492c0.06756-1.0558-0.01551-2.0673-0.25195-3.0352-0.23644-0.96782-0.62557-1.8293-1.166-2.5859-0.52356-0.75666-1.1998-1.355-2.0273-1.7949-0.82756-0.45751-1.7974-0.6875-2.9121-0.6875zm16.189 0c-0.76 0-1.5023 0.18516-2.2285 0.55469-0.72622 0.35193-1.3174 0.92299-1.7734 1.7148h-0.07617v-1.9004h-3.4199v13.646h3.5977v-7.1523c0-1.3901 0.21909-2.3841 0.6582-2.9824 0.43911-0.61588 1.1494-0.92383 2.1289-0.92383 0.86133 0 1.4611 0.28066 1.7988 0.84375 0.33777 0.5455 0.50586 1.3816 0.50586 2.5078v7.707h3.5976v-8.3926c0-0.84464-0.0765-1.6106-0.22851-2.2969-0.13511-0.70387-0.37971-1.2925-0.73438-1.7676-0.35466-0.49271-0.84386-0.87277-1.4688-1.1367-0.608-0.28155-1.3948-0.42188-2.3574-0.42188zm-66.063 0.36914 4.3066 6.4668-4.7129 7.1797h4.0293l2.7363-4.3027 2.7344 4.3027h4.1055l-4.8398-7.2578 4.3066-6.3887h-3.9766l-2.2793 3.5645-2.3066-3.5645zm13.275 0 4.584 12.803c0.10133 0.26395 0.15234 0.54461 0.15234 0.84375 0 0.40472-0.11707 0.77504-0.35352 1.1094-0.21956 0.33434-0.56617 0.52729-1.0391 0.58008-0.35467 0.0176-0.70979 0.0098-1.0645-0.02539-0.35467-0.03519-0.70128-0.07028-1.0391-0.10547v3.0879c0.37156 0.03519 0.73518 0.06051 1.0898 0.07813 0.37156 0.03519 0.74368 0.05273 1.1152 0.05273 1.2329 0 2.1943-0.23778 2.8867-0.71289 0.69244-0.47511 1.2326-1.2664 1.6211-2.375l5.4727-15.336h-3.7246l-2.8613 9.3438h-0.05078l-2.9648-9.3438zm-37.48 2.4551c0.59111 0 1.0823 0.12279 1.4707 0.36914 0.38844 0.24635 0.6991 0.57184 0.93555 0.97656 0.25333 0.38713 0.43187 0.84515 0.5332 1.373 0.10133 0.5103 0.15234 1.0482 0.15234 1.6113 0 0.56309-0.05101 1.1069-0.15234 1.6348-0.10133 0.5279-0.27137 1.0035-0.50781 1.4258-0.23644 0.40472-0.5556 0.73021-0.96094 0.97656-0.38844 0.24635-0.87959 0.36914-1.4707 0.36914-0.55733 0-1.038-0.12279-1.4434-0.36914-0.38844-0.26395-0.71806-0.59723-0.98828-1.002-0.25333-0.42232-0.43842-0.89788-0.55664-1.4258s-0.17773-1.0561-0.17773-1.584c-1e-7 -0.56309 0.05101-1.0991 0.15234-1.6094 0.11822-0.5279 0.29481-0.99567 0.53125-1.4004 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.24635 0.90303-0.36914 1.4941-0.36914zm15.84 0c0.608 0 1.1142 0.13253 1.5195 0.39648 0.42222 0.24635 0.75184 0.57184 0.98828 0.97656 0.25333 0.40472 0.42992 0.87054 0.53125 1.3984 0.10133 0.5279 0.15234 1.0658 0.15234 1.6113 0 0.5455-0.05101 1.0815-0.15234 1.6094-0.10134 0.5103-0.27792 0.97612-0.53125 1.3984-0.23644 0.40472-0.56606 0.73021-0.98828 0.97656-0.40533 0.24635-0.91153 0.36914-1.5195 0.36914-0.608 0-1.1142-0.12279-1.5195-0.36914s-0.73495-0.57184-0.98828-0.97656c-0.23644-0.42232-0.40648-0.88814-0.50781-1.3984-0.10133-0.5279-0.15234-1.0639-0.15234-1.6094 0-0.5455 0.05101-1.0834 0.15234-1.6113 0.10133-0.5279 0.27137-0.99371 0.50781-1.3984 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.26395 0.91153-0.39648 1.5195-0.39648zm42.602 0c0.59111 0 1.0803 0.11499 1.4688 0.34375 0.38844 0.22876 0.70105 0.5367 0.9375 0.92383 0.23644 0.38713 0.40648 0.8354 0.50781 1.3457 0.10133 0.49271 0.15039 1.0209 0.15039 1.584 0 0.4927-0.06606 0.96827-0.20117 1.4258-0.11822 0.43992-0.30526 0.83557-0.55859 1.1875-0.25333 0.35193-0.57445 0.63259-0.96289 0.84375-0.38844 0.21116-0.83513 0.31836-1.3418 0.31836-0.55733 0-1.021-0.12474-1.3926-0.37109-0.37156-0.24635-0.67566-0.56209-0.91211-0.94922-0.21956-0.38713-0.38109-0.81786-0.48242-1.293-0.08444-0.49271-0.12695-0.98581-0.12695-1.4785 0-0.5103 0.05101-0.99366 0.15234-1.4512 0.11822-0.47511 0.29676-0.89025 0.5332-1.2422 0.25333-0.36953 0.55744-0.65993 0.91211-0.87109 0.37156-0.21116 0.80974-0.31641 1.3164-0.31641zm15.535 0c0.87822 0 1.529 0.24753 1.9512 0.74023 0.43911 0.49271 0.74322 1.2138 0.91211 2.1641h-5.8535c0.01689-0.26395 0.0679-0.5641 0.15234-0.89844 0.10133-0.33434 0.26287-0.65008 0.48242-0.94922 0.23644-0.29914 0.54055-0.54667 0.91211-0.74023 0.38845-0.21116 0.86914-0.31641 1.4434-0.31641z" filter="url(#f)" opacity=".3" stroke="#969696" xlink:href="#path141"/>
+  <path d="m0.97202 24.161 43.605-0.0019 0.0508 3.3061-43.6 0.04174z" fill="url(#d)" stroke="#000" stroke-width=".5"/>
+  <path d="m10.283 3.5547v6.8633h-0.05078c-0.40533-0.66867-0.96254-1.1715-1.6719-1.5059-0.69244-0.35193-1.4282-0.52734-2.2051-0.52734-0.96267 0-1.807 0.2027-2.5332 0.60742-0.72622 0.38713-1.3344 0.90556-1.8242 1.5566-0.47289 0.65108-0.83456 1.4092-1.0879 2.2715-0.23644 0.84464-0.35547 1.7236-0.35547 2.6387 0 0.95022 0.11902 1.8643 0.35547 2.7441 0.25333 0.87983 0.615 1.6633 1.0879 2.3496 0.48978 0.66867 1.1065 1.2066 1.8496 1.6113 0.74311 0.38713 1.6044 0.58008 2.584 0.58008 0.86133 0 1.6311-0.15787 2.3066-0.47461 0.69244-0.33434 1.2497-0.87227 1.6719-1.6113h0.05078v1.7422h3.4199v-18.846zm12.875 4.8301c-1.0302 0-1.9596 0.17541-2.7871 0.52734-0.82756 0.33434-1.5358 0.81965-2.127 1.4531-0.59111 0.61588-1.0483 1.3721-1.3691 2.2695-0.32089 0.87983-0.48047 1.866-0.48047 2.957s0.15958 2.0752 0.48047 2.9551c0.32089 0.87983 0.77803 1.6361 1.3691 2.2695 0.59111 0.61588 1.2994 1.0914 2.127 1.4258 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.0302 0 1.9596-0.16762 2.7871-0.50195 0.84444-0.33434 1.5612-0.8099 2.1523-1.4258 0.59111-0.63348 1.0483-1.3897 1.3691-2.2695 0.32089-0.87983 0.48047-1.8641 0.48047-2.9551s-0.15958-2.0772-0.48047-2.957c-0.32089-0.89743-0.77803-1.6536-1.3691-2.2695-0.59111-0.63348-1.3079-1.1188-2.1523-1.4531-0.82756-0.35193-1.7569-0.52734-2.7871-0.52734zm41.715 0c-0.912 0-1.7223 0.18516-2.4316 0.55469-0.69244 0.36953-1.2752 0.87043-1.748 1.5039-0.47289 0.61588-0.83651 1.337-1.0898 2.1641-0.23644 0.80944-0.35352 1.6553-0.35352 2.5352 0 0.93262 0.10007 1.8214 0.30273 2.666 0.21956 0.82704 0.55767 1.556 1.0137 2.1895 0.456 0.61588 1.0387 1.109 1.748 1.4785 0.70933 0.35193 1.5536 0.5293 2.5332 0.5293 0.79378 0 1.5446-0.16762 2.2539-0.50195 0.72622-0.35193 1.2834-0.88986 1.6719-1.6113h0.05078v1.7949c0.01689 0.96782-0.21071 1.7689-0.68359 2.4023-0.456 0.63348-1.1898 0.95117-2.2031 0.95117-0.64178 0-1.2075-0.14228-1.6973-0.42383-0.48978-0.26395-0.81939-0.74731-0.98828-1.4512h-3.5723c0.05067 0.77425 0.25276 1.435 0.60742 1.9805 0.37156 0.56309 0.8287 1.0192 1.3691 1.3711 0.55733 0.35193 1.1656 0.60726 1.8242 0.76562 0.67556 0.17597 1.3328 0.26562 1.9746 0.26562 1.5031 0 2.7025-0.21245 3.5977-0.63477 0.89511-0.42232 1.5798-0.94076 2.0527-1.5566 0.47289-0.59829 0.777-1.2493 0.91211-1.9531 0.152-0.70386 0.22656-1.3295 0.22656-1.875v-12.775h-3.4199v1.8223h-0.05078c-0.43911-0.79185-0.98782-1.3551-1.6465-1.6895-0.64178-0.33434-1.3926-0.50195-2.2539-0.50195zm16.523 0c-0.99644 0-1.9088 0.18516-2.7363 0.55469-0.81067 0.36953-1.5124 0.88017-2.1035 1.5312-0.59111 0.63348-1.0463 1.3897-1.3672 2.2695s-0.48047 1.831-0.48047 2.8516c0 1.0558 0.15108 2.0225 0.45508 2.9023 0.32089 0.87983 0.76758 1.6361 1.3418 2.2695 0.57422 0.63348 1.276 1.1266 2.1035 1.4785 0.82756 0.33434 1.7569 0.50195 2.7871 0.50195 1.4862 0 2.7517-0.35278 3.7988-1.0566 1.0471-0.70386 1.8254-1.8733 2.332-3.5098h-3.168c-0.11822 0.42232-0.43934 0.82772-0.96289 1.2148-0.52355 0.36953-1.1468 0.55274-1.873 0.55273-1.0133 0-1.7916-0.27286-2.332-0.81836-0.54044-0.5455-0.83605-1.4245-0.88672-2.6387h9.4492c0.06756-1.0558-0.01551-2.0673-0.25195-3.0352-0.23644-0.96782-0.62557-1.8293-1.166-2.5859-0.52356-0.75666-1.1998-1.355-2.0273-1.7949-0.82756-0.45751-1.7974-0.6875-2.9121-0.6875zm16.189 0c-0.76 0-1.5023 0.18516-2.2285 0.55469-0.72622 0.35193-1.3174 0.923-1.7734 1.7148h-0.07617v-1.9004h-3.4199v13.646h3.5977v-7.1523c0-1.3901 0.21909-2.3841 0.6582-2.9824 0.43911-0.61588 1.1494-0.92383 2.1289-0.92383 0.86133 0 1.461 0.28066 1.7988 0.84375 0.33778 0.5455 0.50586 1.3816 0.50586 2.5078v7.707h3.5977v-8.3926c0-0.84464-0.0765-1.6106-0.22852-2.2969-0.13511-0.70387-0.3797-1.2925-0.73437-1.7676-0.35466-0.49271-0.84386-0.87277-1.4688-1.1367-0.608-0.28155-1.3948-0.42188-2.3574-0.42188zm-66.062 0.36914 4.3066 6.4668-4.7129 7.1797h4.0293l2.7363-4.3027 2.7344 4.3027h4.1055l-4.8398-7.2578 4.3066-6.3887h-3.9766l-2.2793 3.5645-2.3066-3.5645zm13.275 0 4.584 12.803c0.10133 0.26395 0.15234 0.54461 0.15234 0.84375 0 0.40472-0.11707 0.77504-0.35352 1.1094-0.21956 0.33434-0.56617 0.52729-1.0391 0.58008-0.35467 0.0176-0.70979 0.0098-1.0645-0.02539-0.35467-0.03519-0.70128-0.07027-1.0391-0.10547v3.0879c0.37156 0.03519 0.73518 0.06052 1.0898 0.07813 0.37156 0.03519 0.74368 0.05273 1.1152 0.05273 1.2329 0 2.1943-0.23778 2.8867-0.71289 0.69244-0.47511 1.2326-1.2664 1.6211-2.375l5.4727-15.336h-3.7246l-2.8613 9.3437h-0.05078l-2.9648-9.3437zm-37.48 2.4551c0.59111 0 1.0823 0.12279 1.4707 0.36914s0.6991 0.57184 0.93555 0.97656c0.25333 0.38713 0.43187 0.84515 0.5332 1.373 0.10133 0.5103 0.15234 1.0482 0.15234 1.6113 0 0.56309-0.05101 1.1069-0.15234 1.6348-0.10133 0.5279-0.27137 1.0035-0.50781 1.4258-0.23644 0.40472-0.5556 0.73021-0.96094 0.97656-0.38844 0.24635-0.87959 0.36914-1.4707 0.36914-0.55733 0-1.038-0.12279-1.4434-0.36914-0.38844-0.26395-0.71806-0.59723-0.98828-1.002-0.25333-0.42232-0.43842-0.89788-0.55664-1.4258s-0.17773-1.0561-0.17773-1.584c-1e-7 -0.56309 0.05101-1.0991 0.15234-1.6094 0.11822-0.5279 0.29481-0.99567 0.53125-1.4004 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.24635 0.90303-0.36914 1.4941-0.36914zm15.84 0c0.608 0 1.1142 0.13254 1.5195 0.39648 0.42222 0.24635 0.75184 0.57184 0.98828 0.97656 0.25333 0.40472 0.42992 0.87054 0.53125 1.3984 0.10133 0.5279 0.15234 1.0658 0.15234 1.6113 0 0.5455-0.05101 1.0815-0.15234 1.6094-0.10133 0.5103-0.27792 0.97612-0.53125 1.3984-0.23644 0.40472-0.56606 0.73021-0.98828 0.97656-0.40533 0.24635-0.91153 0.36914-1.5195 0.36914-0.608 0-1.1142-0.12279-1.5195-0.36914s-0.73495-0.57184-0.98828-0.97656c-0.23644-0.42232-0.40648-0.88813-0.50781-1.3984-0.10133-0.5279-0.15234-1.0639-0.15234-1.6094 0-0.5455 0.05101-1.0834 0.15234-1.6113 0.10133-0.5279 0.27137-0.99371 0.50781-1.3984 0.25333-0.40472 0.58295-0.73021 0.98828-0.97656 0.40533-0.26395 0.91153-0.39648 1.5195-0.39648zm42.602 0c0.59111 0 1.0803 0.11499 1.4688 0.34375 0.38844 0.22876 0.70106 0.5367 0.9375 0.92383 0.23644 0.38713 0.40648 0.8354 0.50781 1.3457 0.10133 0.49271 0.15039 1.0209 0.15039 1.584 0 0.49271-0.06606 0.96827-0.20117 1.4258-0.11822 0.43992-0.30526 0.83557-0.55859 1.1875-0.25333 0.35193-0.57445 0.63259-0.96289 0.84375-0.38844 0.21116-0.83513 0.31836-1.3418 0.31836-0.55733 0-1.021-0.12474-1.3926-0.37109-0.37156-0.24635-0.67566-0.56209-0.91211-0.94922-0.21956-0.38713-0.38109-0.81786-0.48242-1.293-0.08444-0.49271-0.12695-0.98581-0.12695-1.4785 0-0.5103 0.05101-0.99366 0.15234-1.4512 0.11822-0.47511 0.29676-0.89026 0.5332-1.2422 0.25333-0.36953 0.55744-0.65993 0.91211-0.87109 0.37156-0.21116 0.80974-0.31641 1.3164-0.31641zm15.535 0c0.87822 0 1.529 0.24753 1.9512 0.74024 0.43911 0.49271 0.74322 1.2138 0.91211 2.1641h-5.8535c0.01689-0.26395 0.0679-0.5641 0.15234-0.89844 0.10133-0.33434 0.26287-0.65008 0.48242-0.94922 0.23644-0.29914 0.54055-0.54667 0.91211-0.74023 0.38845-0.21116 0.86914-0.31641 1.4434-0.31641z" fill="url(#e)" stroke="#4665A2" stroke-width=".7"/>
+  <path d="m52.988 27.291c0.99602-1.0359 1.3944-1.8725 1.7928-3.1076l3.8247-0.03984c0.3113 1.6096 0.82413 2.5137 1.6335 3.1474z" fill="url(#b)" stroke="#000" stroke-width=".5"/>
+  <path d="m73.89 24.04 28.885-0.2011-0.12476 3.3879-31.033 0.16229c1.2621-1.0234 1.9665-2.2859 2.2724-3.3491z" fill="url(#c)" stroke="#000" stroke-width=".41788"/>
+ </g>
+</svg>
diff --git a/ld_client/doc/pdoc/dynsections.js b/ld_client/doc/pdoc/dynsections.js
new file mode 100644
index 0000000..3174bd7
--- /dev/null
+++ b/ld_client/doc/pdoc/dynsections.js
@@ -0,0 +1,121 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+ */
+function toggleVisibility(linkObj)
+{
+ var base = $(linkObj).attr('id');
+ var summary = $('#'+base+'-summary');
+ var content = $('#'+base+'-content');
+ var trigger = $('#'+base+'-trigger');
+ var src=$(trigger).attr('src');
+ if (content.is(':visible')===true) {
+   content.hide();
+   summary.show();
+   $(linkObj).addClass('closed').removeClass('opened');
+   $(trigger).attr('src',src.substring(0,src.length-8)+'closed.png');
+ } else {
+   content.show();
+   summary.hide();
+   $(linkObj).removeClass('closed').addClass('opened');
+   $(trigger).attr('src',src.substring(0,src.length-10)+'open.png');
+ }
+ return false;
+}
+
+function updateStripes()
+{
+  $('table.directory tr').
+       removeClass('even').filter(':visible:even').addClass('even');
+}
+
+function toggleLevel(level)
+{
+  $('table.directory tr').each(function() {
+    var l = this.id.split('_').length-1;
+    var i = $('#img'+this.id.substring(3));
+    var a = $('#arr'+this.id.substring(3));
+    if (l<level+1) {
+      i.removeClass('iconfopen iconfclosed').addClass('iconfopen');
+      a.html('&#9660;');
+      $(this).show();
+    } else if (l==level+1) {
+      i.removeClass('iconfclosed iconfopen').addClass('iconfclosed');
+      a.html('&#9658;');
+      $(this).show();
+    } else {
+      $(this).hide();
+    }
+  });
+  updateStripes();
+}
+
+function toggleFolder(id)
+{
+  // the clicked row
+  var currentRow = $('#row_'+id);
+
+  // all rows after the clicked row
+  var rows = currentRow.nextAll("tr");
+
+  var re = new RegExp('^row_'+id+'\\d+_$', "i"); //only one sub
+
+  // only match elements AFTER this one (can't hide elements before)
+  var childRows = rows.filter(function() { return this.id.match(re); });
+
+  // first row is visible we are HIDING
+  if (childRows.filter(':first').is(':visible')===true) {
+    // replace down arrow by right arrow for current row
+    var currentRowSpans = currentRow.find("span");
+    currentRowSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+    currentRowSpans.filter(".arrow").html('&#9658;');
+    rows.filter("[id^=row_"+id+"]").hide(); // hide all children
+  } else { // we are SHOWING
+    // replace right arrow by down arrow for current row
+    var currentRowSpans = currentRow.find("span");
+    currentRowSpans.filter(".iconfclosed").removeClass("iconfclosed").addClass("iconfopen");
+    currentRowSpans.filter(".arrow").html('&#9660;');
+    // replace down arrows by right arrows for child rows
+    var childRowsSpans = childRows.find("span");
+    childRowsSpans.filter(".iconfopen").removeClass("iconfopen").addClass("iconfclosed");
+    childRowsSpans.filter(".arrow").html('&#9658;');
+    childRows.show(); //show all children
+  }
+  updateStripes();
+}
+
+
+function toggleInherit(id)
+{
+  var rows = $('tr.inherit.'+id);
+  var img = $('tr.inherit_header.'+id+' img');
+  var src = $(img).attr('src');
+  if (rows.filter(':first').is(':visible')===true) {
+    rows.css('display','none');
+    $(img).attr('src',src.substring(0,src.length-8)+'closed.png');
+  } else {
+    rows.css('display','table-row'); // using show() causes jump in firefox
+    $(img).attr('src',src.substring(0,src.length-10)+'open.png');
+  }
+}
+/* @license-end */
diff --git a/ld_client/doc/pdoc/folderclosed.png b/ld_client/doc/pdoc/folderclosed.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb8ab35edce8e97554e360005ee9fc5bffb36e66
GIT binary patch
literal 616
zcmV-u0+;=XP)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz0006nNkl<ZcmeHQ
zO;6N77=GINb=Z(>a9#ETzayK)T~Jw&MMH>OIr#&;dC}is*2Mqdf&akCc=O@`qC+4i
z5Iu3w#1M@KqXCz8TIZd1wli&kkl2HVcAiZ8PUn5z_kG@-y;?yK06=cA0U%H0PH+kU
zl6dp}OR(|r8-RG+YLu`zbI}5TlOU6ToR41{9=uz^?dGTNL;wIMf|V3`d1Wj3y!#6`
zBLZ?xpKR~^2x}?~zA(_NUu3IaDB$tKma*XUdOZN~c=dLt_h_k!dbxm_*ibDM<n!c>
zlFX`g{k$X}yIe%$N)cn1LNu=q<K5OS7CNKPk1f&9-+dXiicCfAy8a*|m;2$mAHWmO
zXHGi+kV1-pHt+rM<gA>9_CS)*<?(PP8<}W6a5(^^keLBRMb50K&dQM@pmn94ZU=xQ
zQX)TlxfVQ_9);_LB~VUu;v|U_-?p*(;VWJ|=^7%ZGN6sBL~)dHv|OyK(wPKdmH>>A
zsX_mM4<gjHpqc8Q=uo450T?4i;CdW;`z|<XAntIp>L@`(cSNQKMFc$RtYbx{79<Tw
zWXi-A43v#7I@t_Ijx7TKV2n(H{k|uniNrjlLmWw}y*t^*R9a-QX?;6B==9%$de=Kk
z*QYpi761&SjtX%clomR5cK>#j-J7hk*>*+ZZhM4Hw?<fJyv$}=71o`ou(^pUn-ky6
z->I?rsXCi#mRWJ=-0LGV5a-WR0Qgt<|Nqf)C-@80`5gIz45^_20000<MNUMnLSTaR
CZX#j;

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/folderopen.png b/ld_client/doc/pdoc/folderopen.png
new file mode 100644
index 0000000000000000000000000000000000000000..d6c7f676a3b3ef8c2c307d319dff3c6a604eb227
GIT binary patch
literal 597
zcmV-b0;>IqP)<h;3K|Lk000e1NJLTq000;O000&U1^@s6+I?Jz0006UNkl<ZcmeHQ
zKX21e5dS%8nlx#!9XpK>X=#(TiCT&PiIIVc55T}TU}EUh*{q$|`3@{d>{Tc9Bo>e=
zfmF3!f>fbI9#GoEHh0f`i5)wkLpva0ztf%HpZneK?w-7AK@b4Itw{y|Zd3k!fH?q2
zlhckHd_V2M_X7+)U&_Xcfvtw60l;--DgZmLSw-Y?S>)zIqMyJ1#FwLU*%bl38ok+!
zh78H87n`ZTS;uhzAR$M`zZ`bVhq=+%u9^$5jDplgxd44}9;IRqUH1YHH|@6oFe%z(
zo4)_>E$F&^P-f(#)>(TrnbE>Pefs9~@iN=|)Rz|V`sGfHNrJ)0gJb8xx+SBmRf@1l
zvuzt=vGfI)<-F9!o&3l?>9~0QbUDT(wFdnQPv%xdD)m*g%!20>Bc9iYmGAp<9YAa(
z0QgY<a!3GSVHw98r3tc|WLmCr=#k@b07--d0B^h;_*7huEOe@B5HbiIMnQNV2X-w6
zOrIHW*Nh!-3RJ{NFA7|xb7mLqy*mtQR%uj&==!8@USn{@{Ji@c`@7F#U6jIrqNF?z
zhGG8IoU)VO(*u}!lcNr&IgdJw?)fXgkFy?t@!%{)3!Y}PHt9|Ph>gTWqf1qN++Gqp
z8@AYPTB3E|6s=WLG?xw0tm|U!o=&zd+H0oRYE;Dbx+Na9s^STqX|Gnq%H8s(nGDGJ
j8vwW|`Ts`)fSK|Kx=IK@RG@g200000NkvXXu0mjfauFEA

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/functions.html b/ld_client/doc/pdoc/functions.html
new file mode 100644
index 0000000..e5d185c
--- /dev/null
+++ b/ld_client/doc/pdoc/functions.html
@@ -0,0 +1,189 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Members</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('functions.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+<div class="textblock">Here is a list of all documented class members with links to the class documentation for each member:</div>
+
+<h3><a id="index__5F" name="index__5F"></a>- _ -</h3><ul>
+<li>_client&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">LDClient.network.ApiClient</a></li>
+</ul>
+
+
+<h3><a id="index_a" name="index_a"></a>- a -</h3><ul>
+<li>ALogger()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">LDClient.utils.loggers.ALogger</a></li>
+<li>ApiClient()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">LDClient.network.ApiClient</a></li>
+</ul>
+
+
+<h3><a id="index_b" name="index_b"></a>- b -</h3><ul>
+<li>BodyDevice&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">LDClient.network.data.Payload</a></li>
+<li>BodySerialNumber&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a></li>
+</ul>
+
+
+<h3><a id="index_c" name="index_c"></a>- c -</h3><ul>
+<li>ClientRunning&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">LDClient.network.ApiClient</a></li>
+<li>ComposeLogRow()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">LDClient.utils.loggers.ALogger</a></li>
+<li>CreateLog()&#160;:&#160;<a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">FileLogger</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a></li>
+<li>Current&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_d" name="index_d"></a>- d -</h3><ul>
+<li>Debug()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">LDClient.utils.loggers.ALogger</a></li>
+<li>DetectionRunning&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">LDClient.detection.ProcessDetection</a></li>
+<li>Dispose()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_e" name="index_e"></a>- e -</h3><ul>
+<li>Error()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">LDClient.utils.loggers.ALogger</a></li>
+<li>ExecuteNewProcess()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a></li>
+</ul>
+
+
+<h3><a id="index_f" name="index_f"></a>- f -</h3><ul>
+<li>FetchDataAsync()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a></li>
+<li>FileUtils&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">LDClient.detection.InfoFetcher</a></li>
+<li>Flush()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_h" name="index_h"></a>- h -</h3><ul>
+<li>HeadDevice&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">LDClient.network.data.Payload</a></li>
+<li>HeadSerialNumber&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a></li>
+<li>HostName&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">LDClient.network.data.Payload</a></li>
+<li>HttpClient()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">LDClient.network.HttpClient</a></li>
+</ul>
+
+
+<h3><a id="index_i" name="index_i"></a>- i -</h3><ul>
+<li>Info()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">LDClient.utils.loggers.ALogger</a></li>
+<li>InfoFetcher()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">LDClient.detection.InfoFetcher</a></li>
+<li>IsProcessRunning()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a></li>
+</ul>
+
+
+<h3><a id="index_p" name="index_p"></a>- p -</h3><ul>
+<li>ParseToJson()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">LDClient.network.data.Payload</a></li>
+<li>PostAsJsonAsync()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a></li>
+<li>ProcessDetection()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">LDClient.detection.ProcessDetection</a></li>
+<li>ProcessUtils&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">LDClient.detection.InfoFetcher</a></li>
+</ul>
+
+
+<h3><a id="index_r" name="index_r"></a>- r -</h3><ul>
+<li>ReadFileAllLines()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>, <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a></li>
+<li>Run()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a></li>
+<li>RunPeriodicDetection()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">LDClient.detection.ProcessDetection</a></li>
+</ul>
+
+
+<h3><a id="index_s" name="index_s"></a>- s -</h3><ul>
+<li>SendPayloadAsync()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a></li>
+<li>SerialNumber&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">LDClient.network.data.DebuggerInfo</a></li>
+<li>Status&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">LDClient.network.data.Payload</a></li>
+</ul>
+
+
+<h3><a id="index_t" name="index_t"></a>- t -</h3><ul>
+<li>TimeStamp&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">LDClient.network.data.Payload</a></li>
+<li>ToString()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">LDClient.network.data.Payload</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_u" name="index_u"></a>- u -</h3><ul>
+<li>UnwrapExceptionMessages()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">LDClient.utils.loggers.ALogger</a></li>
+<li>UserName&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">LDClient.network.data.Payload</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/functions_func.html b/ld_client/doc/pdoc/functions_func.html
new file mode 100644
index 0000000..044f868
--- /dev/null
+++ b/ld_client/doc/pdoc/functions_func.html
@@ -0,0 +1,166 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Members - Functions</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('functions_func.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+&#160;
+
+<h3><a id="index_a" name="index_a"></a>- a -</h3><ul>
+<li>ALogger()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3">LDClient.utils.loggers.ALogger</a></li>
+<li>ApiClient()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73">LDClient.network.ApiClient</a></li>
+</ul>
+
+
+<h3><a id="index_c" name="index_c"></a>- c -</h3><ul>
+<li>ComposeLogRow()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b">LDClient.utils.loggers.ALogger</a></li>
+<li>CreateLog()&#160;:&#160;<a class="el" href="class_file_logger.html#ad39844b2267623f858ab77e6f5433896">FileLogger</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7">LDClient.utils.loggers.ConsoleLogger</a></li>
+</ul>
+
+
+<h3><a id="index_d" name="index_d"></a>- d -</h3><ul>
+<li>Debug()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81">LDClient.utils.loggers.ALogger</a></li>
+<li>Dispose()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_e" name="index_e"></a>- e -</h3><ul>
+<li>Error()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504">LDClient.utils.loggers.ALogger</a></li>
+<li>ExecuteNewProcess()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a></li>
+</ul>
+
+
+<h3><a id="index_f" name="index_f"></a>- f -</h3><ul>
+<li>FetchDataAsync()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a></li>
+<li>Flush()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_h" name="index_h"></a>- h -</h3><ul>
+<li>HttpClient()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3">LDClient.network.HttpClient</a></li>
+</ul>
+
+
+<h3><a id="index_i" name="index_i"></a>- i -</h3><ul>
+<li>Info()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e">LDClient.utils.loggers.ALogger</a></li>
+<li>InfoFetcher()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26">LDClient.detection.InfoFetcher</a></li>
+<li>IsProcessRunning()&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">LDClient.detection.IProcessUtils</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a></li>
+</ul>
+
+
+<h3><a id="index_p" name="index_p"></a>- p -</h3><ul>
+<li>ParseToJson()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57">LDClient.network.data.Payload</a></li>
+<li>PostAsJsonAsync()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">LDClient.network.IHttpClient</a></li>
+<li>ProcessDetection()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679">LDClient.detection.ProcessDetection</a></li>
+</ul>
+
+
+<h3><a id="index_r" name="index_r"></a>- r -</h3><ul>
+<li>ReadFileAllLines()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>, <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">LDClient.utils.IFileUtils</a></li>
+<li>Run()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">LDClient.network.IApiClient</a></li>
+<li>RunPeriodicDetection()&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8">LDClient.detection.ProcessDetection</a></li>
+</ul>
+
+
+<h3><a id="index_s" name="index_s"></a>- s -</h3><ul>
+<li>SendPayloadAsync()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>, <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">LDClient.network.IApiClient</a></li>
+</ul>
+
+
+<h3><a id="index_t" name="index_t"></a>- t -</h3><ul>
+<li>ToString()&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148">LDClient.network.data.Payload</a>, <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+
+
+<h3><a id="index_u" name="index_u"></a>- u -</h3><ul>
+<li>UnwrapExceptionMessages()&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea">LDClient.utils.loggers.ALogger</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/functions_prop.html b/ld_client/doc/pdoc/functions_prop.html
new file mode 100644
index 0000000..e899b21
--- /dev/null
+++ b/ld_client/doc/pdoc/functions_prop.html
@@ -0,0 +1,107 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Members - Properties</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('functions_prop.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+&#160;<ul>
+<li>BodyDevice&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208">LDClient.network.data.Payload</a></li>
+<li>BodySerialNumber&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a></li>
+<li>Current&#160;:&#160;<a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f">LDClient.utils.loggers.ALogger</a></li>
+<li>HeadDevice&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5">LDClient.network.data.Payload</a></li>
+<li>HeadSerialNumber&#160;:&#160;<a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">LDClient.detection.IInfoFetcher</a>, <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a></li>
+<li>HostName&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72">LDClient.network.data.Payload</a></li>
+<li>SerialNumber&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb">LDClient.network.data.DebuggerInfo</a></li>
+<li>Status&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481">LDClient.network.data.Payload</a></li>
+<li>TimeStamp&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297">LDClient.network.data.Payload</a></li>
+<li>UserName&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65">LDClient.network.data.Payload</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/functions_vars.html b/ld_client/doc/pdoc/functions_vars.html
new file mode 100644
index 0000000..77d1832
--- /dev/null
+++ b/ld_client/doc/pdoc/functions_vars.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Members - Variables</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('functions_vars.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+&#160;<ul>
+<li>_client&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d">LDClient.network.ApiClient</a></li>
+<li>ClientRunning&#160;:&#160;<a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1">LDClient.network.ApiClient</a></li>
+<li>DetectionRunning&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6">LDClient.detection.ProcessDetection</a></li>
+<li>FileUtils&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140">LDClient.detection.InfoFetcher</a></li>
+<li>ProcessUtils&#160;:&#160;<a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8">LDClient.detection.InfoFetcher</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/hierarchy.html b/ld_client/doc/pdoc/hierarchy.html
new file mode 100644
index 0000000..9a563d1
--- /dev/null
+++ b/ld_client/doc/pdoc/hierarchy.html
@@ -0,0 +1,120 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Class Hierarchy</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('hierarchy.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Class Hierarchy</div></div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">This inheritance list is sorted roughly, but not completely, alphabetically:</div><div class="directory">
+<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span>]</div><table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><b>ALogger</b></td><td class="desc"></td></tr>
+<tr id="row_0_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_file_logger.html" target="_self">FileLogger</a></td><td class="desc"></td></tr>
+<tr id="row_1_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">LDClient.network.data.DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr>
+<tr id="row_2_"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_2_" class="arrow" onclick="toggleFolder('2_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">LDClient.network.IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr>
+<tr id="row_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">LDClient.network.ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr>
+<tr id="row_3_"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_3_" class="arrow" onclick="toggleFolder('3_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><b>IDisposable</b></td><td class="desc"></td></tr>
+<tr id="row_3_0_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_3_0_" class="arrow" onclick="toggleFolder('3_0_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">LDClient.utils.loggers.ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr>
+<tr id="row_3_0_0_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">LDClient.utils.loggers.ConsoleLogger</a></td><td class="desc"></td></tr>
+<tr id="row_4_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_4_" class="arrow" onclick="toggleFolder('4_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">LDClient.utils.IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr>
+<tr id="row_4_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">LDClient.utils.FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr>
+<tr id="row_5_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_5_" class="arrow" onclick="toggleFolder('5_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">LDClient.network.IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr>
+<tr id="row_5_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">LDClient.network.HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr>
+<tr id="row_6_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_6_" class="arrow" onclick="toggleFolder('6_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">LDClient.detection.IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr>
+<tr id="row_6_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">LDClient.detection.InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr>
+<tr id="row_7_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_7_" class="arrow" onclick="toggleFolder('7_')">&#9660;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">LDClient.detection.IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr>
+<tr id="row_7_0_"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">LDClient.detection.ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr>
+<tr id="row_8_" class="even"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">LDClient.network.data.Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr>
+<tr id="row_9_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">LDClient.detection.ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/hierarchy.js b/ld_client/doc/pdoc/hierarchy.js
new file mode 100644
index 0000000..9ffe682
--- /dev/null
+++ b/ld_client/doc/pdoc/hierarchy.js
@@ -0,0 +1,29 @@
+var hierarchy =
+[
+    [ "ALogger", null, [
+      [ "FileLogger", "class_file_logger.html", null ]
+    ] ],
+    [ "LDClient.network.data.DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", null ],
+    [ "LDClient.network.IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", [
+      [ "LDClient.network.ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", null ]
+    ] ],
+    [ "IDisposable", null, [
+      [ "LDClient.utils.loggers.ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", [
+        [ "LDClient.utils.loggers.ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", null ]
+      ] ]
+    ] ],
+    [ "LDClient.utils.IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", [
+      [ "LDClient.utils.FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", null ]
+    ] ],
+    [ "LDClient.network.IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", [
+      [ "LDClient.network.HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", null ]
+    ] ],
+    [ "LDClient.detection.IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", [
+      [ "LDClient.detection.InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", null ]
+    ] ],
+    [ "LDClient.detection.IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", [
+      [ "LDClient.detection.ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", null ]
+    ] ],
+    [ "LDClient.network.data.Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", null ],
+    [ "LDClient.detection.ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/index.html b/ld_client/doc/pdoc/index.html
new file mode 100644
index 0000000..c018938
--- /dev/null
+++ b/ld_client/doc/pdoc/index.html
@@ -0,0 +1,98 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Main Page</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('index.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient Documentation</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html
new file mode 100644
index 0000000..c5ee33f
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html
@@ -0,0 +1,104 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.detection.IInfoFetcher Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a></td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a>()</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr>
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a></td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">LDClient.detection.IInfoFetcher</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
new file mode 100644
index 0000000..30955ae
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
@@ -0,0 +1,203 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection.IInfoFetcher Interface Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="#properties">Properties</a> &#124;
+<a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection.IInfoFetcher Interface Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger.  
+ <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memItemLeft" align="right" valign="top">Task&lt; bool &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">FetchDataAsync</a> ()</td></tr>
+<tr class="memdesc:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers).  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9">More...</a><br /></td></tr>
+<tr class="separator:a115b4d4fb74bd4eb09d8eeb4716793f9"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="properties" name="properties"></a>
+Properties</h2></td></tr>
+<tr class="memitem:a196620b51706ff95e86dce886bd3d3a0"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">HeadSerialNumber</a><code> [get, set]</code></td></tr>
+<tr class="memdesc:a196620b51706ff95e86dce886bd3d3a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the head serial number of the debugger.  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0">More...</a><br /></td></tr>
+<tr class="separator:a196620b51706ff95e86dce886bd3d3a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:afff68b22c92585ba9169cd558bcb66b9"><td class="memItemLeft" align="right" valign="top">string&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">BodySerialNumber</a><code> [get, set]</code></td></tr>
+<tr class="memdesc:afff68b22c92585ba9169cd558bcb66b9"><td class="mdescLeft">&#160;</td><td class="mdescRight">Returns the body serial number of the debugger.  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9">More...</a><br /></td></tr>
+<tr class="separator:afff68b22c92585ba9169cd558bcb66b9"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a115b4d4fb74bd4eb09d8eeb4716793f9" name="a115b4d4fb74bd4eb09d8eeb4716793f9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a115b4d4fb74bd4eb09d8eeb4716793f9">&#9670;&nbsp;</a></span>FetchDataAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">Task&lt; bool &gt; LDClient.detection.IInfoFetcher.FetchDataAsync </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Fetches data from the debugger. It sends the commands defined in the appsettings.json file to the debugger and tries to parse the .txt (contains the serial numbers). </p>
+<dl class="section return"><dt>Returns</dt><dd>True, if data was fetched successfully. False otherwise.</dd></dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c">LDClient.detection.InfoFetcher</a>.</p>
+
+</div>
+</div>
+<h2 class="groupheader">Property Documentation</h2>
+<a id="afff68b22c92585ba9169cd558bcb66b9" name="afff68b22c92585ba9169cd558bcb66b9"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#afff68b22c92585ba9169cd558bcb66b9">&#9670;&nbsp;</a></span>BodySerialNumber</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">string LDClient.detection.IInfoFetcher.BodySerialNumber</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Returns the body serial number of the debugger. </p>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d">LDClient.detection.InfoFetcher</a>.</p>
+
+</div>
+</div>
+<a id="a196620b51706ff95e86dce886bd3d3a0" name="a196620b51706ff95e86dce886bd3d3a0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a196620b51706ff95e86dce886bd3d3a0">&#9670;&nbsp;</a></span>HeadSerialNumber</h2>
+
+<div class="memitem">
+<div class="memproto">
+<table class="mlabels">
+  <tr>
+  <td class="mlabels-left">
+      <table class="memname">
+        <tr>
+          <td class="memname">string LDClient.detection.IInfoFetcher.HeadSerialNumber</td>
+        </tr>
+      </table>
+  </td>
+  <td class="mlabels-right">
+<span class="mlabels"><span class="mlabel">get</span><span class="mlabel">set</span></span>  </td>
+  </tr>
+</table>
+</div><div class="memdoc">
+
+<p>Returns the head serial number of the debugger. </p>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f">LDClient.detection.InfoFetcher</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this interface was generated from the following file:<ul>
+<li>detection/IInfoFetcher.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js
new file mode 100644
index 0000000..5838d30
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.js
@@ -0,0 +1,6 @@
+var interface_l_d_client_1_1detection_1_1_i_info_fetcher =
+[
+    [ "FetchDataAsync", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9", null ],
+    [ "BodySerialNumber", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9", null ],
+    [ "HeadSerialNumber", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html
new file mode 100644
index 0000000..8058f80
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils-members.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_process_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.detection.IProcessUtils Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a>(string fileName, string argument, int timeout, int desiredExitCode)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a>(string name)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">LDClient.detection.IProcessUtils</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
new file mode 100644
index 0000000..24e7373
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
@@ -0,0 +1,204 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection.IProcessUtils Interface Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1detection_1_1_i_process_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="interface_l_d_client_1_1detection_1_1_i_process_utils-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection.IProcessUtils Interface Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This interface defines the functionality of all methods that are used to work with processes (within this project).  
+ <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">IsProcessRunning</a> (string name)</td></tr>
+<tr class="memdesc:ad86c09b9bd71f7087ada92851b07e1a0"><td class="mdescLeft">&#160;</td><td class="mdescRight">Checks if a process is running or not.  <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0">More...</a><br /></td></tr>
+<tr class="separator:ad86c09b9bd71f7087ada92851b07e1a0"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ab7e48a228ebaf7dddc671e5af2325662"><td class="memItemLeft" align="right" valign="top">bool&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">ExecuteNewProcess</a> (string fileName, string argument, int timeout, int desiredExitCode)</td></tr>
+<tr class="memdesc:ab7e48a228ebaf7dddc671e5af2325662"><td class="mdescLeft">&#160;</td><td class="mdescRight">Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method.  <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662">More...</a><br /></td></tr>
+<tr class="separator:ab7e48a228ebaf7dddc671e5af2325662"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This interface defines the functionality of all methods that are used to work with processes (within this project). </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="ab7e48a228ebaf7dddc671e5af2325662" name="ab7e48a228ebaf7dddc671e5af2325662"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ab7e48a228ebaf7dddc671e5af2325662">&#9670;&nbsp;</a></span>ExecuteNewProcess()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool LDClient.detection.IProcessUtils.ExecuteNewProcess </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>fileName</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>argument</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>timeout</em>, </td>
+        </tr>
+        <tr>
+          <td class="paramkey"></td>
+          <td></td>
+          <td class="paramtype">int&#160;</td>
+          <td class="paramname"><em>desiredExitCode</em>&#160;</td>
+        </tr>
+        <tr>
+          <td></td>
+          <td>)</td>
+          <td></td><td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Executes a new process (t32rem.exe) with arguments which are passed in as a parameter of the method. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">fileName</td><td>Path to the .exe file</td></tr>
+    <tr><td class="paramname">argument</td><td>Arguments passed into the .exe file</td></tr>
+    <tr><td class="paramname">timeout</td><td>Timeout used when waiting for the process to terminate</td></tr>
+    <tr><td class="paramname">desiredExitCode</td><td>Status code indicating a successful termination of the process.</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>True, if the command was executed successfully. False otherwise.</dd></dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557">LDClient.detection.ProcessUtils</a>.</p>
+
+</div>
+</div>
+<a id="ad86c09b9bd71f7087ada92851b07e1a0" name="ad86c09b9bd71f7087ada92851b07e1a0"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ad86c09b9bd71f7087ada92851b07e1a0">&#9670;&nbsp;</a></span>IsProcessRunning()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">bool LDClient.detection.IProcessUtils.IsProcessRunning </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>name</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Checks if a process is running or not. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">name</td><td>Name of the process</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>True, if the process is running. False otherwise.</dd></dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4">LDClient.detection.ProcessUtils</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this interface was generated from the following file:<ul>
+<li>detection/IProcessUtils.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js
new file mode 100644
index 0000000..481e8ab
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.js
@@ -0,0 +1,5 @@
+var interface_l_d_client_1_1detection_1_1_i_process_utils =
+[
+    [ "ExecuteNewProcess", "interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662", null ],
+    [ "IsProcessRunning", "interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html
new file mode 100644
index 0000000..dab2bcc
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client-members.html
@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_api_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.IApiClient Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a>()</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a></td><td class="entry"></td></tr>
+  <tr class="odd"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">LDClient.network.IApiClient</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
new file mode 100644
index 0000000..e333b90
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
@@ -0,0 +1,170 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.IApiClient Interface Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_api_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="interface_l_d_client_1_1network_1_1_i_api_client-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.IApiClient Interface Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This interface defines the functionality of an API client which is used to send information (payloads) to the server.  
+ <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memItemLeft" align="right" valign="top">Task&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">SendPayloadAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Sends a payload to the server (API).  <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f">More...</a><br /></td></tr>
+<tr class="separator:a8edc6823e4fb6f476a88af2da18e3b7f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memItemLeft" align="right" valign="top">void&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">Run</a> ()</td></tr>
+<tr class="memdesc:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="mdescLeft">&#160;</td><td class="mdescRight">Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread.  <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb">More...</a><br /></td></tr>
+<tr class="separator:ab668a6e4e3f1d219c38f5e323d8735cb"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This interface defines the functionality of an API client which is used to send information (payloads) to the server. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="ab668a6e4e3f1d219c38f5e323d8735cb" name="ab668a6e4e3f1d219c38f5e323d8735cb"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ab668a6e4e3f1d219c38f5e323d8735cb">&#9670;&nbsp;</a></span>Run()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">void LDClient.network.IApiClient.Run </td>
+          <td>(</td>
+          <td class="paramname"></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Runs the periodical retrieval of failed payloads stored in a file-based cache. This method is instantiated as a thread. </p>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979">LDClient.network.ApiClient</a>.</p>
+
+</div>
+</div>
+<a id="a8edc6823e4fb6f476a88af2da18e3b7f" name="a8edc6823e4fb6f476a88af2da18e3b7f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a8edc6823e4fb6f476a88af2da18e3b7f">&#9670;&nbsp;</a></span>SendPayloadAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">Task LDClient.network.IApiClient.SendPayloadAsync </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a>&#160;</td>
+          <td class="paramname"><em>payload</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Sends a payload to the server (API). </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">payload</td><td>instance of a payload to be sent off to the server</td></tr>
+  </table>
+  </dd>
+</dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55">LDClient.network.ApiClient</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this interface was generated from the following file:<ul>
+<li>network/IApiClient.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js
new file mode 100644
index 0000000..2cb6345
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.js
@@ -0,0 +1,5 @@
+var interface_l_d_client_1_1network_1_1_i_api_client =
+[
+    [ "Run", "interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb", null ],
+    [ "SendPayloadAsync", "interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html
new file mode 100644
index 0000000..57a319d
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client-members.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_http_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.network.IHttpClient Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">LDClient.network.IHttpClient</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a>(Payload payload)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">LDClient.network.IHttpClient</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
new file mode 100644
index 0000000..c09212a
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.IHttpClient Interface Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1network_1_1_i_http_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="interface_l_d_client_1_1network_1_1_i_http_client-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.IHttpClient Interface Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server.  
+ <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:a241d7baceaf176b341c46844e235bd0f"><td class="memItemLeft" align="right" valign="top">Task&lt; HttpResponseMessage &gt;&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">PostAsJsonAsync</a> (<a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a> payload)</td></tr>
+<tr class="memdesc:a241d7baceaf176b341c46844e235bd0f"><td class="mdescLeft">&#160;</td><td class="mdescRight">Asynchronically sends data in JSON format to the server.  <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f">More...</a><br /></td></tr>
+<tr class="separator:a241d7baceaf176b341c46844e235bd0f"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="a241d7baceaf176b341c46844e235bd0f" name="a241d7baceaf176b341c46844e235bd0f"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a241d7baceaf176b341c46844e235bd0f">&#9670;&nbsp;</a></span>PostAsJsonAsync()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">Task&lt; HttpResponseMessage &gt; LDClient.network.IHttpClient.PostAsJsonAsync </td>
+          <td>(</td>
+          <td class="paramtype"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a>&#160;</td>
+          <td class="paramname"><em>payload</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Asynchronically sends data in JSON format to the server. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">payload</td><td>Payload to be sent to the server</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd></dd></dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d">LDClient.network.HttpClient</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this interface was generated from the following file:<ul>
+<li>network/IHttpClient.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js
new file mode 100644
index 0000000..3786abf
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.js
@@ -0,0 +1,4 @@
+var interface_l_d_client_1_1network_1_1_i_http_client =
+[
+    [ "PostAsJsonAsync", "interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html
new file mode 100644
index 0000000..1938d06
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils-members.html
@@ -0,0 +1,102 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Member List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1utils_1_1_i_file_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient.utils.IFileUtils Member List</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This is the complete list of members for <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">LDClient.utils.IFileUtils</a>, including all inherited members.</p>
+<table class="directory">
+  <tr class="even"><td class="entry"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a>(string file)</td><td class="entry"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">LDClient.utils.IFileUtils</a></td><td class="entry"></td></tr>
+</table></div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
new file mode 100644
index 0000000..dd550a8
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
@@ -0,0 +1,147 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils.IFileUtils Interface Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('interface_l_d_client_1_1utils_1_1_i_file_utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#pub-methods">Public Member Functions</a> &#124;
+<a href="interface_l_d_client_1_1utils_1_1_i_file_utils-members.html">List of all members</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils.IFileUtils Interface Reference</div></div>
+</div><!--header-->
+<div class="contents">
+
+<p>This interface defines IO operations.  
+ <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#details">More...</a></p>
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="pub-methods" name="pub-methods"></a>
+Public Member Functions</h2></td></tr>
+<tr class="memitem:ae4d668d0e5850831680c8793cecd89a3"><td class="memItemLeft" align="right" valign="top">string[]&#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">ReadFileAllLines</a> (string file)</td></tr>
+<tr class="memdesc:ae4d668d0e5850831680c8793cecd89a3"><td class="mdescLeft">&#160;</td><td class="mdescRight">Reads all lines of a files and returns them as a array.  <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3">More...</a><br /></td></tr>
+<tr class="separator:ae4d668d0e5850831680c8793cecd89a3"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
+<div class="textblock"><p >This interface defines IO operations. </p>
+</div><h2 class="groupheader">Member Function Documentation</h2>
+<a id="ae4d668d0e5850831680c8793cecd89a3" name="ae4d668d0e5850831680c8793cecd89a3"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#ae4d668d0e5850831680c8793cecd89a3">&#9670;&nbsp;</a></span>ReadFileAllLines()</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">string[] LDClient.utils.IFileUtils.ReadFileAllLines </td>
+          <td>(</td>
+          <td class="paramtype">string&#160;</td>
+          <td class="paramname"><em>file</em></td><td>)</td>
+          <td></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>Reads all lines of a files and returns them as a array. </p>
+<dl class="params"><dt>Parameters</dt><dd>
+  <table class="params">
+    <tr><td class="paramname">file</td><td>path to the file</td></tr>
+  </table>
+  </dd>
+</dl>
+<dl class="section return"><dt>Returns</dt><dd>all the lines of the file (as an array)</dd></dl>
+
+<p>Implemented in <a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737">LDClient.utils.FileUtils</a>.</p>
+
+</div>
+</div>
+<hr/>The documentation for this interface was generated from the following file:<ul>
+<li>utils/IFileUtils.cs</li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js
new file mode 100644
index 0000000..a033d8b
--- /dev/null
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.js
@@ -0,0 +1,4 @@
+var interface_l_d_client_1_1utils_1_1_i_file_utils =
+[
+    [ "ReadFileAllLines", "interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3", null ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/jquery.js b/ld_client/doc/pdoc/jquery.js
new file mode 100644
index 0000000..c9ed3d9
--- /dev/null
+++ b/ld_client/doc/pdoc/jquery.js
@@ -0,0 +1,35 @@
+/*! jQuery v3.6.0 | (c) OpenJS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType&&"function"!=typeof e.item},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.6.0",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0<t&&t-1 in e)}S.fn=S.prototype={jquery:f,constructor:S,length:0,toArray:function(){return s.call(this)},get:function(e){return null==e?s.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=S.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return S.each(this,e)},map:function(n){return this.pushStack(S.map(this,function(e,t){return n.call(e,t,e)}))},slice:function(){return this.pushStack(s.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},even:function(){return this.pushStack(S.grep(this,function(e,t){return(t+1)%2}))},odd:function(){return this.pushStack(S.grep(this,function(e,t){return t%2}))},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(0<=n&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:u,sort:t.sort,splice:t.splice},S.extend=S.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||m(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)r=e[t],"__proto__"!==t&&a!==r&&(l&&r&&(S.isPlainObject(r)||(i=Array.isArray(r)))?(n=a[t],o=i&&!Array.isArray(n)?[]:i||S.isPlainObject(n)?n:{},i=!1,a[t]=S.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},S.extend({expando:"jQuery"+(f+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==o.call(e))&&(!(t=r(e))||"function"==typeof(n=v.call(t,"constructor")&&t.constructor)&&a.call(n)===l)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e,t,n){b(e,{nonce:t&&t.nonce},n)},each:function(e,t){var n,r=0;if(p(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},makeArray:function(e,t){var n=t||[];return null!=e&&(p(Object(e))?S.merge(n,"string"==typeof e?[e]:e):u.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:i.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r=[],i=0,o=e.length,a=!n;i<o;i++)!t(e[i],i)!==a&&r.push(e[i]);return r},map:function(e,t,n){var r,i,o=0,a=[];if(p(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&a.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&a.push(i);return g(a)},guid:1,support:y}),"function"==typeof Symbol&&(S.fn[Symbol.iterator]=t[Symbol.iterator]),S.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){n["[object "+t+"]"]=t.toLowerCase()});var d=function(n){var e,d,b,o,i,h,f,g,w,u,l,T,C,a,E,v,s,c,y,S="sizzle"+1*new Date,p=n.document,k=0,r=0,m=ue(),x=ue(),A=ue(),N=ue(),j=function(e,t){return e===t&&(l=!0),0},D={}.hasOwnProperty,t=[],q=t.pop,L=t.push,H=t.push,O=t.slice,P=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},R="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",M="[\\x20\\t\\r\\n\\f]",I="(?:\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+",W="\\["+M+"*("+I+")(?:"+M+"*([*^$|!~]?=)"+M+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+I+"))|)"+M+"*\\]",F=":("+I+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+W+")*)|.*)\\)|)",B=new RegExp(M+"+","g"),$=new RegExp("^"+M+"+|((?:^|[^\\\\])(?:\\\\.)*)"+M+"+$","g"),_=new RegExp("^"+M+"*,"+M+"*"),z=new RegExp("^"+M+"*([>+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e&&e.namespaceURI,n=e&&(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML="<a id='"+S+"'></a><select id='"+S+"-\r\\' msallowcapture=''><option selected=''></option></select>",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="<a href='' disabled='disabled'></a><select disabled='disabled'><option/></select>";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},j=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0<se(t,C,null,[e]).length},se.contains=function(e,t){return(e.ownerDocument||e)!=C&&T(e),y(e,t)},se.attr=function(e,t){(e.ownerDocument||e)!=C&&T(e);var n=b.attrHandle[t.toLowerCase()],r=n&&D.call(b.attrHandle,t.toLowerCase())?n(e,t,!E):void 0;return void 0!==r?r:d.attributes||!E?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},se.escape=function(e){return(e+"").replace(re,ie)},se.error=function(e){throw new Error("Syntax error, unrecognized expression: "+e)},se.uniqueSort=function(e){var t,n=[],r=0,i=0;if(l=!d.detectDuplicates,u=!d.sortStable&&e.slice(0),e.sort(j),l){while(t=e[i++])t===e[i]&&(r=n.push(i));while(r--)e.splice(n[r],1)}return u=null,e},o=se.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else while(t=e[r++])n+=o(t);return n},(b=se.selectors={cacheLength:50,createPseudo:le,match:G,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1<t.indexOf(i):"$="===r?i&&t.slice(-i.length)===i:"~="===r?-1<(" "+t.replace(B," ")+" ").indexOf(i):"|="===r&&(t===i||t.slice(0,i.length+1)===i+"-"))}},CHILD:function(h,e,t,g,v){var y="nth"!==h.slice(0,3),m="last"!==h.slice(-4),x="of-type"===e;return 1===g&&0===v?function(e){return!!e.parentNode}:function(e,t,n){var r,i,o,a,s,u,l=y!==m?"nextSibling":"previousSibling",c=e.parentNode,f=x&&e.nodeName.toLowerCase(),p=!n&&!x,d=!1;if(c){if(y){while(l){a=e;while(a=a[l])if(x?a.nodeName.toLowerCase()===f:1===a.nodeType)return!1;u=l="only"===h&&!u&&"nextSibling"}return!0}if(u=[m?c.firstChild:c.lastChild],m&&p){d=(s=(r=(i=(o=(a=c)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1])&&r[2],a=s&&c.childNodes[s];while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if(1===a.nodeType&&++d&&a===e){i[h]=[k,s,d];break}}else if(p&&(d=s=(r=(i=(o=(a=e)[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]||[])[0]===k&&r[1]),!1===d)while(a=++s&&a&&a[l]||(d=s=0)||u.pop())if((x?a.nodeName.toLowerCase()===f:1===a.nodeType)&&++d&&(p&&((i=(o=a[S]||(a[S]={}))[a.uniqueID]||(o[a.uniqueID]={}))[h]=[k,d]),a===e))break;return(d-=v)===g||d%g==0&&0<=d/g}}},PSEUDO:function(e,o){var t,a=b.pseudos[e]||b.setFilters[e.toLowerCase()]||se.error("unsupported pseudo: "+e);return a[S]?a(o):1<a.length?(t=[e,e,"",o],b.setFilters.hasOwnProperty(e.toLowerCase())?le(function(e,t){var n,r=a(e,o),i=r.length;while(i--)e[n=P(e,r[i])]=!(t[n]=r[i])}):function(e){return a(e,0,t)}):a}},pseudos:{not:le(function(e){var r=[],i=[],s=f(e.replace($,"$1"));return s[S]?le(function(e,t,n,r){var i,o=s(e,null,r,[]),a=e.length;while(a--)(i=o[a])&&(e[a]=!(t[a]=i))}):function(e,t,n){return r[0]=e,s(r,null,n,i),r[0]=null,!i.pop()}}),has:le(function(t){return function(e){return 0<se(t,e).length}}),contains:le(function(t){return t=t.replace(te,ne),function(e){return-1<(e.textContent||o(e)).indexOf(t)}}),lang:le(function(n){return V.test(n||"")||se.error("unsupported lang: "+n),n=n.replace(te,ne).toLowerCase(),function(e){var t;do{if(t=E?e.lang:e.getAttribute("xml:lang")||e.getAttribute("lang"))return(t=t.toLowerCase())===n||0===t.indexOf(n+"-")}while((e=e.parentNode)&&1===e.nodeType);return!1}}),target:function(e){var t=n.location&&n.location.hash;return t&&t.slice(1)===e.id},root:function(e){return e===a},focus:function(e){return e===C.activeElement&&(!C.hasFocus||C.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:ge(!1),disabled:ge(!0),checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,!0===e.selected},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!b.pseudos.empty(e)},header:function(e){return J.test(e.nodeName)},input:function(e){return Q.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||"text"===t.toLowerCase())},first:ve(function(){return[0]}),last:ve(function(e,t){return[t-1]}),eq:ve(function(e,t,n){return[n<0?n+t:n]}),even:ve(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:ve(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:ve(function(e,t,n){for(var r=n<0?n+t:t<n?t:n;0<=--r;)e.push(r);return e}),gt:ve(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}}).pseudos.nth=b.pseudos.eq,{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})b.pseudos[e]=de(e);for(e in{submit:!0,reset:!0})b.pseudos[e]=he(e);function me(){}function xe(e){for(var t=0,n=e.length,r="";t<n;t++)r+=e[t].value;return r}function be(s,e,t){var u=e.dir,l=e.next,c=l||u,f=t&&"parentNode"===c,p=r++;return e.first?function(e,t,n){while(e=e[u])if(1===e.nodeType||f)return s(e,t,n);return!1}:function(e,t,n){var r,i,o,a=[k,p];if(n){while(e=e[u])if((1===e.nodeType||f)&&s(e,t,n))return!0}else while(e=e[u])if(1===e.nodeType||f)if(i=(o=e[S]||(e[S]={}))[e.uniqueID]||(o[e.uniqueID]={}),l&&l===e.nodeName.toLowerCase())e=e[u]||e;else{if((r=i[c])&&r[0]===k&&r[1]===p)return a[2]=r[2];if((i[c]=a)[2]=s(e,t,n))return!0}return!1}}function we(i){return 1<i.length?function(e,t,n){var r=i.length;while(r--)if(!i[r](e,t,n))return!1;return!0}:i[0]}function Te(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function Ce(d,h,g,v,y,e){return v&&!v[S]&&(v=Ce(v)),y&&!y[S]&&(y=Ce(y,e)),le(function(e,t,n,r){var i,o,a,s=[],u=[],l=t.length,c=e||function(e,t,n){for(var r=0,i=t.length;r<i;r++)se(e,t[r],n);return n}(h||"*",n.nodeType?[n]:n,[]),f=!d||!e&&h?c:Te(c,s,d,n,r),p=g?y||(e?d:l||v)?[]:t:f;if(g&&g(f,p,n,r),v){i=Te(p,u),v(i,[],n,r),o=i.length;while(o--)(a=i[o])&&(p[u[o]]=!(f[u[o]]=a))}if(e){if(y||d){if(y){i=[],o=p.length;while(o--)(a=p[o])&&i.push(f[o]=a);y(null,p=[],i,r)}o=p.length;while(o--)(a=p[o])&&-1<(i=y?P(e,a):s[o])&&(e[i]=!(t[i]=a))}}else p=Te(p===t?p.splice(l,p.length):p),y?y(null,t,p,r):H.apply(t,p)})}function Ee(e){for(var i,t,n,r=e.length,o=b.relative[e[0].type],a=o||b.relative[" "],s=o?1:0,u=be(function(e){return e===i},a,!0),l=be(function(e){return-1<P(i,e)},a,!0),c=[function(e,t,n){var r=!o&&(n||t!==w)||((i=t).nodeType?u(e,t,n):l(e,t,n));return i=null,r}];s<r;s++)if(t=b.relative[e[s].type])c=[be(we(c),t)];else{if((t=b.filter[e[s].type].apply(null,e[s].matches))[S]){for(n=++s;n<r;n++)if(b.relative[e[n].type])break;return Ce(1<s&&we(c),1<s&&xe(e.slice(0,s-1).concat({value:" "===e[s-2].type?"*":""})).replace($,"$1"),t,s<n&&Ee(e.slice(s,n)),n<r&&Ee(e=e.slice(n)),n<r&&xe(e))}c.push(t)}return we(c)}return me.prototype=b.filters=b.pseudos,b.setFilters=new me,h=se.tokenize=function(e,t){var n,r,i,o,a,s,u,l=x[e+" "];if(l)return t?0:l.slice(0);a=e,s=[],u=b.preFilter;while(a){for(o in n&&!(r=_.exec(a))||(r&&(a=a.slice(r[0].length)||a),s.push(i=[])),n=!1,(r=z.exec(a))&&(n=r.shift(),i.push({value:n,type:r[0].replace($," ")}),a=a.slice(n.length)),b.filter)!(r=G[o].exec(a))||u[o]&&!(r=u[o](r))||(n=r.shift(),i.push({value:n,type:o,matches:r}),a=a.slice(n.length));if(!n)break}return t?a.length:a?se.error(e):x(e,s).slice(0)},f=se.compile=function(e,t){var n,v,y,m,x,r,i=[],o=[],a=A[e+" "];if(!a){t||(t=h(e)),n=t.length;while(n--)(a=Ee(t[n]))[S]?i.push(a):o.push(a);(a=A(e,(v=o,m=0<(y=i).length,x=0<v.length,r=function(e,t,n,r,i){var o,a,s,u=0,l="0",c=e&&[],f=[],p=w,d=e||x&&b.find.TAG("*",i),h=k+=null==p?1:Math.random()||.1,g=d.length;for(i&&(w=t==C||t||i);l!==g&&null!=(o=d[l]);l++){if(x&&o){a=0,t||o.ownerDocument==C||(T(o),n=!E);while(s=v[a++])if(s(o,t||C,n)){r.push(o);break}i&&(k=h)}m&&((o=!s&&o)&&u--,e&&c.push(o))}if(u+=l,m&&l!==u){a=0;while(s=y[a++])s(c,f,t,n);if(e){if(0<u)while(l--)c[l]||f[l]||(f[l]=q.call(r));f=Te(f)}H.apply(r,f),i&&!e&&0<f.length&&1<u+y.length&&se.uniqueSort(r)}return i&&(k=h,w=p),c},m?le(r):r))).selector=e}return a},g=se.select=function(e,t,n,r){var i,o,a,s,u,l="function"==typeof e&&e,c=!r&&h(e=l.selector||e);if(n=n||[],1===c.length){if(2<(o=c[0]=c[0].slice(0)).length&&"ID"===(a=o[0]).type&&9===t.nodeType&&E&&b.relative[o[1].type]){if(!(t=(b.find.ID(a.matches[0].replace(te,ne),t)||[])[0]))return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}i=G.needsContext.test(e)?0:o.length;while(i--){if(a=o[i],b.relative[s=a.type])break;if((u=b.find[s])&&(r=u(a.matches[0].replace(te,ne),ee.test(o[0].type)&&ye(t.parentNode)||t))){if(o.splice(i,1),!(e=r.length&&xe(o)))return H.apply(n,r),n;break}}}return(l||f(e,c))(r,t,!E,n,!t||ee.test(e)&&ye(t.parentNode)||t),n},d.sortStable=S.split("").sort(j).join("")===S,d.detectDuplicates=!!l,T(),d.sortDetached=ce(function(e){return 1&e.compareDocumentPosition(C.createElement("fieldset"))}),ce(function(e){return e.innerHTML="<a href='#'></a>","#"===e.firstChild.getAttribute("href")})||fe("type|href|height|width",function(e,t,n){if(!n)return e.getAttribute(t,"type"===t.toLowerCase()?1:2)}),d.attributes&&ce(function(e){return e.innerHTML="<input/>",e.firstChild.setAttribute("value",""),""===e.firstChild.getAttribute("value")})||fe("value",function(e,t,n){if(!n&&"input"===e.nodeName.toLowerCase())return e.defaultValue}),ce(function(e){return null==e.getAttribute("disabled")})||fe(R,function(e,t,n){var r;if(!n)return!0===e[t]?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),se}(C);S.find=d,S.expr=d.selectors,S.expr[":"]=S.expr.pseudos,S.uniqueSort=S.unique=d.uniqueSort,S.text=d.getText,S.isXMLDoc=d.isXML,S.contains=d.contains,S.escapeSelector=d.escape;var h=function(e,t,n){var r=[],i=void 0!==n;while((e=e[t])&&9!==e.nodeType)if(1===e.nodeType){if(i&&S(e).is(n))break;r.push(e)}return r},T=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},k=S.expr.match.needsContext;function A(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()}var N=/^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1<i.call(n,e)!==r}):S.filter(n,e,r)}S.filter=function(e,t,n){var r=t[0];return n&&(e=":not("+e+")"),1===t.length&&1===r.nodeType?S.find.matchesSelector(r,e)?[r]:[]:S.find.matches(e,S.grep(t,function(e){return 1===e.nodeType}))},S.fn.extend({find:function(e){var t,n,r=this.length,i=this;if("string"!=typeof e)return this.pushStack(S(e).filter(function(){for(t=0;t<r;t++)if(S.contains(i[t],this))return!0}));for(n=this.pushStack([]),t=0;t<r;t++)S.find(e,i[t],n);return 1<r?S.uniqueSort(n):n},filter:function(e){return this.pushStack(j(this,e||[],!1))},not:function(e){return this.pushStack(j(this,e||[],!0))},is:function(e){return!!j(this,"string"==typeof e&&k.test(e)?S(e):e||[],!1).length}});var D,q=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||D,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,D=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e<n;e++)if(S.contains(this,t[e]))return!0})},closest:function(e,t){var n,r=0,i=this.length,o=[],a="string"!=typeof e&&S(e);if(!k.test(e))for(;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?-1<a.index(n):1===n.nodeType&&S.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(1<o.length?S.uniqueSort(o):o)},index:function(e){return e?"string"==typeof e?i.call(S(e),this[0]):i.call(this,e.jquery?e[0]:e):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(S.uniqueSort(S.merge(this.get(),S(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),S.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return h(e,"parentNode")},parentsUntil:function(e,t,n){return h(e,"parentNode",n)},next:function(e){return O(e,"nextSibling")},prev:function(e){return O(e,"previousSibling")},nextAll:function(e){return h(e,"nextSibling")},prevAll:function(e){return h(e,"previousSibling")},nextUntil:function(e,t,n){return h(e,"nextSibling",n)},prevUntil:function(e,t,n){return h(e,"previousSibling",n)},siblings:function(e){return T((e.parentNode||{}).firstChild,e)},children:function(e){return T(e.firstChild)},contents:function(e){return null!=e.contentDocument&&r(e.contentDocument)?e.contentDocument:(A(e,"template")&&(e=e.content||e),S.merge([],e.childNodes))}},function(r,i){S.fn[r]=function(e,t){var n=S.map(this,i,e);return"Until"!==r.slice(-5)&&(t=e),t&&"string"==typeof t&&(n=S.filter(t,n)),1<this.length&&(H[r]||S.uniqueSort(n),L.test(r)&&n.reverse()),this.pushStack(n)}});var P=/[^\x20\t\r\n\f]+/g;function R(e){return e}function M(e){throw e}function I(e,t,n,r){var i;try{e&&m(i=e.promise)?i.call(e).done(t).fail(n):e&&m(i=e.then)?i.call(e,t,n):t.apply(void 0,[e].slice(r))}catch(e){n.apply(void 0,[e])}}S.Callbacks=function(r){var e,n;r="string"==typeof r?(e=r,n={},S.each(e.match(P)||[],function(e,t){n[t]=!0}),n):S.extend({},r);var i,t,o,a,s=[],u=[],l=-1,c=function(){for(a=a||r.once,o=i=!0;u.length;l=-1){t=u.shift();while(++l<s.length)!1===s[l].apply(t[0],t[1])&&r.stopOnFalse&&(l=s.length,t=!1)}r.memory||(t=!1),i=!1,a&&(s=t?[]:"")},f={add:function(){return s&&(t&&!i&&(l=s.length-1,u.push(t)),function n(e){S.each(e,function(e,t){m(t)?r.unique&&f.has(t)||s.push(t):t&&t.length&&"string"!==w(t)&&n(t)})}(arguments),t&&!i&&c()),this},remove:function(){return S.each(arguments,function(e,t){var n;while(-1<(n=S.inArray(t,s,n)))s.splice(n,1),n<=l&&l--}),this},has:function(e){return e?-1<S.inArray(e,s):0<s.length},empty:function(){return s&&(s=[]),this},disable:function(){return a=u=[],s=t="",this},disabled:function(){return!s},lock:function(){return a=u=[],t||i||(s=t=""),this},locked:function(){return!!a},fireWith:function(e,t){return a||(t=[e,(t=t||[]).slice?t.slice():t],u.push(t),i||c()),this},fire:function(){return f.fireWith(this,arguments),this},fired:function(){return!!o}};return f},S.extend({Deferred:function(e){var o=[["notify","progress",S.Callbacks("memory"),S.Callbacks("memory"),2],["resolve","done",S.Callbacks("once memory"),S.Callbacks("once memory"),0,"resolved"],["reject","fail",S.Callbacks("once memory"),S.Callbacks("once memory"),1,"rejected"]],i="pending",a={state:function(){return i},always:function(){return s.done(arguments).fail(arguments),this},"catch":function(e){return a.then(null,e)},pipe:function(){var i=arguments;return S.Deferred(function(r){S.each(o,function(e,t){var n=m(i[t[4]])&&i[t[4]];s[t[1]](function(){var e=n&&n.apply(this,arguments);e&&m(e.promise)?e.promise().progress(r.notify).done(r.resolve).fail(r.reject):r[t[0]+"With"](this,n?[e]:arguments)})}),i=null}).promise()},then:function(t,n,r){var u=0;function l(i,o,a,s){return function(){var n=this,r=arguments,e=function(){var e,t;if(!(i<u)){if((e=a.apply(n,r))===o.promise())throw new TypeError("Thenable self-resolution");t=e&&("object"==typeof e||"function"==typeof e)&&e.then,m(t)?s?t.call(e,l(u,o,R,s),l(u,o,M,s)):(u++,t.call(e,l(u,o,R,s),l(u,o,M,s),l(u,o,R,o.notifyWith))):(a!==R&&(n=void 0,r=[e]),(s||o.resolveWith)(n,r))}},t=s?e:function(){try{e()}catch(e){S.Deferred.exceptionHook&&S.Deferred.exceptionHook(e,t.stackTrace),u<=i+1&&(a!==M&&(n=void 0,r=[e]),o.rejectWith(n,r))}};i?t():(S.Deferred.getStackHook&&(t.stackTrace=S.Deferred.getStackHook()),C.setTimeout(t))}}return S.Deferred(function(e){o[0][3].add(l(0,e,m(r)?r:R,e.notifyWith)),o[1][3].add(l(0,e,m(t)?t:R)),o[2][3].add(l(0,e,m(n)?n:M))}).promise()},promise:function(e){return null!=e?S.extend(e,a):a}},s={};return S.each(o,function(e,t){var n=t[2],r=t[5];a[t[1]]=n.add,r&&n.add(function(){i=r},o[3-e][2].disable,o[3-e][3].disable,o[0][2].lock,o[0][3].lock),n.add(t[3].fire),s[t[0]]=function(){return s[t[0]+"With"](this===s?void 0:this,arguments),this},s[t[0]+"With"]=n.fireWith}),a.promise(s),e&&e.call(s,s),s},when:function(e){var n=arguments.length,t=n,r=Array(t),i=s.call(arguments),o=S.Deferred(),a=function(t){return function(e){r[t]=this,i[t]=1<arguments.length?s.call(arguments):e,--n||o.resolveWith(r,i)}};if(n<=1&&(I(e,o.done(a(t)).resolve,o.reject,!n),"pending"===o.state()||m(i[t]&&i[t].then)))return o.then();while(t--)I(i[t],a(t),o.reject);return o.promise()}});var W=/^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;S.Deferred.exceptionHook=function(e,t){C.console&&C.console.warn&&e&&W.test(e.name)&&C.console.warn("jQuery.Deferred exception: "+e.message,e.stack,t)},S.readyException=function(e){C.setTimeout(function(){throw e})};var F=S.Deferred();function B(){E.removeEventListener("DOMContentLoaded",B),C.removeEventListener("load",B),S.ready()}S.fn.ready=function(e){return F.then(e)["catch"](function(e){S.readyException(e)}),this},S.extend({isReady:!1,readyWait:1,ready:function(e){(!0===e?--S.readyWait:S.isReady)||(S.isReady=!0)!==e&&0<--S.readyWait||F.resolveWith(E,[S])}}),S.ready.then=F.then,"complete"===E.readyState||"loading"!==E.readyState&&!E.documentElement.doScroll?C.setTimeout(S.ready):(E.addEventListener("DOMContentLoaded",B),C.addEventListener("load",B));var $=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if("object"===w(n))for(s in i=!0,n)$(e,t,s,n[s],!0,o,a);else if(void 0!==r&&(i=!0,m(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(S(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},_=/^-ms-/,z=/-([a-z])/g;function U(e,t){return t.toUpperCase()}function X(e){return e.replace(_,"ms-").replace(z,U)}var V=function(e){return 1===e.nodeType||9===e.nodeType||!+e.nodeType};function G(){this.expando=S.expando+G.uid++}G.uid=1,G.prototype={cache:function(e){var t=e[this.expando];return t||(t={},V(e)&&(e.nodeType?e[this.expando]=t:Object.defineProperty(e,this.expando,{value:t,configurable:!0}))),t},set:function(e,t,n){var r,i=this.cache(e);if("string"==typeof t)i[X(t)]=n;else for(r in t)i[X(r)]=t[r];return i},get:function(e,t){return void 0===t?this.cache(e):e[this.expando]&&e[this.expando][X(t)]},access:function(e,t,n){return void 0===t||t&&"string"==typeof t&&void 0===n?this.get(e,t):(this.set(e,t,n),void 0!==n?n:t)},remove:function(e,t){var n,r=e[this.expando];if(void 0!==r){if(void 0!==t){n=(t=Array.isArray(t)?t.map(X):(t=X(t))in r?[t]:t.match(P)||[]).length;while(n--)delete r[t[n]]}(void 0===t||S.isEmptyObject(r))&&(e.nodeType?e[this.expando]=void 0:delete e[this.expando])}},hasData:function(e){var t=e[this.expando];return void 0!==t&&!S.isEmptyObject(t)}};var Y=new G,Q=new G,J=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,K=/[A-Z]/g;function Z(e,t,n){var r,i;if(void 0===n&&1===e.nodeType)if(r="data-"+t.replace(K,"-$&").toLowerCase(),"string"==typeof(n=e.getAttribute(r))){try{n="true"===(i=n)||"false"!==i&&("null"===i?null:i===+i+""?+i:J.test(i)?JSON.parse(i):i)}catch(e){}Q.set(e,t,n)}else n=void 0;return n}S.extend({hasData:function(e){return Q.hasData(e)||Y.hasData(e)},data:function(e,t,n){return Q.access(e,t,n)},removeData:function(e,t){Q.remove(e,t)},_data:function(e,t,n){return Y.access(e,t,n)},_removeData:function(e,t){Y.remove(e,t)}}),S.fn.extend({data:function(n,e){var t,r,i,o=this[0],a=o&&o.attributes;if(void 0===n){if(this.length&&(i=Q.get(o),1===o.nodeType&&!Y.get(o,"hasDataAttrs"))){t=a.length;while(t--)a[t]&&0===(r=a[t].name).indexOf("data-")&&(r=X(r.slice(5)),Z(o,r,i[r]));Y.set(o,"hasDataAttrs",!0)}return i}return"object"==typeof n?this.each(function(){Q.set(this,n)}):$(this,function(e){var t;if(o&&void 0===e)return void 0!==(t=Q.get(o,n))?t:void 0!==(t=Z(o,n))?t:void 0;this.each(function(){Q.set(this,n,e)})},null,e,1<arguments.length,null,!0)},removeData:function(e){return this.each(function(){Q.remove(this,e)})}}),S.extend({queue:function(e,t,n){var r;if(e)return t=(t||"fx")+"queue",r=Y.get(e,t),n&&(!r||Array.isArray(n)?r=Y.access(e,t,S.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||"fx";var n=S.queue(e,t),r=n.length,i=n.shift(),o=S._queueHooks(e,t);"inprogress"===i&&(i=n.shift(),r--),i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,function(){S.dequeue(e,t)},o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return Y.get(e,n)||Y.access(e,n,{empty:S.Callbacks("once memory").add(function(){Y.remove(e,[t+"queue",n])})})}}),S.fn.extend({queue:function(t,n){var e=2;return"string"!=typeof t&&(n=t,t="fx",e--),arguments.length<e?S.queue(this[0],t):void 0===n?this:this.each(function(){var e=S.queue(this,t,n);S._queueHooks(this,t),"fx"===t&&"inprogress"!==e[0]&&S.dequeue(this,t)})},dequeue:function(e){return this.each(function(){S.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,t){var n,r=1,i=S.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};"string"!=typeof e&&(t=e,e=void 0),e=e||"fx";while(a--)(n=Y.get(o[a],e+"queueHooks"))&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}});var ee=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,te=new RegExp("^(?:([+-])=|)("+ee+")([a-z%]*)$","i"),ne=["Top","Right","Bottom","Left"],re=E.documentElement,ie=function(e){return S.contains(e.ownerDocument,e)},oe={composed:!0};re.getRootNode&&(ie=function(e){return S.contains(e.ownerDocument,e)||e.getRootNode(oe)===e.ownerDocument});var ae=function(e,t){return"none"===(e=t||e).style.display||""===e.style.display&&ie(e)&&"none"===S.css(e,"display")};function se(e,t,n,r){var i,o,a=20,s=r?function(){return r.cur()}:function(){return S.css(e,t,"")},u=s(),l=n&&n[3]||(S.cssNumber[t]?"":"px"),c=e.nodeType&&(S.cssNumber[t]||"px"!==l&&+u)&&te.exec(S.css(e,t));if(c&&c[3]!==l){u/=2,l=l||c[3],c=+u||1;while(a--)S.style(e,t,c+l),(1-o)*(1-(o=s()/u||.5))<=0&&(a=0),c/=o;c*=2,S.style(e,t,c+l),n=n||[]}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}var ue={};function le(e,t){for(var n,r,i,o,a,s,u,l=[],c=0,f=e.length;c<f;c++)(r=e[c]).style&&(n=r.style.display,t?("none"===n&&(l[c]=Y.get(r,"display")||null,l[c]||(r.style.display="")),""===r.style.display&&ae(r)&&(l[c]=(u=a=o=void 0,a=(i=r).ownerDocument,s=i.nodeName,(u=ue[s])||(o=a.body.appendChild(a.createElement(s)),u=S.css(o,"display"),o.parentNode.removeChild(o),"none"===u&&(u="block"),ue[s]=u)))):"none"!==n&&(l[c]="none",Y.set(r,"display",n)));for(c=0;c<f;c++)null!=l[c]&&(e[c].style.display=l[c]);return e}S.fn.extend({show:function(){return le(this,!0)},hide:function(){return le(this)},toggle:function(e){return"boolean"==typeof e?e?this.show():this.hide():this.each(function(){ae(this)?S(this).show():S(this).hide()})}});var ce,fe,pe=/^(?:checkbox|radio)$/i,de=/<([a-z][^\/\0>\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="<textarea>x</textarea>",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="<option></option>",y.option=!!ce.lastChild;var ge={thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n<r;n++)Y.set(e[n],"globalEval",!t||Y.get(t[n],"globalEval"))}ge.tbody=ge.tfoot=ge.colgroup=ge.caption=ge.thead,ge.th=ge.td,y.option||(ge.optgroup=ge.option=[1,"<select multiple='multiple'>","</select>"]);var me=/<|&#?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d<h;d++)if((o=e[d])||0===o)if("object"===w(o))S.merge(p,o.nodeType?[o]:o);else if(me.test(o)){a=a||f.appendChild(t.createElement("div")),s=(de.exec(o)||["",""])[1].toLowerCase(),u=ge[s]||ge._default,a.innerHTML=u[1]+S.htmlPrefilter(o)+u[2],c=u[0];while(c--)a=a.lastChild;S.merge(p,a.childNodes),(a=f.firstChild).textContent=""}else p.push(t.createTextNode(o));f.textContent="",d=0;while(o=p[d++])if(r&&-1<S.inArray(o,r))i&&i.push(o);else if(l=ie(o),a=ve(f.appendChild(o),"script"),l&&ye(a),n){c=0;while(o=a[c++])he.test(o.type||"")&&n.push(o)}return f}var be=/^([^.]*)(?:\.(.+)|)/;function we(){return!0}function Te(){return!1}function Ce(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ee(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ee(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Te;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return S().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=S.guid++)),e.each(function(){S.event.add(this,t,i,r,n)})}function Se(e,i,o){o?(Y.set(e,i,!1),S.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Y.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(S.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Y.set(this,i,r),t=o(this,i),this[i](),r!==(n=Y.get(this,i))||t?Y.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n&&n.value}else r.length&&(Y.set(this,i,{value:S.event.trigger(S.extend(r[0],S.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Y.get(e,i)&&S.event.add(e,i,we)}S.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.get(t);if(V(t)){n.handler&&(n=(o=n).handler,i=o.selector),i&&S.find.matchesSelector(re,i),n.guid||(n.guid=S.guid++),(u=v.events)||(u=v.events=Object.create(null)),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof S&&S.event.triggered!==e.type?S.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(P)||[""]).length;while(l--)d=g=(s=be.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=S.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=S.event.special[d]||{},c=S.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&S.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),S.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Y.hasData(e)&&Y.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(P)||[""]).length;while(l--)if(d=g=(s=be.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=S.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||S.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)S.event.remove(e,d+t[l],n,r,!0);S.isEmptyObject(u)&&Y.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=new Array(arguments.length),u=S.event.fix(e),l=(Y.get(this,"events")||Object.create(null))[u.type]||[],c=S.event.special[u.type]||{};for(s[0]=u,t=1;t<arguments.length;t++)s[t]=arguments[t];if(u.delegateTarget=this,!c.preDispatch||!1!==c.preDispatch.call(this,u)){a=S.event.handlers.call(this,u,l),t=0;while((i=a[t++])&&!u.isPropagationStopped()){u.currentTarget=i.elem,n=0;while((o=i.handlers[n++])&&!u.isImmediatePropagationStopped())u.rnamespace&&!1!==o.namespace&&!u.rnamespace.test(o.namespace)||(u.handleObj=o,u.data=o.data,void 0!==(r=((S.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s))&&!1===(u.result=r)&&(u.preventDefault(),u.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,u),u.result}},handlers:function(e,t){var n,r,i,o,a,s=[],u=t.delegateCount,l=e.target;if(u&&l.nodeType&&!("click"===e.type&&1<=e.button))for(;l!==this;l=l.parentNode||this)if(1===l.nodeType&&("click"!==e.type||!0!==l.disabled)){for(o=[],a={},n=0;n<u;n++)void 0===a[i=(r=t[n]).selector+" "]&&(a[i]=r.needsContext?-1<S(i,this).index(l):S.find(i,this,null,[l]).length),a[i]&&o.push(r);o.length&&s.push({elem:l,handlers:o})}return l=this,u<t.length&&s.push({elem:l,handlers:t.slice(u)}),s},addProp:function(t,e){Object.defineProperty(S.Event.prototype,t,{enumerable:!0,configurable:!0,get:m(e)?function(){if(this.originalEvent)return e(this.originalEvent)}:function(){if(this.originalEvent)return this.originalEvent[t]},set:function(e){Object.defineProperty(this,t,{enumerable:!0,configurable:!0,writable:!0,value:e})}})},fix:function(e){return e[S.expando]?e:new S.Event(e)},special:{load:{noBubble:!0},click:{setup:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click",we),!1},trigger:function(e){var t=this||e;return pe.test(t.type)&&t.click&&A(t,"input")&&Se(t,"click"),!0},_default:function(e){var t=e.target;return pe.test(t.type)&&t.click&&A(t,"input")&&Y.get(t,"click")||A(t,"a")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}}},S.removeEvent=function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)},S.Event=function(e,t){if(!(this instanceof S.Event))return new S.Event(e,t);e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&!1===e.returnValue?we:Te,this.target=e.target&&3===e.target.nodeType?e.target.parentNode:e.target,this.currentTarget=e.currentTarget,this.relatedTarget=e.relatedTarget):this.type=e,t&&S.extend(this,t),this.timeStamp=e&&e.timeStamp||Date.now(),this[S.expando]=!0},S.Event.prototype={constructor:S.Event,isDefaultPrevented:Te,isPropagationStopped:Te,isImmediatePropagationStopped:Te,isSimulated:!1,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=we,e&&!this.isSimulated&&e.preventDefault()},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=we,e&&!this.isSimulated&&e.stopPropagation()},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=we,e&&!this.isSimulated&&e.stopImmediatePropagation(),this.stopPropagation()}},S.each({altKey:!0,bubbles:!0,cancelable:!0,changedTouches:!0,ctrlKey:!0,detail:!0,eventPhase:!0,metaKey:!0,pageX:!0,pageY:!0,shiftKey:!0,view:!0,"char":!0,code:!0,charCode:!0,key:!0,keyCode:!0,button:!0,buttons:!0,clientX:!0,clientY:!0,offsetX:!0,offsetY:!0,pointerId:!0,pointerType:!0,screenX:!0,screenY:!0,targetTouches:!0,toElement:!0,touches:!0,which:!0},S.event.addProp),S.each({focus:"focusin",blur:"focusout"},function(e,t){S.event.special[e]={setup:function(){return Se(this,e,Ce),!1},trigger:function(){return Se(this,e),!0},_default:function(){return!0},delegateType:t}}),S.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(e,i){S.event.special[e]={delegateType:i,bindType:i,handle:function(e){var t,n=e.relatedTarget,r=e.handleObj;return n&&(n===this||S.contains(this,n))||(e.type=r.origType,t=r.handler.apply(this,arguments),e.type=i),t}}}),S.fn.extend({on:function(e,t,n,r){return Ee(this,e,t,n,r)},one:function(e,t,n,r){return Ee(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,S(e.delegateTarget).off(r.namespace?r.origType+"."+r.namespace:r.origType,r.selector,r.handler),this;if("object"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return!1!==t&&"function"!=typeof t||(n=t,t=void 0),!1===n&&(n=Te),this.each(function(){S.event.remove(this,e,n,t)})}});var ke=/<script|<style|<link/i,Ae=/checked\s*(?:[^=]|=\s*.checked.)/i,Ne=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function je(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function De(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function qe(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Le(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n<r;n++)S.event.add(t,i,s[i][n]);Q.hasData(e)&&(o=Q.access(e),a=S.extend({},o),Q.set(t,a))}}function He(n,r,i,o){r=g(r);var e,t,a,s,u,l,c=0,f=n.length,p=f-1,d=r[0],h=m(d);if(h||1<f&&"string"==typeof d&&!y.checkClone&&Ae.test(d))return n.each(function(e){var t=n.eq(e);h&&(r[0]=d.call(this,e,t.html())),He(t,r,i,o)});if(f&&(t=(e=xe(r,n[0].ownerDocument,!1,n,o)).firstChild,1===e.childNodes.length&&(e=t),t||o)){for(s=(a=S.map(ve(e,"script"),De)).length;c<f;c++)u=e,c!==p&&(u=S.clone(u,!0,!0),s&&S.merge(a,ve(u,"script"))),i.call(n[c],u,c);if(s)for(l=a[a.length-1].ownerDocument,S.map(a,qe),c=0;c<s;c++)u=a[c],he.test(u.type||"")&&!Y.access(u,"globalEval")&&S.contains(l,u)&&(u.src&&"module"!==(u.type||"").toLowerCase()?S._evalUrl&&!u.noModule&&S._evalUrl(u.src,{nonce:u.nonce||u.getAttribute("nonce")},l):b(u.textContent.replace(Ne,""),u,l))}return n}function Oe(e,t,n){for(var r,i=t?S.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||S.cleanData(ve(r)),r.parentNode&&(n&&ie(r)&&ye(ve(r,"script")),r.parentNode.removeChild(r));return e}S.extend({htmlPrefilter:function(e){return e},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=ie(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||S.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r<i;r++)s=o[r],u=a[r],void 0,"input"===(l=u.nodeName.toLowerCase())&&pe.test(s.type)?u.checked=s.checked:"input"!==l&&"textarea"!==l||(u.defaultValue=s.defaultValue);if(t)if(n)for(o=o||ve(e),a=a||ve(c),r=0,i=o.length;r<i;r++)Le(o[r],a[r]);else Le(e,c);return 0<(a=ve(c,"script")).length&&ye(a,!f&&ve(e,"script")),c},cleanData:function(e){for(var t,n,r,i=S.event.special,o=0;void 0!==(n=e[o]);o++)if(V(n)){if(t=n[Y.expando]){if(t.events)for(r in t.events)i[r]?S.event.remove(n,r):S.removeEvent(n,r,t.handle);n[Y.expando]=void 0}n[Q.expando]&&(n[Q.expando]=void 0)}}}),S.fn.extend({detach:function(e){return Oe(this,e,!0)},remove:function(e){return Oe(this,e)},text:function(e){return $(this,function(e){return void 0===e?S.text(this):this.empty().each(function(){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||(this.textContent=e)})},null,e,arguments.length)},append:function(){return He(this,arguments,function(e){1!==this.nodeType&&11!==this.nodeType&&9!==this.nodeType||je(this,e).appendChild(e)})},prepend:function(){return He(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=je(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return He(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)1===e.nodeType&&(S.cleanData(ve(e,!1)),e.textContent="");return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return S.clone(this,e,t)})},html:function(e){return $(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e&&1===t.nodeType)return t.innerHTML;if("string"==typeof e&&!ke.test(e)&&!ge[(de.exec(e)||["",""])[1].toLowerCase()]){e=S.htmlPrefilter(e);try{for(;n<r;n++)1===(t=this[n]||{}).nodeType&&(S.cleanData(ve(t,!1)),t.innerHTML=e);t=0}catch(e){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var n=[];return He(this,arguments,function(e){var t=this.parentNode;S.inArray(this,n)<0&&(S.cleanData(ve(this)),t&&t.replaceChild(e,this))},n)}}),S.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,a){S.fn[e]=function(e){for(var t,n=[],r=S(e),i=r.length-1,o=0;o<=i;o++)t=o===i?this:this.clone(!0),S(r[o])[a](t),u.apply(n,t.get());return this.pushStack(n)}});var Pe=new RegExp("^("+ee+")(?!px)[a-z%]+$","i"),Re=function(e){var t=e.ownerDocument.defaultView;return t&&t.opener||(t=C),t.getComputedStyle(e)},Me=function(e,t,n){var r,i,o={};for(i in t)o[i]=e.style[i],e.style[i]=t[i];for(i in r=n.call(e),t)e.style[i]=o[i];return r},Ie=new RegExp(ne.join("|"),"i");function We(e,t,n){var r,i,o,a,s=e.style;return(n=n||Re(e))&&(""!==(a=n.getPropertyValue(t)||n[t])||ie(e)||(a=S.style(e,t)),!y.pixelBoxStyles()&&Pe.test(a)&&Ie.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o)),void 0!==a?a+"":a}function Fe(e,t){return{get:function(){if(!e())return(this.get=t).apply(this,arguments);delete this.get}}}!function(){function e(){if(l){u.style.cssText="position:absolute;left:-11111px;width:60px;margin-top:1px;padding:0;border:0",l.style.cssText="position:relative;display:block;box-sizing:border-box;overflow:scroll;margin:auto;border:1px;padding:1px;width:60%;top:1%",re.appendChild(u).appendChild(l);var e=C.getComputedStyle(l);n="1%"!==e.top,s=12===t(e.marginLeft),l.style.right="60%",o=36===t(e.right),r=36===t(e.width),l.style.position="absolute",i=12===t(l.offsetWidth/3),re.removeChild(u),l=null}}function t(e){return Math.round(parseFloat(e))}var n,r,i,o,a,s,u=E.createElement("div"),l=E.createElement("div");l.style&&(l.style.backgroundClip="content-box",l.cloneNode(!0).style.backgroundClip="",y.clearCloneStyle="content-box"===l.style.backgroundClip,S.extend(y,{boxSizingReliable:function(){return e(),r},pixelBoxStyles:function(){return e(),o},pixelPosition:function(){return e(),n},reliableMarginLeft:function(){return e(),s},scrollboxSize:function(){return e(),i},reliableTrDimensions:function(){var e,t,n,r;return null==a&&(e=E.createElement("table"),t=E.createElement("tr"),n=E.createElement("div"),e.style.cssText="position:absolute;left:-11111px;border-collapse:separate",t.style.cssText="border:1px solid",t.style.height="1px",n.style.height="9px",n.style.display="block",re.appendChild(e).appendChild(t).appendChild(n),r=C.getComputedStyle(t),a=parseInt(r.height,10)+parseInt(r.borderTopWidth,10)+parseInt(r.borderBottomWidth,10)===t.offsetHeight,re.removeChild(e)),a}}))}();var Be=["Webkit","Moz","ms"],$e=E.createElement("div").style,_e={};function ze(e){var t=S.cssProps[e]||_e[e];return t||(e in $e?e:_e[e]=function(e){var t=e[0].toUpperCase()+e.slice(1),n=Be.length;while(n--)if((e=Be[n]+t)in $e)return e}(e)||e)}var Ue=/^(none|table(?!-c[ea]).+)/,Xe=/^--/,Ve={position:"absolute",visibility:"hidden",display:"block"},Ge={letterSpacing:"0",fontWeight:"400"};function Ye(e,t,n){var r=te.exec(t);return r?Math.max(0,r[2]-(n||0))+(r[3]||"px"):t}function Qe(e,t,n,r,i,o){var a="width"===t?1:0,s=0,u=0;if(n===(r?"border":"content"))return 0;for(;a<4;a+=2)"margin"===n&&(u+=S.css(e,n+ne[a],!0,i)),r?("content"===n&&(u-=S.css(e,"padding"+ne[a],!0,i)),"margin"!==n&&(u-=S.css(e,"border"+ne[a]+"Width",!0,i))):(u+=S.css(e,"padding"+ne[a],!0,i),"padding"!==n?u+=S.css(e,"border"+ne[a]+"Width",!0,i):s+=S.css(e,"border"+ne[a]+"Width",!0,i));return!r&&0<=o&&(u+=Math.max(0,Math.ceil(e["offset"+t[0].toUpperCase()+t.slice(1)]-o-u-s-.5))||0),u}function Je(e,t,n){var r=Re(e),i=(!y.boxSizingReliable()||n)&&"border-box"===S.css(e,"boxSizing",!1,r),o=i,a=We(e,t,r),s="offset"+t[0].toUpperCase()+t.slice(1);if(Pe.test(a)){if(!n)return a;a="auto"}return(!y.boxSizingReliable()&&i||!y.reliableTrDimensions()&&A(e,"tr")||"auto"===a||!parseFloat(a)&&"inline"===S.css(e,"display",!1,r))&&e.getClientRects().length&&(i="border-box"===S.css(e,"boxSizing",!1,r),(o=s in e)&&(a=e[s])),(a=parseFloat(a)||0)+Qe(e,t,n||(i?"border":"content"),o,r,a)+"px"}function Ke(e,t,n,r,i){return new Ke.prototype.init(e,t,n,r,i)}S.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=We(e,"opacity");return""===n?"1":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,gridArea:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnStart:!0,gridRow:!0,gridRowEnd:!0,gridRowStart:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=X(t),u=Xe.test(t),l=e.style;if(u||(t=ze(s)),a=S.cssHooks[t]||S.cssHooks[s],void 0===n)return a&&"get"in a&&void 0!==(i=a.get(e,!1,r))?i:l[t];"string"===(o=typeof n)&&(i=te.exec(n))&&i[1]&&(n=se(e,t,i),o="number"),null!=n&&n==n&&("number"!==o||u||(n+=i&&i[3]||(S.cssNumber[s]?"":"px")),y.clearCloneStyle||""!==n||0!==t.indexOf("background")||(l[t]="inherit"),a&&"set"in a&&void 0===(n=a.set(e,n,r))||(u?l.setProperty(t,n):l[t]=n))}},css:function(e,t,n,r){var i,o,a,s=X(t);return Xe.test(t)||(t=ze(s)),(a=S.cssHooks[t]||S.cssHooks[s])&&"get"in a&&(i=a.get(e,!0,n)),void 0===i&&(i=We(e,t,r)),"normal"===i&&t in Ge&&(i=Ge[t]),""===n||n?(o=parseFloat(i),!0===n||isFinite(o)?o||0:i):i}}),S.each(["height","width"],function(e,u){S.cssHooks[u]={get:function(e,t,n){if(t)return!Ue.test(S.css(e,"display"))||e.getClientRects().length&&e.getBoundingClientRect().width?Je(e,u,n):Me(e,Ve,function(){return Je(e,u,n)})},set:function(e,t,n){var r,i=Re(e),o=!y.scrollboxSize()&&"absolute"===i.position,a=(o||n)&&"border-box"===S.css(e,"boxSizing",!1,i),s=n?Qe(e,u,n,a,i):0;return a&&o&&(s-=Math.ceil(e["offset"+u[0].toUpperCase()+u.slice(1)]-parseFloat(i[u])-Qe(e,u,"border",!1,i)-.5)),s&&(r=te.exec(t))&&"px"!==(r[3]||"px")&&(e.style[u]=t,t=S.css(e,u)),Ye(0,t,s)}}}),S.cssHooks.marginLeft=Fe(y.reliableMarginLeft,function(e,t){if(t)return(parseFloat(We(e,"marginLeft"))||e.getBoundingClientRect().left-Me(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}))+"px"}),S.each({margin:"",padding:"",border:"Width"},function(i,o){S.cssHooks[i+o]={expand:function(e){for(var t=0,n={},r="string"==typeof e?e.split(" "):[e];t<4;t++)n[i+ne[t]+o]=r[t]||r[t-2]||r[0];return n}},"margin"!==i&&(S.cssHooks[i+o].set=Ye)}),S.fn.extend({css:function(e,t){return $(this,function(e,t,n){var r,i,o={},a=0;if(Array.isArray(t)){for(r=Re(e),i=t.length;a<i;a++)o[t[a]]=S.css(e,t[a],!1,r);return o}return void 0!==n?S.style(e,t,n):S.css(e,t)},e,t,1<arguments.length)}}),((S.Tween=Ke).prototype={constructor:Ke,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||S.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(S.cssNumber[n]?"":"px")},cur:function(){var e=Ke.propHooks[this.prop];return e&&e.get?e.get(this):Ke.propHooks._default.get(this)},run:function(e){var t,n=Ke.propHooks[this.prop];return this.options.duration?this.pos=t=S.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):Ke.propHooks._default.set(this),this}}).init.prototype=Ke.prototype,(Ke.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=S.css(e.elem,e.prop,""))&&"auto"!==t?t:0},set:function(e){S.fx.step[e.prop]?S.fx.step[e.prop](e):1!==e.elem.nodeType||!S.cssHooks[e.prop]&&null==e.elem.style[ze(e.prop)]?e.elem[e.prop]=e.now:S.style(e.elem,e.prop,e.now+e.unit)}}}).scrollTop=Ke.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},S.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:"swing"},S.fx=Ke.prototype.init,S.fx.step={};var Ze,et,tt,nt,rt=/^(?:toggle|show|hide)$/,it=/queueHooks$/;function ot(){et&&(!1===E.hidden&&C.requestAnimationFrame?C.requestAnimationFrame(ot):C.setTimeout(ot,S.fx.interval),S.fx.tick())}function at(){return C.setTimeout(function(){Ze=void 0}),Ze=Date.now()}function st(e,t){var n,r=0,i={height:e};for(t=t?1:0;r<4;r+=2-t)i["margin"+(n=ne[r])]=i["padding"+n]=e;return t&&(i.opacity=i.width=e),i}function ut(e,t,n){for(var r,i=(lt.tweeners[t]||[]).concat(lt.tweeners["*"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function lt(o,e,t){var n,a,r=0,i=lt.prefilters.length,s=S.Deferred().always(function(){delete u.elem}),u=function(){if(a)return!1;for(var e=Ze||at(),t=Math.max(0,l.startTime+l.duration-e),n=1-(t/l.duration||0),r=0,i=l.tweens.length;r<i;r++)l.tweens[r].run(n);return s.notifyWith(o,[l,n,t]),n<1&&i?t:(i||s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l]),!1)},l=s.promise({elem:o,props:S.extend({},e),opts:S.extend(!0,{specialEasing:{},easing:S.easing._default},t),originalProperties:e,originalOptions:t,startTime:Ze||at(),duration:t.duration,tweens:[],createTween:function(e,t){var n=S.Tween(o,l.opts,e,t,l.opts.specialEasing[e]||l.opts.easing);return l.tweens.push(n),n},stop:function(e){var t=0,n=e?l.tweens.length:0;if(a)return this;for(a=!0;t<n;t++)l.tweens[t].run(1);return e?(s.notifyWith(o,[l,1,0]),s.resolveWith(o,[l,e])):s.rejectWith(o,[l,e]),this}}),c=l.props;for(!function(e,t){var n,r,i,o,a;for(n in e)if(i=t[r=X(n)],o=e[n],Array.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),(a=S.cssHooks[r])&&"expand"in a)for(n in o=a.expand(o),delete e[r],o)n in e||(e[n]=o[n],t[n]=i);else t[r]=i}(c,l.opts.specialEasing);r<i;r++)if(n=lt.prefilters[r].call(l,o,c,l.opts))return m(n.stop)&&(S._queueHooks(l.elem,l.opts.queue).stop=n.stop.bind(n)),n;return S.map(c,ut,l),m(l.opts.start)&&l.opts.start.call(o,l),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always),S.fx.timer(S.extend(u,{elem:o,anim:l,queue:l.opts.queue})),l}S.Animation=S.extend(lt,{tweeners:{"*":[function(e,t){var n=this.createTween(e,t);return se(n.elem,e,te.exec(t),n),n}]},tweener:function(e,t){m(e)?(t=e,e=["*"]):e=e.match(P);for(var n,r=0,i=e.length;r<i;r++)n=e[r],lt.tweeners[n]=lt.tweeners[n]||[],lt.tweeners[n].unshift(t)},prefilters:[function(e,t,n){var r,i,o,a,s,u,l,c,f="width"in t||"height"in t,p=this,d={},h=e.style,g=e.nodeType&&ae(e),v=Y.get(e,"fxshow");for(r in n.queue||(null==(a=S._queueHooks(e,"fx")).unqueued&&(a.unqueued=0,s=a.empty.fire,a.empty.fire=function(){a.unqueued||s()}),a.unqueued++,p.always(function(){p.always(function(){a.unqueued--,S.queue(e,"fx").length||a.empty.fire()})})),t)if(i=t[r],rt.test(i)){if(delete t[r],o=o||"toggle"===i,i===(g?"hide":"show")){if("show"!==i||!v||void 0===v[r])continue;g=!0}d[r]=v&&v[r]||S.style(e,r)}if((u=!S.isEmptyObject(t))||!S.isEmptyObject(d))for(r in f&&1===e.nodeType&&(n.overflow=[h.overflow,h.overflowX,h.overflowY],null==(l=v&&v.display)&&(l=Y.get(e,"display")),"none"===(c=S.css(e,"display"))&&(l?c=l:(le([e],!0),l=e.style.display||l,c=S.css(e,"display"),le([e]))),("inline"===c||"inline-block"===c&&null!=l)&&"none"===S.css(e,"float")&&(u||(p.done(function(){h.display=l}),null==l&&(c=h.display,l="none"===c?"":c)),h.display="inline-block")),n.overflow&&(h.overflow="hidden",p.always(function(){h.overflow=n.overflow[0],h.overflowX=n.overflow[1],h.overflowY=n.overflow[2]})),u=!1,d)u||(v?"hidden"in v&&(g=v.hidden):v=Y.access(e,"fxshow",{display:l}),o&&(v.hidden=!g),g&&le([e],!0),p.done(function(){for(r in g||le([e]),Y.remove(e,"fxshow"),d)S.style(e,r,d[r])})),u=ut(g?v[r]:0,r,p),r in v||(v[r]=u.start,g&&(u.end=u.start,u.start=0))}],prefilter:function(e,t){t?lt.prefilters.unshift(e):lt.prefilters.push(e)}}),S.speed=function(e,t,n){var r=e&&"object"==typeof e?S.extend({},e):{complete:n||!n&&t||m(e)&&e,duration:e,easing:n&&t||t&&!m(t)&&t};return S.fx.off?r.duration=0:"number"!=typeof r.duration&&(r.duration in S.fx.speeds?r.duration=S.fx.speeds[r.duration]:r.duration=S.fx.speeds._default),null!=r.queue&&!0!==r.queue||(r.queue="fx"),r.old=r.complete,r.complete=function(){m(r.old)&&r.old.call(this),r.queue&&S.dequeue(this,r.queue)},r},S.fn.extend({fadeTo:function(e,t,n,r){return this.filter(ae).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(t,e,n,r){var i=S.isEmptyObject(t),o=S.speed(e,n,r),a=function(){var e=lt(this,S.extend({},t),o);(i||Y.get(this,"finish"))&&e.stop(!0)};return a.finish=a,i||!1===o.queue?this.each(a):this.queue(o.queue,a)},stop:function(i,e,o){var a=function(e){var t=e.stop;delete e.stop,t(o)};return"string"!=typeof i&&(o=e,e=i,i=void 0),e&&this.queue(i||"fx",[]),this.each(function(){var e=!0,t=null!=i&&i+"queueHooks",n=S.timers,r=Y.get(this);if(t)r[t]&&r[t].stop&&a(r[t]);else for(t in r)r[t]&&r[t].stop&&it.test(t)&&a(r[t]);for(t=n.length;t--;)n[t].elem!==this||null!=i&&n[t].queue!==i||(n[t].anim.stop(o),e=!1,n.splice(t,1));!e&&o||S.dequeue(this,i)})},finish:function(a){return!1!==a&&(a=a||"fx"),this.each(function(){var e,t=Y.get(this),n=t[a+"queue"],r=t[a+"queueHooks"],i=S.timers,o=n?n.length:0;for(t.finish=!0,S.queue(this,a,[]),r&&r.stop&&r.stop.call(this,!0),e=i.length;e--;)i[e].elem===this&&i[e].queue===a&&(i[e].anim.stop(!0),i.splice(e,1));for(e=0;e<o;e++)n[e]&&n[e].finish&&n[e].finish.call(this);delete t.finish})}}),S.each(["toggle","show","hide"],function(e,r){var i=S.fn[r];S.fn[r]=function(e,t,n){return null==e||"boolean"==typeof e?i.apply(this,arguments):this.animate(st(r,!0),e,t,n)}}),S.each({slideDown:st("show"),slideUp:st("hide"),slideToggle:st("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,r){S.fn[e]=function(e,t,n){return this.animate(r,e,t,n)}}),S.timers=[],S.fx.tick=function(){var e,t=0,n=S.timers;for(Ze=Date.now();t<n.length;t++)(e=n[t])()||n[t]!==e||n.splice(t--,1);n.length||S.fx.stop(),Ze=void 0},S.fx.timer=function(e){S.timers.push(e),S.fx.start()},S.fx.interval=13,S.fx.start=function(){et||(et=!0,ot())},S.fx.stop=function(){et=null},S.fx.speeds={slow:600,fast:200,_default:400},S.fn.delay=function(r,e){return r=S.fx&&S.fx.speeds[r]||r,e=e||"fx",this.queue(e,function(e,t){var n=C.setTimeout(e,r);t.stop=function(){C.clearTimeout(n)}})},tt=E.createElement("input"),nt=E.createElement("select").appendChild(E.createElement("option")),tt.type="checkbox",y.checkOn=""!==tt.value,y.optSelected=nt.selected,(tt=E.createElement("input")).value="t",tt.type="radio",y.radioValue="t"===tt.value;var ct,ft=S.expr.attrHandle;S.fn.extend({attr:function(e,t){return $(this,S.attr,e,t,1<arguments.length)},removeAttr:function(e){return this.each(function(){S.removeAttr(this,e)})}}),S.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return"undefined"==typeof e.getAttribute?S.prop(e,t,n):(1===o&&S.isXMLDoc(e)||(i=S.attrHooks[t.toLowerCase()]||(S.expr.match.bool.test(t)?ct:void 0)),void 0!==n?null===n?void S.removeAttr(e,t):i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+""),n):i&&"get"in i&&null!==(r=i.get(e,t))?r:null==(r=S.find.attr(e,t))?void 0:r)},attrHooks:{type:{set:function(e,t){if(!y.radioValue&&"radio"===t&&A(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r=0,i=t&&t.match(P);if(i&&1===e.nodeType)while(n=i[r++])e.removeAttribute(n)}}),ct={set:function(e,t,n){return!1===t?S.removeAttr(e,n):e.setAttribute(n,n),n}},S.each(S.expr.match.bool.source.match(/\w+/g),function(e,t){var a=ft[t]||S.find.attr;ft[t]=function(e,t,n){var r,i,o=t.toLowerCase();return n||(i=ft[o],ft[o]=r,r=null!=a(e,t,n)?o:null,ft[o]=i),r}});var pt=/^(?:input|select|textarea|button)$/i,dt=/^(?:a|area)$/i;function ht(e){return(e.match(P)||[]).join(" ")}function gt(e){return e.getAttribute&&e.getAttribute("class")||""}function vt(e){return Array.isArray(e)?e:"string"==typeof e&&e.match(P)||[]}S.fn.extend({prop:function(e,t){return $(this,S.prop,e,t,1<arguments.length)},removeProp:function(e){return this.each(function(){delete this[S.propFix[e]||e]})}}),S.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&S.isXMLDoc(e)||(t=S.propFix[t]||t,i=S.propHooks[t]),void 0!==n?i&&"set"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&"get"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=S.find.attr(e,"tabindex");return t?parseInt(t,10):pt.test(e.nodeName)||dt.test(e.nodeName)&&e.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),y.optSelected||(S.propHooks.selected={get:function(e){var t=e.parentNode;return t&&t.parentNode&&t.parentNode.selectedIndex,null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),S.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){S.propFix[this.toLowerCase()]=this}),S.fn.extend({addClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).addClass(t.call(this,e,gt(this)))});if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])r.indexOf(" "+o+" ")<0&&(r+=o+" ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},removeClass:function(t){var e,n,r,i,o,a,s,u=0;if(m(t))return this.each(function(e){S(this).removeClass(t.call(this,e,gt(this)))});if(!arguments.length)return this.attr("class","");if((e=vt(t)).length)while(n=this[u++])if(i=gt(n),r=1===n.nodeType&&" "+ht(i)+" "){a=0;while(o=e[a++])while(-1<r.indexOf(" "+o+" "))r=r.replace(" "+o+" "," ");i!==(s=ht(r))&&n.setAttribute("class",s)}return this},toggleClass:function(i,t){var o=typeof i,a="string"===o||Array.isArray(i);return"boolean"==typeof t&&a?t?this.addClass(i):this.removeClass(i):m(i)?this.each(function(e){S(this).toggleClass(i.call(this,e,gt(this),t),t)}):this.each(function(){var e,t,n,r;if(a){t=0,n=S(this),r=vt(i);while(e=r[t++])n.hasClass(e)?n.removeClass(e):n.addClass(e)}else void 0!==i&&"boolean"!==o||((e=gt(this))&&Y.set(this,"__className__",e),this.setAttribute&&this.setAttribute("class",e||!1===i?"":Y.get(this,"__className__")||""))})},hasClass:function(e){var t,n,r=0;t=" "+e+" ";while(n=this[r++])if(1===n.nodeType&&-1<(" "+ht(gt(n))+" ").indexOf(t))return!0;return!1}});var yt=/\r/g;S.fn.extend({val:function(n){var r,e,i,t=this[0];return arguments.length?(i=m(n),this.each(function(e){var t;1===this.nodeType&&(null==(t=i?n.call(this,e,S(this).val()):n)?t="":"number"==typeof t?t+="":Array.isArray(t)&&(t=S.map(t,function(e){return null==e?"":e+""})),(r=S.valHooks[this.type]||S.valHooks[this.nodeName.toLowerCase()])&&"set"in r&&void 0!==r.set(this,t,"value")||(this.value=t))})):t?(r=S.valHooks[t.type]||S.valHooks[t.nodeName.toLowerCase()])&&"get"in r&&void 0!==(e=r.get(t,"value"))?e:"string"==typeof(e=t.value)?e.replace(yt,""):null==e?"":e:void 0}}),S.extend({valHooks:{option:{get:function(e){var t=S.find.attr(e,"value");return null!=t?t:ht(S.text(e))}},select:{get:function(e){var t,n,r,i=e.options,o=e.selectedIndex,a="select-one"===e.type,s=a?null:[],u=a?o+1:i.length;for(r=o<0?u:a?o:0;r<u;r++)if(((n=i[r]).selected||r===o)&&!n.disabled&&(!n.parentNode.disabled||!A(n.parentNode,"optgroup"))){if(t=S(n).val(),a)return t;s.push(t)}return s},set:function(e,t){var n,r,i=e.options,o=S.makeArray(t),a=i.length;while(a--)((r=i[a]).selected=-1<S.inArray(S.valHooks.option.get(r),o))&&(n=!0);return n||(e.selectedIndex=-1),o}}}}),S.each(["radio","checkbox"],function(){S.valHooks[this]={set:function(e,t){if(Array.isArray(t))return e.checked=-1<S.inArray(S(e).val(),t)}},y.checkOn||(S.valHooks[this].get=function(e){return null===e.getAttribute("value")?"on":e.value})}),y.focusin="onfocusin"in C;var mt=/^(?:focusinfocus|focusoutblur)$/,xt=function(e){e.stopPropagation()};S.extend(S.event,{trigger:function(e,t,n,r){var i,o,a,s,u,l,c,f,p=[n||E],d=v.call(e,"type")?e.type:e,h=v.call(e,"namespace")?e.namespace.split("."):[];if(o=f=a=n=n||E,3!==n.nodeType&&8!==n.nodeType&&!mt.test(d+S.event.triggered)&&(-1<d.indexOf(".")&&(d=(h=d.split(".")).shift(),h.sort()),u=d.indexOf(":")<0&&"on"+d,(e=e[S.expando]?e:new S.Event(d,"object"==typeof e&&e)).isTrigger=r?2:3,e.namespace=h.join("."),e.rnamespace=e.namespace?new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,e.result=void 0,e.target||(e.target=n),t=null==t?[e]:S.makeArray(t,[e]),c=S.event.special[d]||{},r||!c.trigger||!1!==c.trigger.apply(n,t))){if(!r&&!c.noBubble&&!x(n)){for(s=c.delegateType||d,mt.test(s+d)||(o=o.parentNode);o;o=o.parentNode)p.push(o),a=o;a===(n.ownerDocument||E)&&p.push(a.defaultView||a.parentWindow||C)}i=0;while((o=p[i++])&&!e.isPropagationStopped())f=o,e.type=1<i?s:c.bindType||d,(l=(Y.get(o,"events")||Object.create(null))[e.type]&&Y.get(o,"handle"))&&l.apply(o,t),(l=u&&o[u])&&l.apply&&V(o)&&(e.result=l.apply(o,t),!1===e.result&&e.preventDefault());return e.type=d,r||e.isDefaultPrevented()||c._default&&!1!==c._default.apply(p.pop(),t)||!V(n)||u&&m(n[d])&&!x(n)&&((a=n[u])&&(n[u]=null),S.event.triggered=d,e.isPropagationStopped()&&f.addEventListener(d,xt),n[d](),e.isPropagationStopped()&&f.removeEventListener(d,xt),S.event.triggered=void 0,a&&(n[u]=a)),e.result}},simulate:function(e,t,n){var r=S.extend(new S.Event,n,{type:e,isSimulated:!0});S.event.trigger(r,null,t)}}),S.fn.extend({trigger:function(e,t){return this.each(function(){S.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return S.event.trigger(e,t,n,!0)}}),y.focusin||S.each({focus:"focusin",blur:"focusout"},function(n,r){var i=function(e){S.event.simulate(r,e.target,S.event.fix(e))};S.event.special[r]={setup:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r);t||e.addEventListener(n,i,!0),Y.access(e,r,(t||0)+1)},teardown:function(){var e=this.ownerDocument||this.document||this,t=Y.access(e,r)-1;t?Y.access(e,r,t):(e.removeEventListener(n,i,!0),Y.remove(e,r))}}});var bt=C.location,wt={guid:Date.now()},Tt=/\?/;S.parseXML=function(e){var t,n;if(!e||"string"!=typeof e)return null;try{t=(new C.DOMParser).parseFromString(e,"text/xml")}catch(e){}return n=t&&t.getElementsByTagName("parsererror")[0],t&&!n||S.error("Invalid XML: "+(n?S.map(n.childNodes,function(e){return e.textContent}).join("\n"):e)),t};var Ct=/\[\]$/,Et=/\r?\n/g,St=/^(?:submit|button|image|reset|file)$/i,kt=/^(?:input|select|textarea|keygen)/i;function At(n,e,r,i){var t;if(Array.isArray(e))S.each(e,function(e,t){r||Ct.test(n)?i(n,t):At(n+"["+("object"==typeof t&&null!=t?e:"")+"]",t,r,i)});else if(r||"object"!==w(e))i(n,e);else for(t in e)At(n+"["+t+"]",e[t],r,i)}S.param=function(e,t){var n,r=[],i=function(e,t){var n=m(t)?t():t;r[r.length]=encodeURIComponent(e)+"="+encodeURIComponent(null==n?"":n)};if(null==e)return"";if(Array.isArray(e)||e.jquery&&!S.isPlainObject(e))S.each(e,function(){i(this.name,this.value)});else for(n in e)At(n,e[n],t,i);return r.join("&")},S.fn.extend({serialize:function(){return S.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=S.prop(this,"elements");return e?S.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!S(this).is(":disabled")&&kt.test(this.nodeName)&&!St.test(e)&&(this.checked||!pe.test(e))}).map(function(e,t){var n=S(this).val();return null==n?null:Array.isArray(n)?S.map(n,function(e){return{name:t.name,value:e.replace(Et,"\r\n")}}):{name:t.name,value:n.replace(Et,"\r\n")}}).get()}});var Nt=/%20/g,jt=/#.*$/,Dt=/([?&])_=[^&]*/,qt=/^(.*?):[ \t]*([^\r\n]*)$/gm,Lt=/^(?:GET|HEAD)$/,Ht=/^\/\//,Ot={},Pt={},Rt="*/".concat("*"),Mt=E.createElement("a");function It(o){return function(e,t){"string"!=typeof e&&(t=e,e="*");var n,r=0,i=e.toLowerCase().match(P)||[];if(m(t))while(n=i[r++])"+"===n[0]?(n=n.slice(1)||"*",(o[n]=o[n]||[]).unshift(t)):(o[n]=o[n]||[]).push(t)}}function Wt(t,i,o,a){var s={},u=t===Pt;function l(e){var r;return s[e]=!0,S.each(t[e]||[],function(e,t){var n=t(i,o,a);return"string"!=typeof n||u||s[n]?u?!(r=n):void 0:(i.dataTypes.unshift(n),l(n),!1)}),r}return l(i.dataTypes[0])||!s["*"]&&l("*")}function Ft(e,t){var n,r,i=S.ajaxSettings.flatOptions||{};for(n in t)void 0!==t[n]&&((i[n]?e:r||(r={}))[n]=t[n]);return r&&S.extend(!0,e,r),e}Mt.href=bt.href,S.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:bt.href,type:"GET",isLocal:/^(?:about|app|app-storage|.+-extension|file|res|widget):$/.test(bt.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Rt,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":JSON.parse,"text xml":S.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Ft(Ft(e,S.ajaxSettings),t):Ft(S.ajaxSettings,e)},ajaxPrefilter:It(Ot),ajaxTransport:It(Pt),ajax:function(e,t){"object"==typeof e&&(t=e,e=void 0),t=t||{};var c,f,p,n,d,r,h,g,i,o,v=S.ajaxSetup({},t),y=v.context||v,m=v.context&&(y.nodeType||y.jquery)?S(y):S.event,x=S.Deferred(),b=S.Callbacks("once memory"),w=v.statusCode||{},a={},s={},u="canceled",T={readyState:0,getResponseHeader:function(e){var t;if(h){if(!n){n={};while(t=qt.exec(p))n[t[1].toLowerCase()+" "]=(n[t[1].toLowerCase()+" "]||[]).concat(t[2])}t=n[e.toLowerCase()+" "]}return null==t?null:t.join(", ")},getAllResponseHeaders:function(){return h?p:null},setRequestHeader:function(e,t){return null==h&&(e=s[e.toLowerCase()]=s[e.toLowerCase()]||e,a[e]=t),this},overrideMimeType:function(e){return null==h&&(v.mimeType=e),this},statusCode:function(e){var t;if(e)if(h)T.always(e[T.status]);else for(t in e)w[t]=[w[t],e[t]];return this},abort:function(e){var t=e||u;return c&&c.abort(t),l(0,t),this}};if(x.promise(T),v.url=((e||v.url||bt.href)+"").replace(Ht,bt.protocol+"//"),v.type=t.method||t.type||v.method||v.type,v.dataTypes=(v.dataType||"*").toLowerCase().match(P)||[""],null==v.crossDomain){r=E.createElement("a");try{r.href=v.url,r.href=r.href,v.crossDomain=Mt.protocol+"//"+Mt.host!=r.protocol+"//"+r.host}catch(e){v.crossDomain=!0}}if(v.data&&v.processData&&"string"!=typeof v.data&&(v.data=S.param(v.data,v.traditional)),Wt(Ot,v,t,T),h)return T;for(i in(g=S.event&&v.global)&&0==S.active++&&S.event.trigger("ajaxStart"),v.type=v.type.toUpperCase(),v.hasContent=!Lt.test(v.type),f=v.url.replace(jt,""),v.hasContent?v.data&&v.processData&&0===(v.contentType||"").indexOf("application/x-www-form-urlencoded")&&(v.data=v.data.replace(Nt,"+")):(o=v.url.slice(f.length),v.data&&(v.processData||"string"==typeof v.data)&&(f+=(Tt.test(f)?"&":"?")+v.data,delete v.data),!1===v.cache&&(f=f.replace(Dt,"$1"),o=(Tt.test(f)?"&":"?")+"_="+wt.guid+++o),v.url=f+o),v.ifModified&&(S.lastModified[f]&&T.setRequestHeader("If-Modified-Since",S.lastModified[f]),S.etag[f]&&T.setRequestHeader("If-None-Match",S.etag[f])),(v.data&&v.hasContent&&!1!==v.contentType||t.contentType)&&T.setRequestHeader("Content-Type",v.contentType),T.setRequestHeader("Accept",v.dataTypes[0]&&v.accepts[v.dataTypes[0]]?v.accepts[v.dataTypes[0]]+("*"!==v.dataTypes[0]?", "+Rt+"; q=0.01":""):v.accepts["*"]),v.headers)T.setRequestHeader(i,v.headers[i]);if(v.beforeSend&&(!1===v.beforeSend.call(y,T,v)||h))return T.abort();if(u="abort",b.add(v.complete),T.done(v.success),T.fail(v.error),c=Wt(Pt,v,t,T)){if(T.readyState=1,g&&m.trigger("ajaxSend",[T,v]),h)return T;v.async&&0<v.timeout&&(d=C.setTimeout(function(){T.abort("timeout")},v.timeout));try{h=!1,c.send(a,l)}catch(e){if(h)throw e;l(-1,e)}}else l(-1,"No Transport");function l(e,t,n,r){var i,o,a,s,u,l=t;h||(h=!0,d&&C.clearTimeout(d),c=void 0,p=r||"",T.readyState=0<e?4:0,i=200<=e&&e<300||304===e,n&&(s=function(e,t,n){var r,i,o,a,s=e.contents,u=e.dataTypes;while("*"===u[0])u.shift(),void 0===r&&(r=e.mimeType||t.getResponseHeader("Content-Type"));if(r)for(i in s)if(s[i]&&s[i].test(r)){u.unshift(i);break}if(u[0]in n)o=u[0];else{for(i in n){if(!u[0]||e.converters[i+" "+u[0]]){o=i;break}a||(a=i)}o=o||a}if(o)return o!==u[0]&&u.unshift(o),n[o]}(v,T,n)),!i&&-1<S.inArray("script",v.dataTypes)&&S.inArray("json",v.dataTypes)<0&&(v.converters["text script"]=function(){}),s=function(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];o=c.shift();while(o)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if("*"===o)o=u;else if("*"!==u&&u!==o){if(!(a=l[u+" "+o]||l["* "+o]))for(i in l)if((s=i.split(" "))[1]===o&&(a=l[u+" "+s[0]]||l["* "+s[0]])){!0===a?a=l[i]:!0!==l[i]&&(o=s[0],c.unshift(s[1]));break}if(!0!==a)if(a&&e["throws"])t=a(t);else try{t=a(t)}catch(e){return{state:"parsererror",error:a?e:"No conversion from "+u+" to "+o}}}return{state:"success",data:t}}(v,s,T,i),i?(v.ifModified&&((u=T.getResponseHeader("Last-Modified"))&&(S.lastModified[f]=u),(u=T.getResponseHeader("etag"))&&(S.etag[f]=u)),204===e||"HEAD"===v.type?l="nocontent":304===e?l="notmodified":(l=s.state,o=s.data,i=!(a=s.error))):(a=l,!e&&l||(l="error",e<0&&(e=0))),T.status=e,T.statusText=(t||l)+"",i?x.resolveWith(y,[o,l,T]):x.rejectWith(y,[T,l,a]),T.statusCode(w),w=void 0,g&&m.trigger(i?"ajaxSuccess":"ajaxError",[T,v,i?o:a]),b.fireWith(y,[T,l]),g&&(m.trigger("ajaxComplete",[T,v]),--S.active||S.event.trigger("ajaxStop")))}return T},getJSON:function(e,t,n){return S.get(e,t,n,"json")},getScript:function(e,t){return S.get(e,void 0,t,"script")}}),S.each(["get","post"],function(e,i){S[i]=function(e,t,n,r){return m(t)&&(r=r||n,n=t,t=void 0),S.ajax(S.extend({url:e,type:i,dataType:r,data:t,success:n},S.isPlainObject(e)&&e))}}),S.ajaxPrefilter(function(e){var t;for(t in e.headers)"content-type"===t.toLowerCase()&&(e.contentType=e.headers[t]||"")}),S._evalUrl=function(e,t,n){return S.ajax({url:e,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,converters:{"text script":function(){}},dataFilter:function(e){S.globalEval(e,t,n)}})},S.fn.extend({wrapAll:function(e){var t;return this[0]&&(m(e)&&(e=e.call(this[0])),t=S(e,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstElementChild)e=e.firstElementChild;return e}).append(this)),this},wrapInner:function(n){return m(n)?this.each(function(e){S(this).wrapInner(n.call(this,e))}):this.each(function(){var e=S(this),t=e.contents();t.length?t.wrapAll(n):e.append(n)})},wrap:function(t){var n=m(t);return this.each(function(e){S(this).wrapAll(n?t.call(this,e):t)})},unwrap:function(e){return this.parent(e).not("body").each(function(){S(this).replaceWith(this.childNodes)}),this}}),S.expr.pseudos.hidden=function(e){return!S.expr.pseudos.visible(e)},S.expr.pseudos.visible=function(e){return!!(e.offsetWidth||e.offsetHeight||e.getClientRects().length)},S.ajaxSettings.xhr=function(){try{return new C.XMLHttpRequest}catch(e){}};var Bt={0:200,1223:204},$t=S.ajaxSettings.xhr();y.cors=!!$t&&"withCredentials"in $t,y.ajax=$t=!!$t,S.ajaxTransport(function(i){var o,a;if(y.cors||$t&&!i.crossDomain)return{send:function(e,t){var n,r=i.xhr();if(r.open(i.type,i.url,i.async,i.username,i.password),i.xhrFields)for(n in i.xhrFields)r[n]=i.xhrFields[n];for(n in i.mimeType&&r.overrideMimeType&&r.overrideMimeType(i.mimeType),i.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest"),e)r.setRequestHeader(n,e[n]);o=function(e){return function(){o&&(o=a=r.onload=r.onerror=r.onabort=r.ontimeout=r.onreadystatechange=null,"abort"===e?r.abort():"error"===e?"number"!=typeof r.status?t(0,"error"):t(r.status,r.statusText):t(Bt[r.status]||r.status,r.statusText,"text"!==(r.responseType||"text")||"string"!=typeof r.responseText?{binary:r.response}:{text:r.responseText},r.getAllResponseHeaders()))}},r.onload=o(),a=r.onerror=r.ontimeout=o("error"),void 0!==r.onabort?r.onabort=a:r.onreadystatechange=function(){4===r.readyState&&C.setTimeout(function(){o&&a()})},o=o("abort");try{r.send(i.hasContent&&i.data||null)}catch(e){if(o)throw e}},abort:function(){o&&o()}}}),S.ajaxPrefilter(function(e){e.crossDomain&&(e.contents.script=!1)}),S.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(e){return S.globalEval(e),e}}}),S.ajaxPrefilter("script",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type="GET")}),S.ajaxTransport("script",function(n){var r,i;if(n.crossDomain||n.scriptAttrs)return{send:function(e,t){r=S("<script>").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var _t,zt=[],Ut=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=zt.pop()||S.expando+"_"+wt.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Ut.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Ut.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Ut,"$1"+r):!1!==e.jsonp&&(e.url+=(Tt.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,zt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((_t=E.implementation.createHTMLDocument("").body).innerHTML="<form></form><form></form>",2===_t.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1<s&&(r=ht(e.slice(s)),e=e.slice(0,s)),m(t)?(n=t,t=void 0):t&&"object"==typeof t&&(i="POST"),0<a.length&&S.ajax({url:e,type:i||"GET",dataType:"html",data:t}).done(function(e){o=arguments,a.html(r?S("<div>").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=Fe(y.pixelPosition,function(e,t){if(t)return t=We(e,n),Pe.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0<arguments.length?this.on(n,null,e,t):this.trigger(n)}});var Xt=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;S.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),m(e))return r=s.call(arguments,2),(i=function(){return e.apply(t||this,r.concat(s.call(arguments)))}).guid=e.guid=e.guid||S.guid++,i},S.holdReady=function(e){e?S.readyWait++:S.ready(!0)},S.isArray=Array.isArray,S.parseJSON=JSON.parse,S.nodeName=A,S.isFunction=m,S.isWindow=x,S.camelCase=X,S.type=w,S.now=Date.now,S.isNumeric=function(e){var t=S.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},S.trim=function(e){return null==e?"":(e+"").replace(Xt,"")},"function"==typeof define&&define.amd&&define("jquery",[],function(){return S});var Vt=C.jQuery,Gt=C.$;return S.noConflict=function(e){return C.$===S&&(C.$=Gt),e&&C.jQuery===S&&(C.jQuery=Vt),S},"undefined"==typeof e&&(C.jQuery=C.$=S),S});
+/*! jQuery UI - v1.12.1 - 2019-01-27
+* http://jqueryui.com
+* Includes: widget.js, position.js, data.js, disable-selection.js, focusable.js, form-reset-mixin.js, jquery-1-7.js, keycode.js, labels.js, scroll-parent.js, tabbable.js, unique-id.js, widgets/resizable.js, widgets/mouse.js
+* Copyright jQuery Foundation and other contributors; Licensed MIT */
+
+(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)})(function(t){function e(t){for(var e=t.css("visibility");"inherit"===e;)t=t.parent(),e=t.css("visibility");return"hidden"!==e}t.ui=t.ui||{},t.ui.version="1.12.1";var i=0,s=Array.prototype.slice;t.cleanData=function(e){return function(i){var s,n,o;for(o=0;null!=(n=i[o]);o++)try{s=t._data(n,"events"),s&&s.remove&&t(n).triggerHandler("remove")}catch(a){}e(i)}}(t.cleanData),t.widget=function(e,i,s){var n,o,a,r={},h=e.split(".")[0];e=e.split(".")[1];var l=h+"-"+e;return s||(s=i,i=t.Widget),t.isArray(s)&&(s=t.extend.apply(null,[{}].concat(s))),t.expr[":"][l.toLowerCase()]=function(e){return!!t.data(e,l)},t[h]=t[h]||{},n=t[h][e],o=t[h][e]=function(t,e){return this._createWidget?(arguments.length&&this._createWidget(t,e),void 0):new o(t,e)},t.extend(o,n,{version:s.version,_proto:t.extend({},s),_childConstructors:[]}),a=new i,a.options=t.widget.extend({},a.options),t.each(s,function(e,s){return t.isFunction(s)?(r[e]=function(){function t(){return i.prototype[e].apply(this,arguments)}function n(t){return i.prototype[e].apply(this,t)}return function(){var e,i=this._super,o=this._superApply;return this._super=t,this._superApply=n,e=s.apply(this,arguments),this._super=i,this._superApply=o,e}}(),void 0):(r[e]=s,void 0)}),o.prototype=t.widget.extend(a,{widgetEventPrefix:n?a.widgetEventPrefix||e:e},r,{constructor:o,namespace:h,widgetName:e,widgetFullName:l}),n?(t.each(n._childConstructors,function(e,i){var s=i.prototype;t.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete n._childConstructors):i._childConstructors.push(o),t.widget.bridge(e,o),o},t.widget.extend=function(e){for(var i,n,o=s.call(arguments,1),a=0,r=o.length;r>a;a++)for(i in o[a])n=o[a][i],o[a].hasOwnProperty(i)&&void 0!==n&&(e[i]=t.isPlainObject(n)?t.isPlainObject(e[i])?t.widget.extend({},e[i],n):t.widget.extend({},n):n);return e},t.widget.bridge=function(e,i){var n=i.prototype.widgetFullName||e;t.fn[e]=function(o){var a="string"==typeof o,r=s.call(arguments,1),h=this;return a?this.length||"instance"!==o?this.each(function(){var i,s=t.data(this,n);return"instance"===o?(h=s,!1):s?t.isFunction(s[o])&&"_"!==o.charAt(0)?(i=s[o].apply(s,r),i!==s&&void 0!==i?(h=i&&i.jquery?h.pushStack(i.get()):i,!1):void 0):t.error("no such method '"+o+"' for "+e+" widget instance"):t.error("cannot call methods on "+e+" prior to initialization; "+"attempted to call method '"+o+"'")}):h=void 0:(r.length&&(o=t.widget.extend.apply(null,[o].concat(r))),this.each(function(){var e=t.data(this,n);e?(e.option(o||{}),e._init&&e._init()):t.data(this,n,new i(o,this))})),h}},t.Widget=function(){},t.Widget._childConstructors=[],t.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{classes:{},disabled:!1,create:null},_createWidget:function(e,s){s=t(s||this.defaultElement||this)[0],this.element=t(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.bindings=t(),this.hoverable=t(),this.focusable=t(),this.classesElementLookup={},s!==this&&(t.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(t){t.target===s&&this.destroy()}}),this.document=t(s.style?s.ownerDocument:s.document||s),this.window=t(this.document[0].defaultView||this.document[0].parentWindow)),this.options=t.widget.extend({},this.options,this._getCreateOptions(),e),this._create(),this.options.disabled&&this._setOptionDisabled(this.options.disabled),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:function(){return{}},_getCreateEventData:t.noop,_create:t.noop,_init:t.noop,destroy:function(){var e=this;this._destroy(),t.each(this.classesElementLookup,function(t,i){e._removeClass(i,t)}),this.element.off(this.eventNamespace).removeData(this.widgetFullName),this.widget().off(this.eventNamespace).removeAttr("aria-disabled"),this.bindings.off(this.eventNamespace)},_destroy:t.noop,widget:function(){return this.element},option:function(e,i){var s,n,o,a=e;if(0===arguments.length)return t.widget.extend({},this.options);if("string"==typeof e)if(a={},s=e.split("."),e=s.shift(),s.length){for(n=a[e]=t.widget.extend({},this.options[e]),o=0;s.length-1>o;o++)n[s[o]]=n[s[o]]||{},n=n[s[o]];if(e=s.pop(),1===arguments.length)return void 0===n[e]?null:n[e];n[e]=i}else{if(1===arguments.length)return void 0===this.options[e]?null:this.options[e];a[e]=i}return this._setOptions(a),this},_setOptions:function(t){var e;for(e in t)this._setOption(e,t[e]);return this},_setOption:function(t,e){return"classes"===t&&this._setOptionClasses(e),this.options[t]=e,"disabled"===t&&this._setOptionDisabled(e),this},_setOptionClasses:function(e){var i,s,n;for(i in e)n=this.classesElementLookup[i],e[i]!==this.options.classes[i]&&n&&n.length&&(s=t(n.get()),this._removeClass(n,i),s.addClass(this._classes({element:s,keys:i,classes:e,add:!0})))},_setOptionDisabled:function(t){this._toggleClass(this.widget(),this.widgetFullName+"-disabled",null,!!t),t&&(this._removeClass(this.hoverable,null,"ui-state-hover"),this._removeClass(this.focusable,null,"ui-state-focus"))},enable:function(){return this._setOptions({disabled:!1})},disable:function(){return this._setOptions({disabled:!0})},_classes:function(e){function i(i,o){var a,r;for(r=0;i.length>r;r++)a=n.classesElementLookup[i[r]]||t(),a=e.add?t(t.unique(a.get().concat(e.element.get()))):t(a.not(e.element).get()),n.classesElementLookup[i[r]]=a,s.push(i[r]),o&&e.classes[i[r]]&&s.push(e.classes[i[r]])}var s=[],n=this;return e=t.extend({element:this.element,classes:this.options.classes||{}},e),this._on(e.element,{remove:"_untrackClassesElement"}),e.keys&&i(e.keys.match(/\S+/g)||[],!0),e.extra&&i(e.extra.match(/\S+/g)||[]),s.join(" ")},_untrackClassesElement:function(e){var i=this;t.each(i.classesElementLookup,function(s,n){-1!==t.inArray(e.target,n)&&(i.classesElementLookup[s]=t(n.not(e.target).get()))})},_removeClass:function(t,e,i){return this._toggleClass(t,e,i,!1)},_addClass:function(t,e,i){return this._toggleClass(t,e,i,!0)},_toggleClass:function(t,e,i,s){s="boolean"==typeof s?s:i;var n="string"==typeof t||null===t,o={extra:n?e:i,keys:n?t:e,element:n?this.element:t,add:s};return o.element.toggleClass(this._classes(o),s),this},_on:function(e,i,s){var n,o=this;"boolean"!=typeof e&&(s=i,i=e,e=!1),s?(i=n=t(i),this.bindings=this.bindings.add(i)):(s=i,i=this.element,n=this.widget()),t.each(s,function(s,a){function r(){return e||o.options.disabled!==!0&&!t(this).hasClass("ui-state-disabled")?("string"==typeof a?o[a]:a).apply(o,arguments):void 0}"string"!=typeof a&&(r.guid=a.guid=a.guid||r.guid||t.guid++);var h=s.match(/^([\w:-]*)\s*(.*)$/),l=h[1]+o.eventNamespace,c=h[2];c?n.on(l,c,r):i.on(l,r)})},_off:function(e,i){i=(i||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.off(i).off(i),this.bindings=t(this.bindings.not(e).get()),this.focusable=t(this.focusable.not(e).get()),this.hoverable=t(this.hoverable.not(e).get())},_delay:function(t,e){function i(){return("string"==typeof t?s[t]:t).apply(s,arguments)}var s=this;return setTimeout(i,e||0)},_hoverable:function(e){this.hoverable=this.hoverable.add(e),this._on(e,{mouseenter:function(e){this._addClass(t(e.currentTarget),null,"ui-state-hover")},mouseleave:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-hover")}})},_focusable:function(e){this.focusable=this.focusable.add(e),this._on(e,{focusin:function(e){this._addClass(t(e.currentTarget),null,"ui-state-focus")},focusout:function(e){this._removeClass(t(e.currentTarget),null,"ui-state-focus")}})},_trigger:function(e,i,s){var n,o,a=this.options[e];if(s=s||{},i=t.Event(i),i.type=(e===this.widgetEventPrefix?e:this.widgetEventPrefix+e).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,s),!(t.isFunction(a)&&a.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},t.each({show:"fadeIn",hide:"fadeOut"},function(e,i){t.Widget.prototype["_"+e]=function(s,n,o){"string"==typeof n&&(n={effect:n});var a,r=n?n===!0||"number"==typeof n?i:n.effect||i:e;n=n||{},"number"==typeof n&&(n={duration:n}),a=!t.isEmptyObject(n),n.complete=o,n.delay&&s.delay(n.delay),a&&t.effects&&t.effects.effect[r]?s[e](n):r!==e&&s[r]?s[r](n.duration,n.easing,o):s.queue(function(i){t(this)[e](),o&&o.call(s[0]),i()})}}),t.widget,function(){function e(t,e,i){return[parseFloat(t[0])*(u.test(t[0])?e/100:1),parseFloat(t[1])*(u.test(t[1])?i/100:1)]}function i(e,i){return parseInt(t.css(e,i),10)||0}function s(e){var i=e[0];return 9===i.nodeType?{width:e.width(),height:e.height(),offset:{top:0,left:0}}:t.isWindow(i)?{width:e.width(),height:e.height(),offset:{top:e.scrollTop(),left:e.scrollLeft()}}:i.preventDefault?{width:0,height:0,offset:{top:i.pageY,left:i.pageX}}:{width:e.outerWidth(),height:e.outerHeight(),offset:e.offset()}}var n,o=Math.max,a=Math.abs,r=/left|center|right/,h=/top|center|bottom/,l=/[\+\-]\d+(\.[\d]+)?%?/,c=/^\w+/,u=/%$/,d=t.fn.position;t.position={scrollbarWidth:function(){if(void 0!==n)return n;var e,i,s=t("<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>"),o=s.children()[0];return t("body").append(s),e=o.offsetWidth,s.css("overflow","scroll"),i=o.offsetWidth,e===i&&(i=s[0].clientWidth),s.remove(),n=e-i},getScrollInfo:function(e){var i=e.isWindow||e.isDocument?"":e.element.css("overflow-x"),s=e.isWindow||e.isDocument?"":e.element.css("overflow-y"),n="scroll"===i||"auto"===i&&e.width<e.element[0].scrollWidth,o="scroll"===s||"auto"===s&&e.height<e.element[0].scrollHeight;return{width:o?t.position.scrollbarWidth():0,height:n?t.position.scrollbarWidth():0}},getWithinInfo:function(e){var i=t(e||window),s=t.isWindow(i[0]),n=!!i[0]&&9===i[0].nodeType,o=!s&&!n;return{element:i,isWindow:s,isDocument:n,offset:o?t(e).offset():{left:0,top:0},scrollLeft:i.scrollLeft(),scrollTop:i.scrollTop(),width:i.outerWidth(),height:i.outerHeight()}}},t.fn.position=function(n){if(!n||!n.of)return d.apply(this,arguments);n=t.extend({},n);var u,p,f,m,g,_,v=t(n.of),b=t.position.getWithinInfo(n.within),y=t.position.getScrollInfo(b),w=(n.collision||"flip").split(" "),x={};return _=s(v),v[0].preventDefault&&(n.at="left top"),p=_.width,f=_.height,m=_.offset,g=t.extend({},m),t.each(["my","at"],function(){var t,e,i=(n[this]||"").split(" ");1===i.length&&(i=r.test(i[0])?i.concat(["center"]):h.test(i[0])?["center"].concat(i):["center","center"]),i[0]=r.test(i[0])?i[0]:"center",i[1]=h.test(i[1])?i[1]:"center",t=l.exec(i[0]),e=l.exec(i[1]),x[this]=[t?t[0]:0,e?e[0]:0],n[this]=[c.exec(i[0])[0],c.exec(i[1])[0]]}),1===w.length&&(w[1]=w[0]),"right"===n.at[0]?g.left+=p:"center"===n.at[0]&&(g.left+=p/2),"bottom"===n.at[1]?g.top+=f:"center"===n.at[1]&&(g.top+=f/2),u=e(x.at,p,f),g.left+=u[0],g.top+=u[1],this.each(function(){var s,r,h=t(this),l=h.outerWidth(),c=h.outerHeight(),d=i(this,"marginLeft"),_=i(this,"marginTop"),k=l+d+i(this,"marginRight")+y.width,C=c+_+i(this,"marginBottom")+y.height,D=t.extend({},g),T=e(x.my,h.outerWidth(),h.outerHeight());"right"===n.my[0]?D.left-=l:"center"===n.my[0]&&(D.left-=l/2),"bottom"===n.my[1]?D.top-=c:"center"===n.my[1]&&(D.top-=c/2),D.left+=T[0],D.top+=T[1],s={marginLeft:d,marginTop:_},t.each(["left","top"],function(e,i){t.ui.position[w[e]]&&t.ui.position[w[e]][i](D,{targetWidth:p,targetHeight:f,elemWidth:l,elemHeight:c,collisionPosition:s,collisionWidth:k,collisionHeight:C,offset:[u[0]+T[0],u[1]+T[1]],my:n.my,at:n.at,within:b,elem:h})}),n.using&&(r=function(t){var e=m.left-D.left,i=e+p-l,s=m.top-D.top,r=s+f-c,u={target:{element:v,left:m.left,top:m.top,width:p,height:f},element:{element:h,left:D.left,top:D.top,width:l,height:c},horizontal:0>i?"left":e>0?"right":"center",vertical:0>r?"top":s>0?"bottom":"middle"};l>p&&p>a(e+i)&&(u.horizontal="center"),c>f&&f>a(s+r)&&(u.vertical="middle"),u.important=o(a(e),a(i))>o(a(s),a(r))?"horizontal":"vertical",n.using.call(this,t,u)}),h.offset(t.extend(D,{using:r}))})},t.ui.position={fit:{left:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollLeft:s.offset.left,a=s.width,r=t.left-e.collisionPosition.marginLeft,h=n-r,l=r+e.collisionWidth-a-n;e.collisionWidth>a?h>0&&0>=l?(i=t.left+h+e.collisionWidth-a-n,t.left+=h-i):t.left=l>0&&0>=h?n:h>l?n+a-e.collisionWidth:n:h>0?t.left+=h:l>0?t.left-=l:t.left=o(t.left-r,t.left)},top:function(t,e){var i,s=e.within,n=s.isWindow?s.scrollTop:s.offset.top,a=e.within.height,r=t.top-e.collisionPosition.marginTop,h=n-r,l=r+e.collisionHeight-a-n;e.collisionHeight>a?h>0&&0>=l?(i=t.top+h+e.collisionHeight-a-n,t.top+=h-i):t.top=l>0&&0>=h?n:h>l?n+a-e.collisionHeight:n:h>0?t.top+=h:l>0?t.top-=l:t.top=o(t.top-r,t.top)}},flip:{left:function(t,e){var i,s,n=e.within,o=n.offset.left+n.scrollLeft,r=n.width,h=n.isWindow?n.scrollLeft:n.offset.left,l=t.left-e.collisionPosition.marginLeft,c=l-h,u=l+e.collisionWidth-r-h,d="left"===e.my[0]?-e.elemWidth:"right"===e.my[0]?e.elemWidth:0,p="left"===e.at[0]?e.targetWidth:"right"===e.at[0]?-e.targetWidth:0,f=-2*e.offset[0];0>c?(i=t.left+d+p+f+e.collisionWidth-r-o,(0>i||a(c)>i)&&(t.left+=d+p+f)):u>0&&(s=t.left-e.collisionPosition.marginLeft+d+p+f-h,(s>0||u>a(s))&&(t.left+=d+p+f))},top:function(t,e){var i,s,n=e.within,o=n.offset.top+n.scrollTop,r=n.height,h=n.isWindow?n.scrollTop:n.offset.top,l=t.top-e.collisionPosition.marginTop,c=l-h,u=l+e.collisionHeight-r-h,d="top"===e.my[1],p=d?-e.elemHeight:"bottom"===e.my[1]?e.elemHeight:0,f="top"===e.at[1]?e.targetHeight:"bottom"===e.at[1]?-e.targetHeight:0,m=-2*e.offset[1];0>c?(s=t.top+p+f+m+e.collisionHeight-r-o,(0>s||a(c)>s)&&(t.top+=p+f+m)):u>0&&(i=t.top-e.collisionPosition.marginTop+p+f+m-h,(i>0||u>a(i))&&(t.top+=p+f+m))}},flipfit:{left:function(){t.ui.position.flip.left.apply(this,arguments),t.ui.position.fit.left.apply(this,arguments)},top:function(){t.ui.position.flip.top.apply(this,arguments),t.ui.position.fit.top.apply(this,arguments)}}}}(),t.ui.position,t.extend(t.expr[":"],{data:t.expr.createPseudo?t.expr.createPseudo(function(e){return function(i){return!!t.data(i,e)}}):function(e,i,s){return!!t.data(e,s[3])}}),t.fn.extend({disableSelection:function(){var t="onselectstart"in document.createElement("div")?"selectstart":"mousedown";return function(){return this.on(t+".ui-disableSelection",function(t){t.preventDefault()})}}(),enableSelection:function(){return this.off(".ui-disableSelection")}}),t.ui.focusable=function(i,s){var n,o,a,r,h,l=i.nodeName.toLowerCase();return"area"===l?(n=i.parentNode,o=n.name,i.href&&o&&"map"===n.nodeName.toLowerCase()?(a=t("img[usemap='#"+o+"']"),a.length>0&&a.is(":visible")):!1):(/^(input|select|textarea|button|object)$/.test(l)?(r=!i.disabled,r&&(h=t(i).closest("fieldset")[0],h&&(r=!h.disabled))):r="a"===l?i.href||s:s,r&&t(i).is(":visible")&&e(t(i)))},t.extend(t.expr[":"],{focusable:function(e){return t.ui.focusable(e,null!=t.attr(e,"tabindex"))}}),t.ui.focusable,t.fn.form=function(){return"string"==typeof this[0].form?this.closest("form"):t(this[0].form)},t.ui.formResetMixin={_formResetHandler:function(){var e=t(this);setTimeout(function(){var i=e.data("ui-form-reset-instances");t.each(i,function(){this.refresh()})})},_bindFormResetHandler:function(){if(this.form=this.element.form(),this.form.length){var t=this.form.data("ui-form-reset-instances")||[];t.length||this.form.on("reset.ui-form-reset",this._formResetHandler),t.push(this),this.form.data("ui-form-reset-instances",t)}},_unbindFormResetHandler:function(){if(this.form.length){var e=this.form.data("ui-form-reset-instances");e.splice(t.inArray(this,e),1),e.length?this.form.data("ui-form-reset-instances",e):this.form.removeData("ui-form-reset-instances").off("reset.ui-form-reset")}}},"1.7"===t.fn.jquery.substring(0,3)&&(t.each(["Width","Height"],function(e,i){function s(e,i,s,o){return t.each(n,function(){i-=parseFloat(t.css(e,"padding"+this))||0,s&&(i-=parseFloat(t.css(e,"border"+this+"Width"))||0),o&&(i-=parseFloat(t.css(e,"margin"+this))||0)}),i}var n="Width"===i?["Left","Right"]:["Top","Bottom"],o=i.toLowerCase(),a={innerWidth:t.fn.innerWidth,innerHeight:t.fn.innerHeight,outerWidth:t.fn.outerWidth,outerHeight:t.fn.outerHeight};t.fn["inner"+i]=function(e){return void 0===e?a["inner"+i].call(this):this.each(function(){t(this).css(o,s(this,e)+"px")})},t.fn["outer"+i]=function(e,n){return"number"!=typeof e?a["outer"+i].call(this,e):this.each(function(){t(this).css(o,s(this,e,!0,n)+"px")})}}),t.fn.addBack=function(t){return this.add(null==t?this.prevObject:this.prevObject.filter(t))}),t.ui.keyCode={BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38},t.ui.escapeSelector=function(){var t=/([!"#$%&'()*+,./:;<=>?@[\]^`{|}~])/g;return function(e){return e.replace(t,"\\$1")}}(),t.fn.labels=function(){var e,i,s,n,o;return this[0].labels&&this[0].labels.length?this.pushStack(this[0].labels):(n=this.eq(0).parents("label"),s=this.attr("id"),s&&(e=this.eq(0).parents().last(),o=e.add(e.length?e.siblings():this.siblings()),i="label[for='"+t.ui.escapeSelector(s)+"']",n=n.add(o.find(i).addBack(i))),this.pushStack(n))},t.fn.scrollParent=function(e){var i=this.css("position"),s="absolute"===i,n=e?/(auto|scroll|hidden)/:/(auto|scroll)/,o=this.parents().filter(function(){var e=t(this);return s&&"static"===e.css("position")?!1:n.test(e.css("overflow")+e.css("overflow-y")+e.css("overflow-x"))}).eq(0);return"fixed"!==i&&o.length?o:t(this[0].ownerDocument||document)},t.extend(t.expr[":"],{tabbable:function(e){var i=t.attr(e,"tabindex"),s=null!=i;return(!s||i>=0)&&t.ui.focusable(e,s)}}),t.fn.extend({uniqueId:function(){var t=0;return function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++t)})}}(),removeUniqueId:function(){return this.each(function(){/^ui-id-\d+$/.test(this.id)&&t(this).removeAttr("id")})}}),t.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase());var n=!1;t(document).on("mouseup",function(){n=!1}),t.widget("ui.mouse",{version:"1.12.1",options:{cancel:"input, textarea, button, select, option",distance:1,delay:0},_mouseInit:function(){var e=this;this.element.on("mousedown."+this.widgetName,function(t){return e._mouseDown(t)}).on("click."+this.widgetName,function(i){return!0===t.data(i.target,e.widgetName+".preventClickEvent")?(t.removeData(i.target,e.widgetName+".preventClickEvent"),i.stopImmediatePropagation(),!1):void 0}),this.started=!1},_mouseDestroy:function(){this.element.off("."+this.widgetName),this._mouseMoveDelegate&&this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate)},_mouseDown:function(e){if(!n){this._mouseMoved=!1,this._mouseStarted&&this._mouseUp(e),this._mouseDownEvent=e;var i=this,s=1===e.which,o="string"==typeof this.options.cancel&&e.target.nodeName?t(e.target).closest(this.options.cancel).length:!1;return s&&!o&&this._mouseCapture(e)?(this.mouseDelayMet=!this.options.delay,this.mouseDelayMet||(this._mouseDelayTimer=setTimeout(function(){i.mouseDelayMet=!0},this.options.delay)),this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(e)!==!1,!this._mouseStarted)?(e.preventDefault(),!0):(!0===t.data(e.target,this.widgetName+".preventClickEvent")&&t.removeData(e.target,this.widgetName+".preventClickEvent"),this._mouseMoveDelegate=function(t){return i._mouseMove(t)},this._mouseUpDelegate=function(t){return i._mouseUp(t)},this.document.on("mousemove."+this.widgetName,this._mouseMoveDelegate).on("mouseup."+this.widgetName,this._mouseUpDelegate),e.preventDefault(),n=!0,!0)):!0}},_mouseMove:function(e){if(this._mouseMoved){if(t.ui.ie&&(!document.documentMode||9>document.documentMode)&&!e.button)return this._mouseUp(e);if(!e.which)if(e.originalEvent.altKey||e.originalEvent.ctrlKey||e.originalEvent.metaKey||e.originalEvent.shiftKey)this.ignoreMissingWhich=!0;else if(!this.ignoreMissingWhich)return this._mouseUp(e)}return(e.which||e.button)&&(this._mouseMoved=!0),this._mouseStarted?(this._mouseDrag(e),e.preventDefault()):(this._mouseDistanceMet(e)&&this._mouseDelayMet(e)&&(this._mouseStarted=this._mouseStart(this._mouseDownEvent,e)!==!1,this._mouseStarted?this._mouseDrag(e):this._mouseUp(e)),!this._mouseStarted)},_mouseUp:function(e){this.document.off("mousemove."+this.widgetName,this._mouseMoveDelegate).off("mouseup."+this.widgetName,this._mouseUpDelegate),this._mouseStarted&&(this._mouseStarted=!1,e.target===this._mouseDownEvent.target&&t.data(e.target,this.widgetName+".preventClickEvent",!0),this._mouseStop(e)),this._mouseDelayTimer&&(clearTimeout(this._mouseDelayTimer),delete this._mouseDelayTimer),this.ignoreMissingWhich=!1,n=!1,e.preventDefault()},_mouseDistanceMet:function(t){return Math.max(Math.abs(this._mouseDownEvent.pageX-t.pageX),Math.abs(this._mouseDownEvent.pageY-t.pageY))>=this.options.distance},_mouseDelayMet:function(){return this.mouseDelayMet},_mouseStart:function(){},_mouseDrag:function(){},_mouseStop:function(){},_mouseCapture:function(){return!0}}),t.ui.plugin={add:function(e,i,s){var n,o=t.ui[e].prototype;for(n in s)o.plugins[n]=o.plugins[n]||[],o.plugins[n].push([i,s[n]])},call:function(t,e,i,s){var n,o=t.plugins[e];if(o&&(s||t.element[0].parentNode&&11!==t.element[0].parentNode.nodeType))for(n=0;o.length>n;n++)t.options[o[n][0]]&&o[n][1].apply(t.element,i)}},t.widget("ui.resizable",t.ui.mouse,{version:"1.12.1",widgetEventPrefix:"resize",options:{alsoResize:!1,animate:!1,animateDuration:"slow",animateEasing:"swing",aspectRatio:!1,autoHide:!1,classes:{"ui-resizable-se":"ui-icon ui-icon-gripsmall-diagonal-se"},containment:!1,ghost:!1,grid:!1,handles:"e,s,se",helper:!1,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:90,resize:null,start:null,stop:null},_num:function(t){return parseFloat(t)||0},_isNumber:function(t){return!isNaN(parseFloat(t))},_hasScroll:function(e,i){if("hidden"===t(e).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",n=!1;return e[s]>0?!0:(e[s]=1,n=e[s]>0,e[s]=0,n)},_create:function(){var e,i=this.options,s=this;this._addClass("ui-resizable"),t.extend(this,{_aspectRatio:!!i.aspectRatio,aspectRatio:i.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:i.helper||i.ghost||i.animate?i.helper||"ui-resizable-helper":null}),this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)&&(this.element.wrap(t("<div class='ui-wrapper' style='overflow: hidden;'></div>").css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")})),this.element=this.element.parent().data("ui-resizable",this.element.resizable("instance")),this.elementIsWrapper=!0,e={marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom"),marginLeft:this.originalElement.css("marginLeft")},this.element.css(e),this.originalElement.css("margin",0),this.originalResizeStyle=this.originalElement.css("resize"),this.originalElement.css("resize","none"),this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"})),this.originalElement.css(e),this._proportionallyResize()),this._setupHandles(),i.autoHide&&t(this.element).on("mouseenter",function(){i.disabled||(s._removeClass("ui-resizable-autohide"),s._handles.show())}).on("mouseleave",function(){i.disabled||s.resizing||(s._addClass("ui-resizable-autohide"),s._handles.hide())}),this._mouseInit()},_destroy:function(){this._mouseDestroy();var e,i=function(e){t(e).removeData("resizable").removeData("ui-resizable").off(".resizable").find(".ui-resizable-handle").remove()};return this.elementIsWrapper&&(i(this.element),e=this.element,this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")}).insertAfter(e),e.remove()),this.originalElement.css("resize",this.originalResizeStyle),i(this.originalElement),this},_setOption:function(t,e){switch(this._super(t,e),t){case"handles":this._removeHandles(),this._setupHandles();break;default:}},_setupHandles:function(){var e,i,s,n,o,a=this.options,r=this;if(this.handles=a.handles||(t(".ui-resizable-handle",this.element).length?{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"}:"e,s,se"),this._handles=t(),this.handles.constructor===String)for("all"===this.handles&&(this.handles="n,e,s,w,se,sw,ne,nw"),s=this.handles.split(","),this.handles={},i=0;s.length>i;i++)e=t.trim(s[i]),n="ui-resizable-"+e,o=t("<div>"),this._addClass(o,"ui-resizable-handle "+n),o.css({zIndex:a.zIndex}),this.handles[e]=".ui-resizable-"+e,this.element.append(o);this._renderAxis=function(e){var i,s,n,o;e=e||this.element;for(i in this.handles)this.handles[i].constructor===String?this.handles[i]=this.element.children(this.handles[i]).first().show():(this.handles[i].jquery||this.handles[i].nodeType)&&(this.handles[i]=t(this.handles[i]),this._on(this.handles[i],{mousedown:r._mouseDown})),this.elementIsWrapper&&this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)&&(s=t(this.handles[i],this.element),o=/sw|ne|nw|se|n|s/.test(i)?s.outerHeight():s.outerWidth(),n=["padding",/ne|nw|n/.test(i)?"Top":/se|sw|s/.test(i)?"Bottom":/^e$/.test(i)?"Right":"Left"].join(""),e.css(n,o),this._proportionallyResize()),this._handles=this._handles.add(this.handles[i])},this._renderAxis(this.element),this._handles=this._handles.add(this.element.find(".ui-resizable-handle")),this._handles.disableSelection(),this._handles.on("mouseover",function(){r.resizing||(this.className&&(o=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)),r.axis=o&&o[1]?o[1]:"se")}),a.autoHide&&(this._handles.hide(),this._addClass("ui-resizable-autohide"))},_removeHandles:function(){this._handles.remove()},_mouseCapture:function(e){var i,s,n=!1;for(i in this.handles)s=t(this.handles[i])[0],(s===e.target||t.contains(s,e.target))&&(n=!0);return!this.options.disabled&&n},_mouseStart:function(e){var i,s,n,o=this.options,a=this.element;return this.resizing=!0,this._renderProxy(),i=this._num(this.helper.css("left")),s=this._num(this.helper.css("top")),o.containment&&(i+=t(o.containment).scrollLeft()||0,s+=t(o.containment).scrollTop()||0),this.offset=this.helper.offset(),this.position={left:i,top:s},this.size=this._helper?{width:this.helper.width(),height:this.helper.height()}:{width:a.width(),height:a.height()},this.originalSize=this._helper?{width:a.outerWidth(),height:a.outerHeight()}:{width:a.width(),height:a.height()},this.sizeDiff={width:a.outerWidth()-a.width(),height:a.outerHeight()-a.height()},this.originalPosition={left:i,top:s},this.originalMousePosition={left:e.pageX,top:e.pageY},this.aspectRatio="number"==typeof o.aspectRatio?o.aspectRatio:this.originalSize.width/this.originalSize.height||1,n=t(".ui-resizable-"+this.axis).css("cursor"),t("body").css("cursor","auto"===n?this.axis+"-resize":n),this._addClass("ui-resizable-resizing"),this._propagate("start",e),!0},_mouseDrag:function(e){var i,s,n=this.originalMousePosition,o=this.axis,a=e.pageX-n.left||0,r=e.pageY-n.top||0,h=this._change[o];return this._updatePrevProperties(),h?(i=h.apply(this,[e,a,r]),this._updateVirtualBoundaries(e.shiftKey),(this._aspectRatio||e.shiftKey)&&(i=this._updateRatio(i,e)),i=this._respectSize(i,e),this._updateCache(i),this._propagate("resize",e),s=this._applyChanges(),!this._helper&&this._proportionallyResizeElements.length&&this._proportionallyResize(),t.isEmptyObject(s)||(this._updatePrevProperties(),this._trigger("resize",e,this.ui()),this._applyChanges()),!1):!1},_mouseStop:function(e){this.resizing=!1;var i,s,n,o,a,r,h,l=this.options,c=this;return this._helper&&(i=this._proportionallyResizeElements,s=i.length&&/textarea/i.test(i[0].nodeName),n=s&&this._hasScroll(i[0],"left")?0:c.sizeDiff.height,o=s?0:c.sizeDiff.width,a={width:c.helper.width()-o,height:c.helper.height()-n},r=parseFloat(c.element.css("left"))+(c.position.left-c.originalPosition.left)||null,h=parseFloat(c.element.css("top"))+(c.position.top-c.originalPosition.top)||null,l.animate||this.element.css(t.extend(a,{top:h,left:r})),c.helper.height(c.size.height),c.helper.width(c.size.width),this._helper&&!l.animate&&this._proportionallyResize()),t("body").css("cursor","auto"),this._removeClass("ui-resizable-resizing"),this._propagate("stop",e),this._helper&&this.helper.remove(),!1},_updatePrevProperties:function(){this.prevPosition={top:this.position.top,left:this.position.left},this.prevSize={width:this.size.width,height:this.size.height}},_applyChanges:function(){var t={};return this.position.top!==this.prevPosition.top&&(t.top=this.position.top+"px"),this.position.left!==this.prevPosition.left&&(t.left=this.position.left+"px"),this.size.width!==this.prevSize.width&&(t.width=this.size.width+"px"),this.size.height!==this.prevSize.height&&(t.height=this.size.height+"px"),this.helper.css(t),t},_updateVirtualBoundaries:function(t){var e,i,s,n,o,a=this.options;o={minWidth:this._isNumber(a.minWidth)?a.minWidth:0,maxWidth:this._isNumber(a.maxWidth)?a.maxWidth:1/0,minHeight:this._isNumber(a.minHeight)?a.minHeight:0,maxHeight:this._isNumber(a.maxHeight)?a.maxHeight:1/0},(this._aspectRatio||t)&&(e=o.minHeight*this.aspectRatio,s=o.minWidth/this.aspectRatio,i=o.maxHeight*this.aspectRatio,n=o.maxWidth/this.aspectRatio,e>o.minWidth&&(o.minWidth=e),s>o.minHeight&&(o.minHeight=s),o.maxWidth>i&&(o.maxWidth=i),o.maxHeight>n&&(o.maxHeight=n)),this._vBoundaries=o},_updateCache:function(t){this.offset=this.helper.offset(),this._isNumber(t.left)&&(this.position.left=t.left),this._isNumber(t.top)&&(this.position.top=t.top),this._isNumber(t.height)&&(this.size.height=t.height),this._isNumber(t.width)&&(this.size.width=t.width)},_updateRatio:function(t){var e=this.position,i=this.size,s=this.axis;return this._isNumber(t.height)?t.width=t.height*this.aspectRatio:this._isNumber(t.width)&&(t.height=t.width/this.aspectRatio),"sw"===s&&(t.left=e.left+(i.width-t.width),t.top=null),"nw"===s&&(t.top=e.top+(i.height-t.height),t.left=e.left+(i.width-t.width)),t},_respectSize:function(t){var e=this._vBoundaries,i=this.axis,s=this._isNumber(t.width)&&e.maxWidth&&e.maxWidth<t.width,n=this._isNumber(t.height)&&e.maxHeight&&e.maxHeight<t.height,o=this._isNumber(t.width)&&e.minWidth&&e.minWidth>t.width,a=this._isNumber(t.height)&&e.minHeight&&e.minHeight>t.height,r=this.originalPosition.left+this.originalSize.width,h=this.originalPosition.top+this.originalSize.height,l=/sw|nw|w/.test(i),c=/nw|ne|n/.test(i);return o&&(t.width=e.minWidth),a&&(t.height=e.minHeight),s&&(t.width=e.maxWidth),n&&(t.height=e.maxHeight),o&&l&&(t.left=r-e.minWidth),s&&l&&(t.left=r-e.maxWidth),a&&c&&(t.top=h-e.minHeight),n&&c&&(t.top=h-e.maxHeight),t.width||t.height||t.left||!t.top?t.width||t.height||t.top||!t.left||(t.left=null):t.top=null,t},_getPaddingPlusBorderDimensions:function(t){for(var e=0,i=[],s=[t.css("borderTopWidth"),t.css("borderRightWidth"),t.css("borderBottomWidth"),t.css("borderLeftWidth")],n=[t.css("paddingTop"),t.css("paddingRight"),t.css("paddingBottom"),t.css("paddingLeft")];4>e;e++)i[e]=parseFloat(s[e])||0,i[e]+=parseFloat(n[e])||0;return{height:i[0]+i[2],width:i[1]+i[3]}},_proportionallyResize:function(){if(this._proportionallyResizeElements.length)for(var t,e=0,i=this.helper||this.element;this._proportionallyResizeElements.length>e;e++)t=this._proportionallyResizeElements[e],this.outerDimensions||(this.outerDimensions=this._getPaddingPlusBorderDimensions(t)),t.css({height:i.height()-this.outerDimensions.height||0,width:i.width()-this.outerDimensions.width||0})},_renderProxy:function(){var e=this.element,i=this.options;this.elementOffset=e.offset(),this._helper?(this.helper=this.helper||t("<div style='overflow:hidden;'></div>"),this._addClass(this.helper,this._helper),this.helper.css({width:this.element.outerWidth(),height:this.element.outerHeight(),position:"absolute",left:this.elementOffset.left+"px",top:this.elementOffset.top+"px",zIndex:++i.zIndex}),this.helper.appendTo("body").disableSelection()):this.helper=this.element
+},_change:{e:function(t,e){return{width:this.originalSize.width+e}},w:function(t,e){var i=this.originalSize,s=this.originalPosition;return{left:s.left+e,width:i.width-e}},n:function(t,e,i){var s=this.originalSize,n=this.originalPosition;return{top:n.top+i,height:s.height-i}},s:function(t,e,i){return{height:this.originalSize.height+i}},se:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},sw:function(e,i,s){return t.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[e,i,s]))},ne:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[e,i,s]))},nw:function(e,i,s){return t.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[e,i,s]))}},_propagate:function(e,i){t.ui.plugin.call(this,e,[i,this.ui()]),"resize"!==e&&this._trigger(e,i,this.ui())},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}),t.ui.plugin.add("resizable","animate",{stop:function(e){var i=t(this).resizable("instance"),s=i.options,n=i._proportionallyResizeElements,o=n.length&&/textarea/i.test(n[0].nodeName),a=o&&i._hasScroll(n[0],"left")?0:i.sizeDiff.height,r=o?0:i.sizeDiff.width,h={width:i.size.width-r,height:i.size.height-a},l=parseFloat(i.element.css("left"))+(i.position.left-i.originalPosition.left)||null,c=parseFloat(i.element.css("top"))+(i.position.top-i.originalPosition.top)||null;i.element.animate(t.extend(h,c&&l?{top:c,left:l}:{}),{duration:s.animateDuration,easing:s.animateEasing,step:function(){var s={width:parseFloat(i.element.css("width")),height:parseFloat(i.element.css("height")),top:parseFloat(i.element.css("top")),left:parseFloat(i.element.css("left"))};n&&n.length&&t(n[0]).css({width:s.width,height:s.height}),i._updateCache(s),i._propagate("resize",e)}})}}),t.ui.plugin.add("resizable","containment",{start:function(){var e,i,s,n,o,a,r,h=t(this).resizable("instance"),l=h.options,c=h.element,u=l.containment,d=u instanceof t?u.get(0):/parent/.test(u)?c.parent().get(0):u;d&&(h.containerElement=t(d),/document/.test(u)||u===document?(h.containerOffset={left:0,top:0},h.containerPosition={left:0,top:0},h.parentData={element:t(document),left:0,top:0,width:t(document).width(),height:t(document).height()||document.body.parentNode.scrollHeight}):(e=t(d),i=[],t(["Top","Right","Left","Bottom"]).each(function(t,s){i[t]=h._num(e.css("padding"+s))}),h.containerOffset=e.offset(),h.containerPosition=e.position(),h.containerSize={height:e.innerHeight()-i[3],width:e.innerWidth()-i[1]},s=h.containerOffset,n=h.containerSize.height,o=h.containerSize.width,a=h._hasScroll(d,"left")?d.scrollWidth:o,r=h._hasScroll(d)?d.scrollHeight:n,h.parentData={element:d,left:s.left,top:s.top,width:a,height:r}))},resize:function(e){var i,s,n,o,a=t(this).resizable("instance"),r=a.options,h=a.containerOffset,l=a.position,c=a._aspectRatio||e.shiftKey,u={top:0,left:0},d=a.containerElement,p=!0;d[0]!==document&&/static/.test(d.css("position"))&&(u=h),l.left<(a._helper?h.left:0)&&(a.size.width=a.size.width+(a._helper?a.position.left-h.left:a.position.left-u.left),c&&(a.size.height=a.size.width/a.aspectRatio,p=!1),a.position.left=r.helper?h.left:0),l.top<(a._helper?h.top:0)&&(a.size.height=a.size.height+(a._helper?a.position.top-h.top:a.position.top),c&&(a.size.width=a.size.height*a.aspectRatio,p=!1),a.position.top=a._helper?h.top:0),n=a.containerElement.get(0)===a.element.parent().get(0),o=/relative|absolute/.test(a.containerElement.css("position")),n&&o?(a.offset.left=a.parentData.left+a.position.left,a.offset.top=a.parentData.top+a.position.top):(a.offset.left=a.element.offset().left,a.offset.top=a.element.offset().top),i=Math.abs(a.sizeDiff.width+(a._helper?a.offset.left-u.left:a.offset.left-h.left)),s=Math.abs(a.sizeDiff.height+(a._helper?a.offset.top-u.top:a.offset.top-h.top)),i+a.size.width>=a.parentData.width&&(a.size.width=a.parentData.width-i,c&&(a.size.height=a.size.width/a.aspectRatio,p=!1)),s+a.size.height>=a.parentData.height&&(a.size.height=a.parentData.height-s,c&&(a.size.width=a.size.height*a.aspectRatio,p=!1)),p||(a.position.left=a.prevPosition.left,a.position.top=a.prevPosition.top,a.size.width=a.prevSize.width,a.size.height=a.prevSize.height)},stop:function(){var e=t(this).resizable("instance"),i=e.options,s=e.containerOffset,n=e.containerPosition,o=e.containerElement,a=t(e.helper),r=a.offset(),h=a.outerWidth()-e.sizeDiff.width,l=a.outerHeight()-e.sizeDiff.height;e._helper&&!i.animate&&/relative/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l}),e._helper&&!i.animate&&/static/.test(o.css("position"))&&t(this).css({left:r.left-n.left-s.left,width:h,height:l})}}),t.ui.plugin.add("resizable","alsoResize",{start:function(){var e=t(this).resizable("instance"),i=e.options;t(i.alsoResize).each(function(){var e=t(this);e.data("ui-resizable-alsoresize",{width:parseFloat(e.width()),height:parseFloat(e.height()),left:parseFloat(e.css("left")),top:parseFloat(e.css("top"))})})},resize:function(e,i){var s=t(this).resizable("instance"),n=s.options,o=s.originalSize,a=s.originalPosition,r={height:s.size.height-o.height||0,width:s.size.width-o.width||0,top:s.position.top-a.top||0,left:s.position.left-a.left||0};t(n.alsoResize).each(function(){var e=t(this),s=t(this).data("ui-resizable-alsoresize"),n={},o=e.parents(i.originalElement[0]).length?["width","height"]:["width","height","top","left"];t.each(o,function(t,e){var i=(s[e]||0)+(r[e]||0);i&&i>=0&&(n[e]=i||null)}),e.css(n)})},stop:function(){t(this).removeData("ui-resizable-alsoresize")}}),t.ui.plugin.add("resizable","ghost",{start:function(){var e=t(this).resizable("instance"),i=e.size;e.ghost=e.originalElement.clone(),e.ghost.css({opacity:.25,display:"block",position:"relative",height:i.height,width:i.width,margin:0,left:0,top:0}),e._addClass(e.ghost,"ui-resizable-ghost"),t.uiBackCompat!==!1&&"string"==typeof e.options.ghost&&e.ghost.addClass(this.options.ghost),e.ghost.appendTo(e.helper)},resize:function(){var e=t(this).resizable("instance");e.ghost&&e.ghost.css({position:"relative",height:e.size.height,width:e.size.width})},stop:function(){var e=t(this).resizable("instance");e.ghost&&e.helper&&e.helper.get(0).removeChild(e.ghost.get(0))}}),t.ui.plugin.add("resizable","grid",{resize:function(){var e,i=t(this).resizable("instance"),s=i.options,n=i.size,o=i.originalSize,a=i.originalPosition,r=i.axis,h="number"==typeof s.grid?[s.grid,s.grid]:s.grid,l=h[0]||1,c=h[1]||1,u=Math.round((n.width-o.width)/l)*l,d=Math.round((n.height-o.height)/c)*c,p=o.width+u,f=o.height+d,m=s.maxWidth&&p>s.maxWidth,g=s.maxHeight&&f>s.maxHeight,_=s.minWidth&&s.minWidth>p,v=s.minHeight&&s.minHeight>f;s.grid=h,_&&(p+=l),v&&(f+=c),m&&(p-=l),g&&(f-=c),/^(se|s|e)$/.test(r)?(i.size.width=p,i.size.height=f):/^(ne)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.top=a.top-d):/^(sw)$/.test(r)?(i.size.width=p,i.size.height=f,i.position.left=a.left-u):((0>=f-c||0>=p-l)&&(e=i._getPaddingPlusBorderDimensions(this)),f-c>0?(i.size.height=f,i.position.top=a.top-d):(f=c-e.height,i.size.height=f,i.position.top=a.top+o.height-f),p-l>0?(i.size.width=p,i.position.left=a.left-u):(p=l-e.width,i.size.width=p,i.position.left=a.left+o.width-p))}}),t.ui.resizable});/**
+ * Copyright (c) 2007 Ariel Flesler - aflesler ○ gmail • com | https://github.com/flesler
+ * Licensed under MIT
+ * @author Ariel Flesler
+ * @version 2.1.2
+ */
+;(function(f){"use strict";"function"===typeof define&&define.amd?define(["jquery"],f):"undefined"!==typeof module&&module.exports?module.exports=f(require("jquery")):f(jQuery)})(function($){"use strict";function n(a){return!a.nodeName||-1!==$.inArray(a.nodeName.toLowerCase(),["iframe","#document","html","body"])}function h(a){return $.isFunction(a)||$.isPlainObject(a)?a:{top:a,left:a}}var p=$.scrollTo=function(a,d,b){return $(window).scrollTo(a,d,b)};p.defaults={axis:"xy",duration:0,limit:!0};$.fn.scrollTo=function(a,d,b){"object"=== typeof d&&(b=d,d=0);"function"===typeof b&&(b={onAfter:b});"max"===a&&(a=9E9);b=$.extend({},p.defaults,b);d=d||b.duration;var u=b.queue&&1<b.axis.length;u&&(d/=2);b.offset=h(b.offset);b.over=h(b.over);return this.each(function(){function k(a){var k=$.extend({},b,{queue:!0,duration:d,complete:a&&function(){a.call(q,e,b)}});r.animate(f,k)}if(null!==a){var l=n(this),q=l?this.contentWindow||window:this,r=$(q),e=a,f={},t;switch(typeof e){case "number":case "string":if(/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(e)){e= h(e);break}e=l?$(e):$(e,q);case "object":if(e.length===0)return;if(e.is||e.style)t=(e=$(e)).offset()}var v=$.isFunction(b.offset)&&b.offset(q,e)||b.offset;$.each(b.axis.split(""),function(a,c){var d="x"===c?"Left":"Top",m=d.toLowerCase(),g="scroll"+d,h=r[g](),n=p.max(q,c);t?(f[g]=t[m]+(l?0:h-r.offset()[m]),b.margin&&(f[g]-=parseInt(e.css("margin"+d),10)||0,f[g]-=parseInt(e.css("border"+d+"Width"),10)||0),f[g]+=v[m]||0,b.over[m]&&(f[g]+=e["x"===c?"width":"height"]()*b.over[m])):(d=e[m],f[g]=d.slice&& "%"===d.slice(-1)?parseFloat(d)/100*n:d);b.limit&&/^\d+$/.test(f[g])&&(f[g]=0>=f[g]?0:Math.min(f[g],n));!a&&1<b.axis.length&&(h===f[g]?f={}:u&&(k(b.onAfterFirst),f={}))});k(b.onAfter)}})};p.max=function(a,d){var b="x"===d?"Width":"Height",h="scroll"+b;if(!n(a))return a[h]-$(a)[b.toLowerCase()]();var b="client"+b,k=a.ownerDocument||a.document,l=k.documentElement,k=k.body;return Math.max(l[h],k[h])-Math.min(l[b],k[b])};$.Tween.propHooks.scrollLeft=$.Tween.propHooks.scrollTop={get:function(a){return $(a.elem)[a.prop]()}, set:function(a){var d=this.get(a);if(a.options.interrupt&&a._last&&a._last!==d)return $(a.elem).stop();var b=Math.round(a.now);d!==b&&($(a.elem)[a.prop](b),a._last=this.get(a))}};return p});
+/*!
+ PowerTip v1.3.1 (2018-04-15)
+ https://stevenbenner.github.io/jquery-powertip/
+ Copyright (c) 2018 Steven Benner (http://stevenbenner.com/).
+ Released under MIT license.
+ https://raw.github.com/stevenbenner/jquery-powertip/master/LICENSE.txt
+*/
+(function(root,factory){if(typeof define==="function"&&define.amd){define(["jquery"],factory)}else if(typeof module==="object"&&module.exports){module.exports=factory(require("jquery"))}else{factory(root.jQuery)}})(this,function($){var $document=$(document),$window=$(window),$body=$("body");var DATA_DISPLAYCONTROLLER="displayController",DATA_HASACTIVEHOVER="hasActiveHover",DATA_FORCEDOPEN="forcedOpen",DATA_HASMOUSEMOVE="hasMouseMove",DATA_MOUSEONTOTIP="mouseOnToPopup",DATA_ORIGINALTITLE="originalTitle",DATA_POWERTIP="powertip",DATA_POWERTIPJQ="powertipjq",DATA_POWERTIPTARGET="powertiptarget",EVENT_NAMESPACE=".powertip",RAD2DEG=180/Math.PI,MOUSE_EVENTS=["click","dblclick","mousedown","mouseup","mousemove","mouseover","mouseout","mouseenter","mouseleave","contextmenu"];var session={tooltips:null,isTipOpen:false,isFixedTipOpen:false,isClosing:false,tipOpenImminent:false,activeHover:null,currentX:0,currentY:0,previousX:0,previousY:0,desyncTimeout:null,closeDelayTimeout:null,mouseTrackingActive:false,delayInProgress:false,windowWidth:0,windowHeight:0,scrollTop:0,scrollLeft:0};var Collision={none:0,top:1,bottom:2,left:4,right:8};$.fn.powerTip=function(opts,arg){var targetElements=this,options,tipController;if(!targetElements.length){return targetElements}if($.type(opts)==="string"&&$.powerTip[opts]){return $.powerTip[opts].call(targetElements,targetElements,arg)}options=$.extend({},$.fn.powerTip.defaults,opts);tipController=new TooltipController(options);initTracking();targetElements.each(function elementSetup(){var $this=$(this),dataPowertip=$this.data(DATA_POWERTIP),dataElem=$this.data(DATA_POWERTIPJQ),dataTarget=$this.data(DATA_POWERTIPTARGET),title=$this.attr("title");if(!dataPowertip&&!dataTarget&&!dataElem&&title){$this.data(DATA_POWERTIP,title);$this.data(DATA_ORIGINALTITLE,title);$this.removeAttr("title")}$this.data(DATA_DISPLAYCONTROLLER,new DisplayController($this,options,tipController))});if(!options.manual){$.each(options.openEvents,function(idx,evt){if($.inArray(evt,options.closeEvents)>-1){targetElements.on(evt+EVENT_NAMESPACE,function elementToggle(event){$.powerTip.toggle(this,event)})}else{targetElements.on(evt+EVENT_NAMESPACE,function elementOpen(event){$.powerTip.show(this,event)})}});$.each(options.closeEvents,function(idx,evt){if($.inArray(evt,options.openEvents)<0){targetElements.on(evt+EVENT_NAMESPACE,function elementClose(event){$.powerTip.hide(this,!isMouseEvent(event))})}});targetElements.on("keydown"+EVENT_NAMESPACE,function elementKeyDown(event){if(event.keyCode===27){$.powerTip.hide(this,true)}})}return targetElements};$.fn.powerTip.defaults={fadeInTime:200,fadeOutTime:100,followMouse:false,popupId:"powerTip",popupClass:null,intentSensitivity:7,intentPollInterval:100,closeDelay:100,placement:"n",smartPlacement:false,offset:10,mouseOnToPopup:false,manual:false,openEvents:["mouseenter","focus"],closeEvents:["mouseleave","blur"]};$.fn.powerTip.smartPlacementLists={n:["n","ne","nw","s"],e:["e","ne","se","w","nw","sw","n","s","e"],s:["s","se","sw","n"],w:["w","nw","sw","e","ne","se","n","s","w"],nw:["nw","w","sw","n","s","se","nw"],ne:["ne","e","se","n","s","sw","ne"],sw:["sw","w","nw","s","n","ne","sw"],se:["se","e","ne","s","n","nw","se"],"nw-alt":["nw-alt","n","ne-alt","sw-alt","s","se-alt","w","e"],"ne-alt":["ne-alt","n","nw-alt","se-alt","s","sw-alt","e","w"],"sw-alt":["sw-alt","s","se-alt","nw-alt","n","ne-alt","w","e"],"se-alt":["se-alt","s","sw-alt","ne-alt","n","nw-alt","e","w"]};$.powerTip={show:function apiShowTip(element,event){if(isMouseEvent(event)){trackMouse(event);session.previousX=event.pageX;session.previousY=event.pageY;$(element).data(DATA_DISPLAYCONTROLLER).show()}else{$(element).first().data(DATA_DISPLAYCONTROLLER).show(true,true)}return element},reposition:function apiResetPosition(element){$(element).first().data(DATA_DISPLAYCONTROLLER).resetPosition();return element},hide:function apiCloseTip(element,immediate){var displayController;immediate=element?immediate:true;if(element){displayController=$(element).first().data(DATA_DISPLAYCONTROLLER)}else if(session.activeHover){displayController=session.activeHover.data(DATA_DISPLAYCONTROLLER)}if(displayController){displayController.hide(immediate)}return element},toggle:function apiToggle(element,event){if(session.activeHover&&session.activeHover.is(element)){$.powerTip.hide(element,!isMouseEvent(event))}else{$.powerTip.show(element,event)}return element}};$.powerTip.showTip=$.powerTip.show;$.powerTip.closeTip=$.powerTip.hide;function CSSCoordinates(){var me=this;me.top="auto";me.left="auto";me.right="auto";me.bottom="auto";me.set=function(property,value){if($.isNumeric(value)){me[property]=Math.round(value)}}}function DisplayController(element,options,tipController){var hoverTimer=null,myCloseDelay=null;function openTooltip(immediate,forceOpen){cancelTimer();if(!element.data(DATA_HASACTIVEHOVER)){if(!immediate){session.tipOpenImminent=true;hoverTimer=setTimeout(function intentDelay(){hoverTimer=null;checkForIntent()},options.intentPollInterval)}else{if(forceOpen){element.data(DATA_FORCEDOPEN,true)}closeAnyDelayed();tipController.showTip(element)}}else{cancelClose()}}function closeTooltip(disableDelay){if(myCloseDelay){myCloseDelay=session.closeDelayTimeout=clearTimeout(myCloseDelay);session.delayInProgress=false}cancelTimer();session.tipOpenImminent=false;if(element.data(DATA_HASACTIVEHOVER)){element.data(DATA_FORCEDOPEN,false);if(!disableDelay){session.delayInProgress=true;session.closeDelayTimeout=setTimeout(function closeDelay(){session.closeDelayTimeout=null;tipController.hideTip(element);session.delayInProgress=false;myCloseDelay=null},options.closeDelay);myCloseDelay=session.closeDelayTimeout}else{tipController.hideTip(element)}}}function checkForIntent(){var xDifference=Math.abs(session.previousX-session.currentX),yDifference=Math.abs(session.previousY-session.currentY),totalDifference=xDifference+yDifference;if(totalDifference<options.intentSensitivity){cancelClose();closeAnyDelayed();tipController.showTip(element)}else{session.previousX=session.currentX;session.previousY=session.currentY;openTooltip()}}function cancelTimer(stopClose){hoverTimer=clearTimeout(hoverTimer);if(session.closeDelayTimeout&&myCloseDelay===session.closeDelayTimeout||stopClose){cancelClose()}}function cancelClose(){session.closeDelayTimeout=clearTimeout(session.closeDelayTimeout);session.delayInProgress=false}function closeAnyDelayed(){if(session.delayInProgress&&session.activeHover&&!session.activeHover.is(element)){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide(true)}}function repositionTooltip(){tipController.resetPosition(element)}this.show=openTooltip;this.hide=closeTooltip;this.cancel=cancelTimer;this.resetPosition=repositionTooltip}function PlacementCalculator(){function computePlacementCoords(element,placement,tipWidth,tipHeight,offset){var placementBase=placement.split("-")[0],coords=new CSSCoordinates,position;if(isSvgElement(element)){position=getSvgPlacement(element,placementBase)}else{position=getHtmlPlacement(element,placementBase)}switch(placement){case"n":coords.set("left",position.left-tipWidth/2);coords.set("bottom",session.windowHeight-position.top+offset);break;case"e":coords.set("left",position.left+offset);coords.set("top",position.top-tipHeight/2);break;case"s":coords.set("left",position.left-tipWidth/2);coords.set("top",position.top+offset);break;case"w":coords.set("top",position.top-tipHeight/2);coords.set("right",session.windowWidth-position.left+offset);break;case"nw":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"nw-alt":coords.set("left",position.left);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne":coords.set("left",position.left-20);coords.set("bottom",session.windowHeight-position.top+offset);break;case"ne-alt":coords.set("bottom",session.windowHeight-position.top+offset);coords.set("right",session.windowWidth-position.left);break;case"sw":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left-20);break;case"sw-alt":coords.set("left",position.left);coords.set("top",position.top+offset);break;case"se":coords.set("left",position.left-20);coords.set("top",position.top+offset);break;case"se-alt":coords.set("top",position.top+offset);coords.set("right",session.windowWidth-position.left);break}return coords}function getHtmlPlacement(element,placement){var objectOffset=element.offset(),objectWidth=element.outerWidth(),objectHeight=element.outerHeight(),left,top;switch(placement){case"n":left=objectOffset.left+objectWidth/2;top=objectOffset.top;break;case"e":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight/2;break;case"s":left=objectOffset.left+objectWidth/2;top=objectOffset.top+objectHeight;break;case"w":left=objectOffset.left;top=objectOffset.top+objectHeight/2;break;case"nw":left=objectOffset.left;top=objectOffset.top;break;case"ne":left=objectOffset.left+objectWidth;top=objectOffset.top;break;case"sw":left=objectOffset.left;top=objectOffset.top+objectHeight;break;case"se":left=objectOffset.left+objectWidth;top=objectOffset.top+objectHeight;break}return{top:top,left:left}}function getSvgPlacement(element,placement){var svgElement=element.closest("svg")[0],domElement=element[0],point=svgElement.createSVGPoint(),boundingBox=domElement.getBBox(),matrix=domElement.getScreenCTM(),halfWidth=boundingBox.width/2,halfHeight=boundingBox.height/2,placements=[],placementKeys=["nw","n","ne","e","se","s","sw","w"],coords,rotation,steps,x;function pushPlacement(){placements.push(point.matrixTransform(matrix))}point.x=boundingBox.x;point.y=boundingBox.y;pushPlacement();point.x+=halfWidth;pushPlacement();point.x+=halfWidth;pushPlacement();point.y+=halfHeight;pushPlacement();point.y+=halfHeight;pushPlacement();point.x-=halfWidth;pushPlacement();point.x-=halfWidth;pushPlacement();point.y-=halfHeight;pushPlacement();if(placements[0].y!==placements[1].y||placements[0].x!==placements[7].x){rotation=Math.atan2(matrix.b,matrix.a)*RAD2DEG;steps=Math.ceil((rotation%360-22.5)/45);if(steps<1){steps+=8}while(steps--){placementKeys.push(placementKeys.shift())}}for(x=0;x<placements.length;x++){if(placementKeys[x]===placement){coords=placements[x];break}}return{top:coords.y+session.scrollTop,left:coords.x+session.scrollLeft}}this.compute=computePlacementCoords}function TooltipController(options){var placementCalculator=new PlacementCalculator,tipElement=$("#"+options.popupId);if(tipElement.length===0){tipElement=$("<div/>",{id:options.popupId});if($body.length===0){$body=$("body")}$body.append(tipElement);session.tooltips=session.tooltips?session.tooltips.add(tipElement):tipElement}if(options.followMouse){if(!tipElement.data(DATA_HASMOUSEMOVE)){$document.on("mousemove"+EVENT_NAMESPACE,positionTipOnCursor);$window.on("scroll"+EVENT_NAMESPACE,positionTipOnCursor);tipElement.data(DATA_HASMOUSEMOVE,true)}}function beginShowTip(element){element.data(DATA_HASACTIVEHOVER,true);tipElement.queue(function queueTipInit(next){showTip(element);next()})}function showTip(element){var tipContent;if(!element.data(DATA_HASACTIVEHOVER)){return}if(session.isTipOpen){if(!session.isClosing){hideTip(session.activeHover)}tipElement.delay(100).queue(function queueTipAgain(next){showTip(element);next()});return}element.trigger("powerTipPreRender");tipContent=getTooltipContent(element);if(tipContent){tipElement.empty().append(tipContent)}else{return}element.trigger("powerTipRender");session.activeHover=element;session.isTipOpen=true;tipElement.data(DATA_MOUSEONTOTIP,options.mouseOnToPopup);tipElement.addClass(options.popupClass);if(!options.followMouse||element.data(DATA_FORCEDOPEN)){positionTipOnElement(element);session.isFixedTipOpen=true}else{positionTipOnCursor()}if(!element.data(DATA_FORCEDOPEN)&&!options.followMouse){$document.on("click"+EVENT_NAMESPACE,function documentClick(event){var target=event.target;if(target!==element[0]){if(options.mouseOnToPopup){if(target!==tipElement[0]&&!$.contains(tipElement[0],target)){$.powerTip.hide()}}else{$.powerTip.hide()}}})}if(options.mouseOnToPopup&&!options.manual){tipElement.on("mouseenter"+EVENT_NAMESPACE,function tipMouseEnter(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).cancel()}});tipElement.on("mouseleave"+EVENT_NAMESPACE,function tipMouseLeave(){if(session.activeHover){session.activeHover.data(DATA_DISPLAYCONTROLLER).hide()}})}tipElement.fadeIn(options.fadeInTime,function fadeInCallback(){if(!session.desyncTimeout){session.desyncTimeout=setInterval(closeDesyncedTip,500)}element.trigger("powerTipOpen")})}function hideTip(element){session.isClosing=true;session.isTipOpen=false;session.desyncTimeout=clearInterval(session.desyncTimeout);element.data(DATA_HASACTIVEHOVER,false);element.data(DATA_FORCEDOPEN,false);$document.off("click"+EVENT_NAMESPACE);tipElement.off(EVENT_NAMESPACE);tipElement.fadeOut(options.fadeOutTime,function fadeOutCallback(){var coords=new CSSCoordinates;session.activeHover=null;session.isClosing=false;session.isFixedTipOpen=false;tipElement.removeClass();coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);tipElement.css(coords);element.trigger("powerTipClose")})}function positionTipOnCursor(){var tipWidth,tipHeight,coords,collisions,collisionCount;if(!session.isFixedTipOpen&&(session.isTipOpen||session.tipOpenImminent&&tipElement.data(DATA_HASMOUSEMOVE))){tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=new CSSCoordinates;coords.set("top",session.currentY+options.offset);coords.set("left",session.currentX+options.offset);collisions=getViewportCollisions(coords,tipWidth,tipHeight);if(collisions!==Collision.none){collisionCount=countFlags(collisions);if(collisionCount===1){if(collisions===Collision.right){coords.set("left",session.scrollLeft+session.windowWidth-tipWidth)}else if(collisions===Collision.bottom){coords.set("top",session.scrollTop+session.windowHeight-tipHeight)}}else{coords.set("left",session.currentX-tipWidth-options.offset);coords.set("top",session.currentY-tipHeight-options.offset)}}tipElement.css(coords)}}function positionTipOnElement(element){var priorityList,finalPlacement;if(options.smartPlacement||options.followMouse&&element.data(DATA_FORCEDOPEN)){priorityList=$.fn.powerTip.smartPlacementLists[options.placement];$.each(priorityList,function(idx,pos){var collisions=getViewportCollisions(placeTooltip(element,pos),tipElement.outerWidth(),tipElement.outerHeight());finalPlacement=pos;return collisions!==Collision.none})}else{placeTooltip(element,options.placement);finalPlacement=options.placement}tipElement.removeClass("w nw sw e ne se n s w se-alt sw-alt ne-alt nw-alt");tipElement.addClass(finalPlacement)}function placeTooltip(element,placement){var iterationCount=0,tipWidth,tipHeight,coords=new CSSCoordinates;coords.set("top",0);coords.set("left",0);tipElement.css(coords);do{tipWidth=tipElement.outerWidth();tipHeight=tipElement.outerHeight();coords=placementCalculator.compute(element,placement,tipWidth,tipHeight,options.offset);tipElement.css(coords)}while(++iterationCount<=5&&(tipWidth!==tipElement.outerWidth()||tipHeight!==tipElement.outerHeight()));return coords}function closeDesyncedTip(){var isDesynced=false,hasDesyncableCloseEvent=$.grep(["mouseleave","mouseout","blur","focusout"],function(eventType){return $.inArray(eventType,options.closeEvents)!==-1}).length>0;if(session.isTipOpen&&!session.isClosing&&!session.delayInProgress&&hasDesyncableCloseEvent){if(session.activeHover.data(DATA_HASACTIVEHOVER)===false||session.activeHover.is(":disabled")){isDesynced=true}else if(!isMouseOver(session.activeHover)&&!session.activeHover.is(":focus")&&!session.activeHover.data(DATA_FORCEDOPEN)){if(tipElement.data(DATA_MOUSEONTOTIP)){if(!isMouseOver(tipElement)){isDesynced=true}}else{isDesynced=true}}if(isDesynced){hideTip(session.activeHover)}}}this.showTip=beginShowTip;this.hideTip=hideTip;this.resetPosition=positionTipOnElement}function isSvgElement(element){return Boolean(window.SVGElement&&element[0]instanceof SVGElement)}function isMouseEvent(event){return Boolean(event&&$.inArray(event.type,MOUSE_EVENTS)>-1&&typeof event.pageX==="number")}function initTracking(){if(!session.mouseTrackingActive){session.mouseTrackingActive=true;getViewportDimensions();$(getViewportDimensions);$document.on("mousemove"+EVENT_NAMESPACE,trackMouse);$window.on("resize"+EVENT_NAMESPACE,trackResize);$window.on("scroll"+EVENT_NAMESPACE,trackScroll)}}function getViewportDimensions(){session.scrollLeft=$window.scrollLeft();session.scrollTop=$window.scrollTop();session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackResize(){session.windowWidth=$window.width();session.windowHeight=$window.height()}function trackScroll(){var x=$window.scrollLeft(),y=$window.scrollTop();if(x!==session.scrollLeft){session.currentX+=x-session.scrollLeft;session.scrollLeft=x}if(y!==session.scrollTop){session.currentY+=y-session.scrollTop;session.scrollTop=y}}function trackMouse(event){session.currentX=event.pageX;session.currentY=event.pageY}function isMouseOver(element){var elementPosition=element.offset(),elementBox=element[0].getBoundingClientRect(),elementWidth=elementBox.right-elementBox.left,elementHeight=elementBox.bottom-elementBox.top;return session.currentX>=elementPosition.left&&session.currentX<=elementPosition.left+elementWidth&&session.currentY>=elementPosition.top&&session.currentY<=elementPosition.top+elementHeight}function getTooltipContent(element){var tipText=element.data(DATA_POWERTIP),tipObject=element.data(DATA_POWERTIPJQ),tipTarget=element.data(DATA_POWERTIPTARGET),targetElement,content;if(tipText){if($.isFunction(tipText)){tipText=tipText.call(element[0])}content=tipText}else if(tipObject){if($.isFunction(tipObject)){tipObject=tipObject.call(element[0])}if(tipObject.length>0){content=tipObject.clone(true,true)}}else if(tipTarget){targetElement=$("#"+tipTarget);if(targetElement.length>0){content=targetElement.html()}}return content}function getViewportCollisions(coords,elementWidth,elementHeight){var viewportTop=session.scrollTop,viewportLeft=session.scrollLeft,viewportBottom=viewportTop+session.windowHeight,viewportRight=viewportLeft+session.windowWidth,collisions=Collision.none;if(coords.top<viewportTop||Math.abs(coords.bottom-session.windowHeight)-elementHeight<viewportTop){collisions|=Collision.top}if(coords.top+elementHeight>viewportBottom||Math.abs(coords.bottom-session.windowHeight)>viewportBottom){collisions|=Collision.bottom}if(coords.left<viewportLeft||coords.right+elementWidth>viewportRight){collisions|=Collision.left}if(coords.left+elementWidth>viewportRight||coords.right<viewportLeft){collisions|=Collision.right}return collisions}function countFlags(value){var count=0;while(value){value&=value-1;count++}return count}return $.powerTip});/*!
+ * jQuery UI Touch Punch 0.2.3
+ *
+ * Copyright 2011–2014, Dave Furfero
+ * Dual licensed under the MIT or GPL Version 2 licenses.
+ *
+ * Depends:
+ *  jquery.ui.widget.js
+ *  jquery.ui.mouse.js
+ */
+!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);/*! SmartMenus jQuery Plugin - v1.1.0 - September 17, 2017
+ * http://www.smartmenus.org/
+ * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).off(e),mouseDetectionEnabled=!1);else{var i=!0,s=null,o={mousemove:function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}};o[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut"]=function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)},$(document).on(getEventsNS(o,e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};for(var s in t)i[s.split(" ").join(e+" ")+e]=t[s];return i}var menuTrees=[],mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)},canAnimate=!!$.fn.animate;return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).on(getEventsNS({"mouseover focusin":$.proxy(this.rootOver,this),"mouseout focusout":$.proxy(this.rootOut,this),keydown:$.proxy(this.rootKeyDown,this)},i)).on(getEventsNS({mouseenter:$.proxy(this.itemEnter,this),mouseleave:$.proxy(this.itemLeave,this),mousedown:$.proxy(this.itemDown,this),focus:$.proxy(this.itemFocus,this),blur:$.proxy(this.itemBlur,this),click:$.proxy(this.itemClick,this)},i),"a"),i+=this.rootId,this.opts.hideOnClick&&$(document).on(getEventsNS({touchstart:$.proxy(this.docTouchStart,this),touchmove:$.proxy(this.docTouchMove,this),touchend:$.proxy(this.docTouchEnd,this),click:$.proxy(this.docClick,this)},i)),$(window).on(getEventsNS({"resize orientationchange":$.proxy(this.winResize,this)},i)),this.opts.subIndicators&&(this.$subArrow=$("<span/>").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").off(e),e+=this.rootId,$(document).off(e),$(window).off(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('<div class="sm-jquery-disable-overlay"/>').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).closest("a").length)&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"inline"!=this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is(".sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1,a=this.isCollapsible(),n=/toggle$/.test(this.opts.collapsibleBehavior),r=/link$/.test(this.opts.collapsibleBehavior),h=/^accordion/.test(this.opts.collapsibleBehavior);if(s&&!s.is(":visible")){if((!r||!a||i)&&(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e,h),s.is(":visible")))return this.focusActivated=!0,!1}else if(a&&(n||i))return this.itemActivate(e,h),this.menuHide(s),n&&(this.focusActivated=!1),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}},itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(canAnimate&&t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?canAnimate&&this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).off(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(canAnimate&&this.$root.stop(!0,!0),this.$root.is(":visible")&&(canAnimate&&this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration))),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),b=this.getViewportWidth(),S=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenuSubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+b&&(e=g?f+b-r-y+e:w-r),g||(S>h&&I+h>v+S?i+=v+S-h-I:(h>=S||v>I)&&(i+=v-I)),g&&(I+h>v+S+.49||v>I)||!g&&h>S+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0],$('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]).on({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var A=".smartmenus_scroll";if(t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).on(getEventsNS({mouseover:function(e){x.menuScrollOver(t,e)},mouseout:function(e){x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(e){x.menuScrollMousewheel(t,e)}},A)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()){var C={};C[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp"]=function(e){x.menuScrollTouch(t,e)},t.css({"touch-action":"none","-ms-touch-action":"none"}).on(getEventsNS(C,A))}}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y<o.upEnd)&&a.eq(o.up?1:0).show(),o.y==n)mouse&&a.eq(o.up?0:1).hide(),this.menuScrollStop(t);else if(!e){this.opts.scrollAccelerate&&o.step<this.opts.scrollStep&&(o.step+=.2);var h=this;this.scrollTimeout=requestAnimationFrame(function(){h.menuScroll(t)})}},menuScrollMousewheel:function(t,e){if(this.getClosestMenu(e.target)==t[0]){e=e.originalEvent;var i=(e.wheelDelta||-e.detail)>0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0),canAnimate&&t.stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a"),i=this.isCollapsible();if((this.opts.keepHighlighted||i)&&e.addClass("highlighted"),i)t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var s=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),s>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t)}var o=function(){t.css("overflow","")};i?canAnimate&&this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,o):t.show(this.opts.collapsibleShowDuration,o):canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,t,o):t.show(this.opts.showDuration,o),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0),canAnimate&&this.$root.stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e});var i=this,s=function(){i.$root.css("overflow","")};canAnimate&&this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}return this.each(function(){var dataOpts=$(this).data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"append",subIndicatorsText:"",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,collapsibleBehavior:"default"},$});
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/menu.js b/ld_client/doc/pdoc/menu.js
new file mode 100644
index 0000000..818b859
--- /dev/null
+++ b/ld_client/doc/pdoc/menu.js
@@ -0,0 +1,135 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+ */
+function initMenu(relPath,searchEnabled,serverSide,searchPage,search) {
+  function makeTree(data,relPath) {
+    var result='';
+    if ('children' in data) {
+      result+='<ul>';
+      for (var i in data.children) {
+        var url;
+        var link;
+        link = data.children[i].url;
+        if (link.substring(0,1)=='^') {
+          url = link.substring(1);
+        } else {
+          url = relPath+link;
+        }
+        result+='<li><a href="'+url+'">'+
+                                data.children[i].text+'</a>'+
+                                makeTree(data.children[i],relPath)+'</li>';
+      }
+      result+='</ul>';
+    }
+    return result;
+  }
+  var searchBox;
+  if (searchEnabled) {
+    if (serverSide) {
+      searchBox='<div id="MSearchBox" class="MSearchBoxInactive">'+
+                 '<div class="left">'+
+                  '<form id="FSearchBox" action="'+relPath+searchPage+
+                    '" method="get"><img id="MSearchSelect" src="'+
+                    relPath+'search/mag.svg" alt=""/>'+
+                  '<input type="text" id="MSearchField" name="query" value="'+search+
+                    '" size="20" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)"'+
+                    ' onblur="searchBox.OnSearchFieldFocus(false)">'+
+                  '</form>'+
+                 '</div>'+
+                 '<div class="right"></div>'+
+                '</div>';
+    } else {
+      searchBox='<div id="MSearchBox" class="MSearchBoxInactive">'+
+                 '<span class="left">'+
+                  '<img id="MSearchSelect" src="'+relPath+
+                     'search/mag_sel.svg" onmouseover="return searchBox.OnSearchSelectShow()"'+
+                     ' onmouseout="return searchBox.OnSearchSelectHide()" alt=""/>'+
+                  '<input type="text" id="MSearchField" value="'+search+
+                    '" accesskey="S" onfocus="searchBox.OnSearchFieldFocus(true)" '+
+                    'onblur="searchBox.OnSearchFieldFocus(false)" '+
+                    'onkeyup="searchBox.OnSearchFieldChange(event)"/>'+
+                 '</span>'+
+                 '<span class="right"><a id="MSearchClose" '+
+                  'href="javascript:searchBox.CloseResultsWindow()">'+
+                  '<img id="MSearchCloseImg" border="0" src="'+relPath+
+                  'search/close.svg" alt=""/></a>'
+                 '</span>'
+                '</div>';
+    }
+  }
+
+  $('#main-nav').before('<div class="sm sm-dox"><input id="main-menu-state" type="checkbox"/>'+
+                        '<label class="main-menu-btn" for="main-menu-state">'+
+                        '<span class="main-menu-btn-icon"></span> '+
+                        'Toggle main menu visibility</label>'+
+                        '<span id="searchBoxPos1" style="position:absolute;right:8px;top:8px;height:36px;"></span>'+
+                        '</div>');
+  $('#main-nav').append(makeTree(menudata,relPath));
+  $('#main-nav').children(':first').addClass('sm sm-dox').attr('id','main-menu');
+  if (searchBox) {
+    $('#main-menu').append('<li id="searchBoxPos2" style="float:right"></li>');
+  }
+  var $mainMenuState = $('#main-menu-state');
+  var prevWidth = 0;
+  if ($mainMenuState.length) {
+    function initResizableIfExists() {
+      if (typeof initResizable==='function') initResizable();
+    }
+    // animate mobile menu
+    $mainMenuState.change(function(e) {
+      var $menu = $('#main-menu');
+      var options = { duration: 250, step: initResizableIfExists };
+      if (this.checked) {
+        options['complete'] = function() { $menu.css('display', 'block') };
+        $menu.hide().slideDown(options);
+      } else {
+        options['complete'] = function() { $menu.css('display', 'none') };
+        $menu.show().slideUp(options);
+      }
+    });
+    // set default menu visibility
+    function resetState() {
+      var $menu = $('#main-menu');
+      var $mainMenuState = $('#main-menu-state');
+      var newWidth = $(window).outerWidth();
+      if (newWidth!=prevWidth) {
+        if ($(window).outerWidth()<768) {
+          $mainMenuState.prop('checked',false); $menu.hide();
+          $('#searchBoxPos1').html(searchBox);
+          $('#searchBoxPos2').hide();
+        } else {
+          $menu.show();
+          $('#searchBoxPos1').empty();
+          $('#searchBoxPos2').html(searchBox);
+          $('#searchBoxPos2').show();
+        }
+        prevWidth = newWidth;
+      }
+    }
+    $(window).ready(function() { resetState(); initResizableIfExists(); });
+    $(window).resize(resetState);
+  }
+  $('#main-menu').smartmenus();
+}
+/* @license-end */
diff --git a/ld_client/doc/pdoc/menudata.js b/ld_client/doc/pdoc/menudata.js
new file mode 100644
index 0000000..bdd6830
--- /dev/null
+++ b/ld_client/doc/pdoc/menudata.js
@@ -0,0 +1,66 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+*/
+var menudata={children:[
+{text:"Main Page",url:"index.html"},
+{text:"Packages",url:"namespaces.html",children:[
+{text:"Package List",url:"namespaces.html"},
+{text:"Package Members",url:"namespacemembers.html",children:[
+{text:"All",url:"namespacemembers.html"},
+{text:"Enumerations",url:"namespacemembers_enum.html"}]}]},
+{text:"Classes",url:"annotated.html",children:[
+{text:"Class List",url:"annotated.html"},
+{text:"Class Index",url:"classes.html"},
+{text:"Class Hierarchy",url:"hierarchy.html"},
+{text:"Class Members",url:"functions.html",children:[
+{text:"All",url:"functions.html",children:[
+{text:"_",url:"functions.html#index__5F"},
+{text:"a",url:"functions.html#index_a"},
+{text:"b",url:"functions.html#index_b"},
+{text:"c",url:"functions.html#index_c"},
+{text:"d",url:"functions.html#index_d"},
+{text:"e",url:"functions.html#index_e"},
+{text:"f",url:"functions.html#index_f"},
+{text:"h",url:"functions.html#index_h"},
+{text:"i",url:"functions.html#index_i"},
+{text:"p",url:"functions.html#index_p"},
+{text:"r",url:"functions.html#index_r"},
+{text:"s",url:"functions.html#index_s"},
+{text:"t",url:"functions.html#index_t"},
+{text:"u",url:"functions.html#index_u"}]},
+{text:"Functions",url:"functions_func.html",children:[
+{text:"a",url:"functions_func.html#index_a"},
+{text:"c",url:"functions_func.html#index_c"},
+{text:"d",url:"functions_func.html#index_d"},
+{text:"e",url:"functions_func.html#index_e"},
+{text:"f",url:"functions_func.html#index_f"},
+{text:"h",url:"functions_func.html#index_h"},
+{text:"i",url:"functions_func.html#index_i"},
+{text:"p",url:"functions_func.html#index_p"},
+{text:"r",url:"functions_func.html#index_r"},
+{text:"s",url:"functions_func.html#index_s"},
+{text:"t",url:"functions_func.html#index_t"},
+{text:"u",url:"functions_func.html#index_u"}]},
+{text:"Variables",url:"functions_vars.html"},
+{text:"Properties",url:"functions_prop.html"}]}]}]}
diff --git a/ld_client/doc/pdoc/namespace_l_d_client.html b/ld_client/doc/pdoc/namespace_l_d_client.html
new file mode 100644
index 0000000..c14ee5f
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client.js b/ld_client/doc/pdoc/namespace_l_d_client.js
new file mode 100644
index 0000000..5099a19
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client.js
@@ -0,0 +1,6 @@
+var namespace_l_d_client =
+[
+    [ "detection", "namespace_l_d_client_1_1detection.html", "namespace_l_d_client_1_1detection" ],
+    [ "network", "namespace_l_d_client_1_1network.html", "namespace_l_d_client_1_1network" ],
+    [ "utils", "namespace_l_d_client_1_1utils.html", "namespace_l_d_client_1_1utils" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html
new file mode 100644
index 0000000..8e858c2
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.html
@@ -0,0 +1,126 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.detection Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client_1_1detection.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#nested-classes">Classes</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.detection Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
+Classes</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><b>DebuggerInfoParser</b></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class parses the .txt file generated from the debugger. Its primary interest is to find two serial numbers (head + body). <br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html">IInfoFetcher</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger.  <a href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html">InfoFetcher</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher.  <a href="class_l_d_client_1_1detection_1_1_info_fetcher.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><b>IProcessDetection</b></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines the functionality of a process detector. A process detector is used to determine whether a user is currently using a debugger or not. <br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html">IProcessUtils</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines the functionality of all methods that are used to work with processes (within this project).  <a href="interface_l_d_client_1_1detection_1_1_i_process_utils.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html">ProcessDetection</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger.  <a href="class_l_d_client_1_1detection_1_1_process_detection.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html">ProcessUtils</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes.  <a href="class_l_d_client_1_1detection_1_1_process_utils.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1detection.html">detection</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js
new file mode 100644
index 0000000..de070af
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1detection.js
@@ -0,0 +1,8 @@
+var namespace_l_d_client_1_1detection =
+[
+    [ "IInfoFetcher", "interface_l_d_client_1_1detection_1_1_i_info_fetcher.html", "interface_l_d_client_1_1detection_1_1_i_info_fetcher" ],
+    [ "InfoFetcher", "class_l_d_client_1_1detection_1_1_info_fetcher.html", "class_l_d_client_1_1detection_1_1_info_fetcher" ],
+    [ "IProcessUtils", "interface_l_d_client_1_1detection_1_1_i_process_utils.html", "interface_l_d_client_1_1detection_1_1_i_process_utils" ],
+    [ "ProcessDetection", "class_l_d_client_1_1detection_1_1_process_detection.html", "class_l_d_client_1_1detection_1_1_process_detection" ],
+    [ "ProcessUtils", "class_l_d_client_1_1detection_1_1_process_utils.html", "class_l_d_client_1_1detection_1_1_process_utils" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html
new file mode 100644
index 0000000..a166f36
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.html
@@ -0,0 +1,117 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client_1_1network.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#nested-classes">Classes</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
+Classes</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html">ApiClient</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client.  <a href="class_l_d_client_1_1network_1_1_api_client.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html">HttpClient</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server.  <a href="class_l_d_client_1_1network_1_1_http_client.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html">IApiClient</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines the functionality of an API client which is used to send information (payloads) to the server.  <a href="interface_l_d_client_1_1network_1_1_i_api_client.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html">IHttpClient</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server.  <a href="interface_l_d_client_1_1network_1_1_i_http_client.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js
new file mode 100644
index 0000000..95e41ff
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network.js
@@ -0,0 +1,8 @@
+var namespace_l_d_client_1_1network =
+[
+    [ "data", "namespace_l_d_client_1_1network_1_1data.html", "namespace_l_d_client_1_1network_1_1data" ],
+    [ "ApiClient", "class_l_d_client_1_1network_1_1_api_client.html", "class_l_d_client_1_1network_1_1_api_client" ],
+    [ "HttpClient", "class_l_d_client_1_1network_1_1_http_client.html", "class_l_d_client_1_1network_1_1_http_client" ],
+    [ "IApiClient", "interface_l_d_client_1_1network_1_1_i_api_client.html", "interface_l_d_client_1_1network_1_1_i_api_client" ],
+    [ "IHttpClient", "interface_l_d_client_1_1network_1_1_i_http_client.html", "interface_l_d_client_1_1network_1_1_i_http_client" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html
new file mode 100644
index 0000000..38e4cf2
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.html
@@ -0,0 +1,143 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.network.data Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client_1_1network_1_1data.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#nested-classes">Classes</a> &#124;
+<a href="#enum-members">Enumerations</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.network.data Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
+Classes</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html">DebuggerInfo</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class holds all the information about a specific part of a debugger (head/body).  <a href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html">Payload</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class represents a single payload that is sent to the server.  <a href="class_l_d_client_1_1network_1_1data_1_1_payload.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr class="memitem:a0c6d481eff113dd190f5a162b6464e60"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">ConnectionStatus</a> { <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7">Connected</a>
+, <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0">Disconnected</a>
+ }</td></tr>
+<tr class="memdesc:a0c6d481eff113dd190f5a162b6464e60"><td class="mdescLeft">&#160;</td><td class="mdescRight">This enumeration defines different states in which a debugger can be.  <a href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">More...</a><br /></td></tr>
+<tr class="separator:a0c6d481eff113dd190f5a162b6464e60"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<h2 class="groupheader">Enumeration Type Documentation</h2>
+<a id="a0c6d481eff113dd190f5a162b6464e60" name="a0c6d481eff113dd190f5a162b6464e60"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a0c6d481eff113dd190f5a162b6464e60">&#9670;&nbsp;</a></span>ConnectionStatus</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">enum <a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data.ConnectionStatus</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>This enumeration defines different states in which a debugger can be. </p>
+<table class="fieldtable">
+<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7" name="a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7"></a>Connected&#160;</td><td class="fielddoc"><p >Debugger is connected </p>
+</td></tr>
+<tr><td class="fieldname"><a id="a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0" name="a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0"></a>Disconnected&#160;</td><td class="fielddoc"><p >Debugger is disconnected </p>
+</td></tr>
+</table>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network.html">network</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1network_1_1data.html">data</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js
new file mode 100644
index 0000000..3bba0dc
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1network_1_1data.js
@@ -0,0 +1,9 @@
+var namespace_l_d_client_1_1network_1_1data =
+[
+    [ "DebuggerInfo", "class_l_d_client_1_1network_1_1data_1_1_debugger_info.html", "class_l_d_client_1_1network_1_1data_1_1_debugger_info" ],
+    [ "Payload", "class_l_d_client_1_1network_1_1data_1_1_payload.html", "class_l_d_client_1_1network_1_1data_1_1_payload" ],
+    [ "ConnectionStatus", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60", [
+      [ "Connected", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7", null ],
+      [ "Disconnected", "namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0", null ]
+    ] ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html
new file mode 100644
index 0000000..4505713
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.html
@@ -0,0 +1,114 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client_1_1utils.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#nested-classes">Classes</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
+Classes</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><b>ConfigLoader</b></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class loads up the configuration file (appsettingss.json). <br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html">FileUtils</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations.  <a href="class_l_d_client_1_1utils_1_1_file_utils.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">interface &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html">IFileUtils</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This interface defines IO operations.  <a href="interface_l_d_client_1_1utils_1_1_i_file_utils.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js
new file mode 100644
index 0000000..8cfd3d6
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils.js
@@ -0,0 +1,6 @@
+var namespace_l_d_client_1_1utils =
+[
+    [ "loggers", "namespace_l_d_client_1_1utils_1_1loggers.html", "namespace_l_d_client_1_1utils_1_1loggers" ],
+    [ "FileUtils", "class_l_d_client_1_1utils_1_1_file_utils.html", "class_l_d_client_1_1utils_1_1_file_utils" ],
+    [ "IFileUtils", "interface_l_d_client_1_1utils_1_1_i_file_utils.html", "interface_l_d_client_1_1utils_1_1_i_file_utils" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html
new file mode 100644
index 0000000..f600f48
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.html
@@ -0,0 +1,154 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: LDClient.utils.loggers Namespace Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespace_l_d_client_1_1utils_1_1loggers.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="summary">
+<a href="#nested-classes">Classes</a> &#124;
+<a href="#enum-members">Enumerations</a>  </div>
+  <div class="headertitle"><div class="title">LDClient.utils.loggers Namespace Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="nested-classes" name="nested-classes"></a>
+Classes</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html">ALogger</a></td></tr>
+<tr class="memdesc:"><td class="mdescLeft">&#160;</td><td class="mdescRight">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern  <a href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#details">More...</a><br /></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">class &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html">ConsoleLogger</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table><table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="enum-members" name="enum-members"></a>
+Enumerations</h2></td></tr>
+<tr class="memitem:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="memItemLeft" align="right" valign="top">enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LogFlow</a> { <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f">Console</a> = 0
+, <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e">File</a>
+ }</td></tr>
+<tr class="memdesc:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="mdescLeft">&#160;</td><td class="mdescRight">This enum specifies all possible types of loggers  <a href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">More...</a><br /></td></tr>
+<tr class="separator:a8a6f0dbee11cb125ee34af8fcc8bc345"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:afeef5648c4f78e32623be5fa2b27f37c"><td class="memItemLeft" align="right" valign="top"><a id="afeef5648c4f78e32623be5fa2b27f37c" name="afeef5648c4f78e32623be5fa2b27f37c"></a>enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LogType</a> { <b>Info</b> = 0
+, <b>Debug</b>
+, <b>Error</b>
+ }</td></tr>
+<tr class="memdesc:afeef5648c4f78e32623be5fa2b27f37c"><td class="mdescLeft">&#160;</td><td class="mdescRight">Types of all possible logs <br /></td></tr>
+<tr class="separator:afeef5648c4f78e32623be5fa2b27f37c"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="memItemLeft" align="right" valign="top"><a id="a98b0cc04a019c9d28b7a9bd5737f944d" name="a98b0cc04a019c9d28b7a9bd5737f944d"></a>enum &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LogVerbosity</a> { <b>None</b> = 0
+, <b>Exceptions</b>
+, <b>Full</b>
+ }</td></tr>
+<tr class="memdesc:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="mdescLeft">&#160;</td><td class="mdescRight">Enum specifies the verbosity of the log messages <br /></td></tr>
+<tr class="separator:a98b0cc04a019c9d28b7a9bd5737f944d"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+<h2 class="groupheader">Enumeration Type Documentation</h2>
+<a id="a8a6f0dbee11cb125ee34af8fcc8bc345" name="a8a6f0dbee11cb125ee34af8fcc8bc345"></a>
+<h2 class="memtitle"><span class="permalink"><a href="#a8a6f0dbee11cb125ee34af8fcc8bc345">&#9670;&nbsp;</a></span>LogFlow</h2>
+
+<div class="memitem">
+<div class="memproto">
+      <table class="memname">
+        <tr>
+          <td class="memname">enum <a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers.LogFlow</a></td>
+        </tr>
+      </table>
+</div><div class="memdoc">
+
+<p>This enum specifies all possible types of loggers </p>
+<table class="fieldtable">
+<tr><th colspan="2">Enumerator</th></tr><tr><td class="fieldname"><a id="a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f" name="a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f"></a>Console&#160;</td><td class="fielddoc"><p >Console logger </p>
+</td></tr>
+<tr><td class="fieldname"><a id="a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e" name="a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e"></a>File&#160;</td><td class="fielddoc"><p >Rotating file logger </p>
+</td></tr>
+</table>
+
+</div>
+</div>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="namespace_l_d_client.html">LDClient</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils.html">utils</a></li><li class="navelem"><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html">loggers</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js
new file mode 100644
index 0000000..d3a32a7
--- /dev/null
+++ b/ld_client/doc/pdoc/namespace_l_d_client_1_1utils_1_1loggers.js
@@ -0,0 +1,19 @@
+var namespace_l_d_client_1_1utils_1_1loggers =
+[
+    [ "ALogger", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_a_logger" ],
+    [ "ConsoleLogger", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html", "class_l_d_client_1_1utils_1_1loggers_1_1_console_logger" ],
+    [ "LogFlow", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345", [
+      [ "Console", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f", null ],
+      [ "File", "namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e", null ]
+    ] ],
+    [ "LogType", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c", [
+      [ "Info", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca4059b0251f66a18cb56f544728796875", null ],
+      [ "Debug", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37caa603905470e2a5b8c13e96b579ef0dba", null ],
+      [ "Error", "namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca902b0d55fddef6f8d651fe1035b7d4bd", null ]
+    ] ],
+    [ "LogVerbosity", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d", [
+      [ "None", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944da6adf97f83acf6453d4a6a4b1070f3754", null ],
+      [ "Exceptions", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dad5f1381c5f97f928df4ef8d18c2a27c0", null ],
+      [ "Full", "namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dabbd47109890259c0127154db1af26c75", null ]
+    ] ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/namespacemembers.html b/ld_client/doc/pdoc/namespacemembers.html
new file mode 100644
index 0000000..09b0c35
--- /dev/null
+++ b/ld_client/doc/pdoc/namespacemembers.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Package Members</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespacemembers.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+<div class="textblock">Here is a list of all documented namespace members with links to the namespaces they belong to:</div><ul>
+<li>ConnectionStatus&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data</a></li>
+<li>LogFlow&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers</a></li>
+<li>LogType&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LDClient.utils.loggers</a></li>
+<li>LogVerbosity&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LDClient.utils.loggers</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespacemembers_enum.html b/ld_client/doc/pdoc/namespacemembers_enum.html
new file mode 100644
index 0000000..bfff096
--- /dev/null
+++ b/ld_client/doc/pdoc/namespacemembers_enum.html
@@ -0,0 +1,101 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Package Members</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespacemembers_enum.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="contents">
+&#160;<ul>
+<li>ConnectionStatus&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60">LDClient.network.data</a></li>
+<li>LogFlow&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345">LDClient.utils.loggers</a></li>
+<li>LogType&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c">LDClient.utils.loggers</a></li>
+<li>LogVerbosity&#160;:&#160;<a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d">LDClient.utils.loggers</a></li>
+</ul>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespaces.html b/ld_client/doc/pdoc/namespaces.html
new file mode 100644
index 0000000..9fa0abd
--- /dev/null
+++ b/ld_client/doc/pdoc/namespaces.html
@@ -0,0 +1,123 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: Package List</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('namespaces.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Package List</div></div>
+</div><!--header-->
+<div class="contents">
+<div class="textblock">Here are the packages with brief descriptions (if available):</div><div class="directory">
+<div class="levels">[detail level <span onclick="javascript:toggleLevel(1);">1</span><span onclick="javascript:toggleLevel(2);">2</span><span onclick="javascript:toggleLevel(3);">3</span><span onclick="javascript:toggleLevel(4);">4</span>]</div><table class="directory">
+<tr id="row_0_" class="even"><td class="entry"><span style="width:0px;display:inline-block;">&#160;</span><span id="arr_0_" class="arrow" onclick="toggleFolder('0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client.html" target="_self">LDClient</a></td><td class="desc"></td></tr>
+<tr id="row_0_0_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_0_" class="arrow" onclick="toggleFolder('0_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1detection.html" target="_self">detection</a></td><td class="desc"></td></tr>
+<tr id="row_0_0_0_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" target="_self">IInfoFetcher</a></td><td class="desc">This interface defines the functionality of an info fetcher which takes care of sending commands to the debugger. </td></tr>
+<tr id="row_0_0_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_info_fetcher.html" target="_self">InfoFetcher</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_info_fetcher.html" title="This interface defines the functionality of an info fetcher which takes care of sending commands to t...">IInfoFetcher</a> interface which defines the functionality of an info fetcher. </td></tr>
+<tr id="row_0_0_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" target="_self">IProcessUtils</a></td><td class="desc">This interface defines the functionality of all methods that are used to work with processes (within this project). </td></tr>
+<tr id="row_0_0_3_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_detection.html" target="_self">ProcessDetection</a></td><td class="desc">This class takes care of process detection. When t32mtc (process) is detected, it means that the debugger is currently being used. The class keeps track of the current state of a debugger. </td></tr>
+<tr id="row_0_0_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1detection_1_1_process_utils.html" target="_self">ProcessUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1detection_1_1_i_process_utils.html" title="This interface defines the functionality of all methods that are used to work with processes (within ...">IProcessUtils</a> interface. It implements methods that are used when dealing with processes. </td></tr>
+<tr id="row_0_1_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_1_" class="arrow" onclick="toggleFolder('0_1_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network.html" target="_self">network</a></td><td class="desc"></td></tr>
+<tr id="row_0_1_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_1_0_" class="arrow" onclick="toggleFolder('0_1_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1network_1_1data.html" target="_self">data</a></td><td class="desc"></td></tr>
+<tr id="row_0_1_0_0_"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_debugger_info.html" target="_self">DebuggerInfo</a></td><td class="desc">This class holds all the information about a specific part of a debugger (head/body). </td></tr>
+<tr id="row_0_1_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1data_1_1_payload.html" target="_self">Payload</a></td><td class="desc">This class represents a single payload that is sent to the server. </td></tr>
+<tr id="row_0_1_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_api_client.html" target="_self">ApiClient</a></td><td class="desc">This class implements <a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" title="This interface defines the functionality of an API client which is used to send information (payloads...">IApiClient</a> which is an interface defining all the functionality required from an API client. </td></tr>
+<tr id="row_0_1_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1network_1_1_http_client.html" target="_self">HttpClient</a></td><td class="desc">Implementation of <a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" title="This interface defines the functionality of a HTTP client through which the API client sends data (pa...">IHttpClient</a> which defines the functionality of a HTTP client that is used by the API client to send data to the server. </td></tr>
+<tr id="row_0_1_3_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_api_client.html" target="_self">IApiClient</a></td><td class="desc">This interface defines the functionality of an API client which is used to send information (payloads) to the server. </td></tr>
+<tr id="row_0_1_4_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1network_1_1_i_http_client.html" target="_self">IHttpClient</a></td><td class="desc">This interface defines the functionality of a HTTP client through which the API client sends data (payloads) to the server. </td></tr>
+<tr id="row_0_2_"><td class="entry"><span style="width:16px;display:inline-block;">&#160;</span><span id="arr_0_2_" class="arrow" onclick="toggleFolder('0_2_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils.html" target="_self">utils</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_0_" class="even"><td class="entry"><span style="width:32px;display:inline-block;">&#160;</span><span id="arr_0_2_0_" class="arrow" onclick="toggleFolder('0_2_0_')">&#9660;</span><span class="icona"><span class="icon">N</span></span><a class="el" href="namespace_l_d_client_1_1utils_1_1loggers.html" target="_self">loggers</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_0_0_"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html" target="_self">ALogger</a></td><td class="desc">This class implements all abstract functions of the logger. It contains all functions (error, info, debug) that are present in any other standard logger. Class is used as singleton design pattern </td></tr>
+<tr id="row_0_2_0_1_" class="even"><td class="entry"><span style="width:64px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html" target="_self">ConsoleLogger</a></td><td class="desc"></td></tr>
+<tr id="row_0_2_1_"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="class_l_d_client_1_1utils_1_1_file_utils.html" target="_self">FileUtils</a></td><td class="desc">This class implements the <a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" title="This interface defines IO operations.">IFileUtils</a> interface which defines IO operations. </td></tr>
+<tr id="row_0_2_2_" class="even"><td class="entry"><span style="width:48px;display:inline-block;">&#160;</span><span class="icona"><span class="icon">C</span></span><a class="el" href="interface_l_d_client_1_1utils_1_1_i_file_utils.html" target="_self">IFileUtils</a></td><td class="desc">This interface defines IO operations. </td></tr>
+</table>
+</div><!-- directory -->
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/namespaces_dup.js b/ld_client/doc/pdoc/namespaces_dup.js
new file mode 100644
index 0000000..dc23a9c
--- /dev/null
+++ b/ld_client/doc/pdoc/namespaces_dup.js
@@ -0,0 +1,4 @@
+var namespaces_dup =
+[
+    [ "LDClient", "namespace_l_d_client.html", "namespace_l_d_client" ]
+];
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/nav_f.png b/ld_client/doc/pdoc/nav_f.png
new file mode 100644
index 0000000000000000000000000000000000000000..72a58a529ed3a9ed6aa0c51a79cf207e026deee2
GIT binary patch
literal 153
zcmeAS@N?(olHy`uVBq!ia0vp^j6iI`!2~2XGqLUlQVE_ejv*C{Z|{2ZH7M}7UYxc)
zn!W8uqtnIQ>_<lqdB{jiFDSaaN3W^xbJMH7CDK7=Q3_$6tQ&<~Cp4L6ZEndC`8;cO
zrss?`_g+2sGU&M|cu~La_w1Rnf~7w`e!jQgteDwDLg6kW!`DinT@0SCelF{r5}E+Y
CM>z8U

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/nav_g.png b/ld_client/doc/pdoc/nav_g.png
new file mode 100644
index 0000000000000000000000000000000000000000..2093a237a94f6c83e19ec6e5fd42f7ddabdafa81
GIT binary patch
literal 95
zcmeAS@N?(olHy`uVBq!ia0vp^j6lrB!3HFm1ilyoDK$?Q$B+ufw|5PB85lU25BhtE
tr?otc=hd~V+ws&_A@j8Fiv!K<?EJwDd;c`qumW{3c)I$ztaD0e0syCC7$E=v

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/nav_h.png b/ld_client/doc/pdoc/nav_h.png
new file mode 100644
index 0000000000000000000000000000000000000000..33389b101d9cd9b4c98ad286b5d9c46a6671f650
GIT binary patch
literal 98
zcmeAS@N?(olHy`uVBq!ia0vp^j6lr8!2~3AUOE6t22D>F$B+ufw|5=67#uj90@pIL
wZ=Q8~_Ju`#59=RjDrmm`tMD@M=!-l18IR?&v<Kx}xDV3h>FVdQ&MBb@0HFXL<NyEw

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/navtree.css b/ld_client/doc/pdoc/navtree.css
new file mode 100644
index 0000000..d8a311a
--- /dev/null
+++ b/ld_client/doc/pdoc/navtree.css
@@ -0,0 +1,147 @@
+#nav-tree .children_ul {
+  margin:0;
+  padding:4px;
+}
+
+#nav-tree ul {
+  list-style:none outside none;
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree li {
+  white-space:nowrap;
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree .plus {
+  margin:0px;
+}
+
+#nav-tree .selected {
+  background-image: url('tab_a.png');
+  background-repeat:repeat-x;
+  color: #fff;
+  text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);
+}
+
+#nav-tree img {
+  margin:0px;
+  padding:0px;
+  border:0px;
+  vertical-align: middle;
+}
+
+#nav-tree a {
+  text-decoration:none;
+  padding:0px;
+  margin:0px;
+  outline:none;
+}
+
+#nav-tree .label {
+  margin:0px;
+  padding:0px;
+  font: 12px 'Lucida Grande',Geneva,Helvetica,Arial,sans-serif;
+}
+
+#nav-tree .label a {
+  padding:2px;
+}
+
+#nav-tree .selected a {
+  text-decoration:none;
+  color:#fff;
+}
+
+#nav-tree .children_ul {
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree .item {
+  margin:0px;
+  padding:0px;
+}
+
+#nav-tree {
+  padding: 0px 0px;
+  background-color: #FAFAFF; 
+  font-size:14px;
+  overflow:auto;
+}
+
+#doc-content {
+  overflow:auto;
+  display:block;
+  padding:0px;
+  margin:0px;
+  -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#side-nav {
+  padding:0 6px 0 0;
+  margin: 0px;
+  display:block;
+  position: absolute;
+  left: 0px;
+  width: 250px;
+  overflow : hidden;
+}
+
+.ui-resizable .ui-resizable-handle {
+  display:block;
+}
+
+.ui-resizable-e {
+  background-image:url("splitbar.png");
+  background-size:100%;
+  background-repeat:repeat-y;
+  background-attachment: scroll;
+  cursor:ew-resize;
+  height:100%;
+  right:0;
+  top:0;
+  width:6px;
+}
+
+.ui-resizable-handle {
+  display:none;
+  font-size:0.1px;
+  position:absolute;
+  z-index:1;
+}
+
+#nav-tree-contents {
+  margin: 6px 0px 0px 0px;
+}
+
+#nav-tree {
+  background-image:url('nav_h.png');
+  background-repeat:repeat-x;
+  background-color: #F9FAFC;
+  -webkit-overflow-scrolling : touch; /* iOS 5+ */
+}
+
+#nav-sync {
+  position:absolute;
+  top:5px;
+  right:24px;
+  z-index:0;
+}
+
+#nav-sync img {
+  opacity:0.3;
+}
+
+#nav-sync img:hover {
+  opacity:0.9;
+}
+
+@media print
+{
+  #nav-tree { display: none; }
+  div.ui-resizable-handle { display: none; position: relative; }
+}
+
diff --git a/ld_client/doc/pdoc/navtree.js b/ld_client/doc/pdoc/navtree.js
new file mode 100644
index 0000000..2798368
--- /dev/null
+++ b/ld_client/doc/pdoc/navtree.js
@@ -0,0 +1,549 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+ */
+var navTreeSubIndices = new Array();
+var arrowDown = '&#9660;';
+var arrowRight = '&#9658;';
+
+function getData(varName)
+{
+  var i = varName.lastIndexOf('/');
+  var n = i>=0 ? varName.substring(i+1) : varName;
+  return eval(n.replace(/\-/g,'_'));
+}
+
+function stripPath(uri)
+{
+  return uri.substring(uri.lastIndexOf('/')+1);
+}
+
+function stripPath2(uri)
+{
+  var i = uri.lastIndexOf('/');
+  var s = uri.substring(i+1);
+  var m = uri.substring(0,i+1).match(/\/d\w\/d\w\w\/$/);
+  return m ? uri.substring(i-6) : s;
+}
+
+function hashValue()
+{
+  return $(location).attr('hash').substring(1).replace(/[^\w\-]/g,'');
+}
+
+function hashUrl()
+{
+  return '#'+hashValue();
+}
+
+function pathName()
+{
+  return $(location).attr('pathname').replace(/[^-A-Za-z0-9+&@#/%?=~_|!:,.;\(\)]/g, '');
+}
+
+function localStorageSupported()
+{
+  try {
+    return 'localStorage' in window && window['localStorage'] !== null && window.localStorage.getItem;
+  }
+  catch(e) {
+    return false;
+  }
+}
+
+function storeLink(link)
+{
+  if (!$("#nav-sync").hasClass('sync') && localStorageSupported()) {
+      window.localStorage.setItem('navpath',link);
+  }
+}
+
+function deleteLink()
+{
+  if (localStorageSupported()) {
+    window.localStorage.setItem('navpath','');
+  }
+}
+
+function cachedLink()
+{
+  if (localStorageSupported()) {
+    return window.localStorage.getItem('navpath');
+  } else {
+    return '';
+  }
+}
+
+function getScript(scriptName,func,show)
+{
+  var head = document.getElementsByTagName("head")[0];
+  var script = document.createElement('script');
+  script.id = scriptName;
+  script.type = 'text/javascript';
+  script.onload = func;
+  script.src = scriptName+'.js';
+  head.appendChild(script);
+}
+
+function createIndent(o,domNode,node,level)
+{
+  var level=-1;
+  var n = node;
+  while (n.parentNode) { level++; n=n.parentNode; }
+  if (node.childrenData) {
+    var imgNode = document.createElement("span");
+    imgNode.className = 'arrow';
+    imgNode.style.paddingLeft=(16*level).toString()+'px';
+    imgNode.innerHTML=arrowRight;
+    node.plus_img = imgNode;
+    node.expandToggle = document.createElement("a");
+    node.expandToggle.href = "javascript:void(0)";
+    node.expandToggle.onclick = function() {
+      if (node.expanded) {
+        $(node.getChildrenUL()).slideUp("fast");
+        node.plus_img.innerHTML=arrowRight;
+        node.expanded = false;
+      } else {
+        expandNode(o, node, false, false);
+      }
+    }
+    node.expandToggle.appendChild(imgNode);
+    domNode.appendChild(node.expandToggle);
+  } else {
+    var span = document.createElement("span");
+    span.className = 'arrow';
+    span.style.width   = 16*(level+1)+'px';
+    span.innerHTML = '&#160;';
+    domNode.appendChild(span);
+  }
+}
+
+var animationInProgress = false;
+
+function gotoAnchor(anchor,aname,updateLocation)
+{
+  var pos, docContent = $('#doc-content');
+  var ancParent = $(anchor.parent());
+  if (ancParent.hasClass('memItemLeft') ||
+      ancParent.hasClass('memtitle') ||
+      ancParent.hasClass('fieldname') ||
+      ancParent.hasClass('fieldtype') ||
+      ancParent.is(':header'))
+  {
+    pos = ancParent.position().top;
+  } else if (anchor.position()) {
+    pos = anchor.position().top;
+  }
+  if (pos) {
+    var dist = Math.abs(Math.min(
+               pos-docContent.offset().top,
+               docContent[0].scrollHeight-
+               docContent.height()-docContent.scrollTop()));
+    animationInProgress=true;
+    docContent.animate({
+      scrollTop: pos + docContent.scrollTop() - docContent.offset().top
+    },Math.max(50,Math.min(500,dist)),function(){
+      if (updateLocation) window.location.href=aname;
+      animationInProgress=false;
+    });
+  }
+}
+
+function newNode(o, po, text, link, childrenData, lastNode)
+{
+  var node = new Object();
+  node.children = Array();
+  node.childrenData = childrenData;
+  node.depth = po.depth + 1;
+  node.relpath = po.relpath;
+  node.isLast = lastNode;
+
+  node.li = document.createElement("li");
+  po.getChildrenUL().appendChild(node.li);
+  node.parentNode = po;
+
+  node.itemDiv = document.createElement("div");
+  node.itemDiv.className = "item";
+
+  node.labelSpan = document.createElement("span");
+  node.labelSpan.className = "label";
+
+  createIndent(o,node.itemDiv,node,0);
+  node.itemDiv.appendChild(node.labelSpan);
+  node.li.appendChild(node.itemDiv);
+
+  var a = document.createElement("a");
+  node.labelSpan.appendChild(a);
+  node.label = document.createTextNode(text);
+  node.expanded = false;
+  a.appendChild(node.label);
+  if (link) {
+    var url;
+    if (link.substring(0,1)=='^') {
+      url = link.substring(1);
+      link = url;
+    } else {
+      url = node.relpath+link;
+    }
+    a.className = stripPath(link.replace('#',':'));
+    if (link.indexOf('#')!=-1) {
+      var aname = '#'+link.split('#')[1];
+      var srcPage = stripPath(pathName());
+      var targetPage = stripPath(link.split('#')[0]);
+      a.href = srcPage!=targetPage ? url : "javascript:void(0)";
+      a.onclick = function(){
+        storeLink(link);
+        if (!$(a).parent().parent().hasClass('selected'))
+        {
+          $('.item').removeClass('selected');
+          $('.item').removeAttr('id');
+          $(a).parent().parent().addClass('selected');
+          $(a).parent().parent().attr('id','selected');
+        }
+        var anchor = $(aname);
+        gotoAnchor(anchor,aname,true);
+      };
+    } else {
+      a.href = url;
+      a.onclick = function() { storeLink(link); }
+    }
+  } else {
+    if (childrenData != null)
+    {
+      a.className = "nolink";
+      a.href = "javascript:void(0)";
+      a.onclick = node.expandToggle.onclick;
+    }
+  }
+
+  node.childrenUL = null;
+  node.getChildrenUL = function() {
+    if (!node.childrenUL) {
+      node.childrenUL = document.createElement("ul");
+      node.childrenUL.className = "children_ul";
+      node.childrenUL.style.display = "none";
+      node.li.appendChild(node.childrenUL);
+    }
+    return node.childrenUL;
+  };
+
+  return node;
+}
+
+function showRoot()
+{
+  var headerHeight = $("#top").height();
+  var footerHeight = $("#nav-path").height();
+  var windowHeight = $(window).height() - headerHeight - footerHeight;
+  (function (){ // retry until we can scroll to the selected item
+    try {
+      var navtree=$('#nav-tree');
+      navtree.scrollTo('#selected',100,{offset:-windowHeight/2});
+    } catch (err) {
+      setTimeout(arguments.callee, 0);
+    }
+  })();
+}
+
+function expandNode(o, node, imm, showRoot)
+{
+  if (node.childrenData && !node.expanded) {
+    if (typeof(node.childrenData)==='string') {
+      var varName    = node.childrenData;
+      getScript(node.relpath+varName,function(){
+        node.childrenData = getData(varName);
+        expandNode(o, node, imm, showRoot);
+      }, showRoot);
+    } else {
+      if (!node.childrenVisited) {
+        getNode(o, node);
+      }
+      $(node.getChildrenUL()).slideDown("fast");
+      node.plus_img.innerHTML = arrowDown;
+      node.expanded = true;
+    }
+  }
+}
+
+function glowEffect(n,duration)
+{
+  n.addClass('glow').delay(duration).queue(function(next){
+    $(this).removeClass('glow');next();
+  });
+}
+
+function highlightAnchor()
+{
+  var aname = hashUrl();
+  var anchor = $(aname);
+  if (anchor.parent().attr('class')=='memItemLeft'){
+    var rows = $('.memberdecls tr[class$="'+hashValue()+'"]');
+    glowEffect(rows.children(),300); // member without details
+  } else if (anchor.parent().attr('class')=='fieldname'){
+    glowEffect(anchor.parent().parent(),1000); // enum value
+  } else if (anchor.parent().attr('class')=='fieldtype'){
+    glowEffect(anchor.parent().parent(),1000); // struct field
+  } else if (anchor.parent().is(":header")) {
+    glowEffect(anchor.parent(),1000); // section header
+  } else {
+    glowEffect(anchor.next(),1000); // normal member
+  }
+}
+
+function selectAndHighlight(hash,n)
+{
+  var a;
+  if (hash) {
+    var link=stripPath(pathName())+':'+hash.substring(1);
+    a=$('.item a[class$="'+link+'"]');
+  }
+  if (a && a.length) {
+    a.parent().parent().addClass('selected');
+    a.parent().parent().attr('id','selected');
+    highlightAnchor();
+  } else if (n) {
+    $(n.itemDiv).addClass('selected');
+    $(n.itemDiv).attr('id','selected');
+  }
+  var topOffset=5;
+  if (typeof page_layout!=='undefined' && page_layout==1) {
+    topOffset+=$('#top').outerHeight();
+  }
+  if ($('#nav-tree-contents .item:first').hasClass('selected')) {
+    topOffset+=25;
+  }
+  $('#nav-sync').css('top',topOffset+'px');
+  showRoot();
+}
+
+function showNode(o, node, index, hash)
+{
+  if (node && node.childrenData) {
+    if (typeof(node.childrenData)==='string') {
+      var varName    = node.childrenData;
+      getScript(node.relpath+varName,function(){
+        node.childrenData = getData(varName);
+        showNode(o,node,index,hash);
+      },true);
+    } else {
+      if (!node.childrenVisited) {
+        getNode(o, node);
+      }
+      $(node.getChildrenUL()).css({'display':'block'});
+      node.plus_img.innerHTML = arrowDown;
+      node.expanded = true;
+      var n = node.children[o.breadcrumbs[index]];
+      if (index+1<o.breadcrumbs.length) {
+        showNode(o,n,index+1,hash);
+      } else {
+        if (typeof(n.childrenData)==='string') {
+          var varName = n.childrenData;
+          getScript(n.relpath+varName,function(){
+            n.childrenData = getData(varName);
+            node.expanded=false;
+            showNode(o,node,index,hash); // retry with child node expanded
+          },true);
+        } else {
+          var rootBase = stripPath(o.toroot.replace(/\..+$/, ''));
+          if (rootBase=="index" || rootBase=="pages" || rootBase=="search") {
+            expandNode(o, n, true, true);
+          }
+          selectAndHighlight(hash,n);
+        }
+      }
+    }
+  } else {
+    selectAndHighlight(hash);
+  }
+}
+
+function removeToInsertLater(element) {
+  var parentNode = element.parentNode;
+  var nextSibling = element.nextSibling;
+  parentNode.removeChild(element);
+  return function() {
+    if (nextSibling) {
+      parentNode.insertBefore(element, nextSibling);
+    } else {
+      parentNode.appendChild(element);
+    }
+  };
+}
+
+function getNode(o, po)
+{
+  var insertFunction = removeToInsertLater(po.li);
+  po.childrenVisited = true;
+  var l = po.childrenData.length-1;
+  for (var i in po.childrenData) {
+    var nodeData = po.childrenData[i];
+    po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2],
+      i==l);
+  }
+  insertFunction();
+}
+
+function gotoNode(o,subIndex,root,hash,relpath)
+{
+  var nti = navTreeSubIndices[subIndex][root+hash];
+  o.breadcrumbs = $.extend(true, [], nti ? nti : navTreeSubIndices[subIndex][root]);
+  if (!o.breadcrumbs && root!=NAVTREE[0][1]) { // fallback: show index
+    navTo(o,NAVTREE[0][1],"",relpath);
+    $('.item').removeClass('selected');
+    $('.item').removeAttr('id');
+  }
+  if (o.breadcrumbs) {
+    o.breadcrumbs.unshift(0); // add 0 for root node
+    showNode(o, o.node, 0, hash);
+  }
+}
+
+function navTo(o,root,hash,relpath)
+{
+  var link = cachedLink();
+  if (link) {
+    var parts = link.split('#');
+    root = parts[0];
+    if (parts.length>1) hash = '#'+parts[1].replace(/[^\w\-]/g,'');
+    else hash='';
+  }
+  if (hash.match(/^#l\d+$/)) {
+    var anchor=$('a[name='+hash.substring(1)+']');
+    glowEffect(anchor.parent(),1000); // line number
+    hash=''; // strip line number anchors
+  }
+  var url=root+hash;
+  var i=-1;
+  while (NAVTREEINDEX[i+1]<=url) i++;
+  if (i==-1) { i=0; root=NAVTREE[0][1]; } // fallback: show index
+  if (navTreeSubIndices[i]) {
+    gotoNode(o,i,root,hash,relpath)
+  } else {
+    getScript(relpath+'navtreeindex'+i,function(){
+      navTreeSubIndices[i] = eval('NAVTREEINDEX'+i);
+      if (navTreeSubIndices[i]) {
+        gotoNode(o,i,root,hash,relpath);
+      }
+    },true);
+  }
+}
+
+function showSyncOff(n,relpath)
+{
+    n.html('<img src="'+relpath+'sync_off.png" title="'+SYNCOFFMSG+'"/>');
+}
+
+function showSyncOn(n,relpath)
+{
+    n.html('<img src="'+relpath+'sync_on.png" title="'+SYNCONMSG+'"/>');
+}
+
+function toggleSyncButton(relpath)
+{
+  var navSync = $('#nav-sync');
+  if (navSync.hasClass('sync')) {
+    navSync.removeClass('sync');
+    showSyncOff(navSync,relpath);
+    storeLink(stripPath2(pathName())+hashUrl());
+  } else {
+    navSync.addClass('sync');
+    showSyncOn(navSync,relpath);
+    deleteLink();
+  }
+}
+
+var loadTriggered = false;
+var readyTriggered = false;
+var loadObject,loadToRoot,loadUrl,loadRelPath;
+
+$(window).on('load',function(){
+  if (readyTriggered) { // ready first
+    navTo(loadObject,loadToRoot,loadUrl,loadRelPath);
+    showRoot();
+  }
+  loadTriggered=true;
+});
+
+function initNavTree(toroot,relpath)
+{
+  var o = new Object();
+  o.toroot = toroot;
+  o.node = new Object();
+  o.node.li = document.getElementById("nav-tree-contents");
+  o.node.childrenData = NAVTREE;
+  o.node.children = new Array();
+  o.node.childrenUL = document.createElement("ul");
+  o.node.getChildrenUL = function() { return o.node.childrenUL; };
+  o.node.li.appendChild(o.node.childrenUL);
+  o.node.depth = 0;
+  o.node.relpath = relpath;
+  o.node.expanded = false;
+  o.node.isLast = true;
+  o.node.plus_img = document.createElement("span");
+  o.node.plus_img.className = 'arrow';
+  o.node.plus_img.innerHTML = arrowRight;
+
+  if (localStorageSupported()) {
+    var navSync = $('#nav-sync');
+    if (cachedLink()) {
+      showSyncOff(navSync,relpath);
+      navSync.removeClass('sync');
+    } else {
+      showSyncOn(navSync,relpath);
+    }
+    navSync.click(function(){ toggleSyncButton(relpath); });
+  }
+
+  if (loadTriggered) { // load before ready
+    navTo(o,toroot,hashUrl(),relpath);
+    showRoot();
+  } else { // ready before load
+    loadObject  = o;
+    loadToRoot  = toroot;
+    loadUrl     = hashUrl();
+    loadRelPath = relpath;
+    readyTriggered=true;
+  }
+
+  $(window).bind('hashchange', function(){
+     if (window.location.hash && window.location.hash.length>1){
+       var a;
+       if ($(location).attr('hash')){
+         var clslink=stripPath(pathName())+':'+hashValue();
+         a=$('.item a[class$="'+clslink.replace(/</g,'\\3c ')+'"]');
+       }
+       if (a==null || !$(a).parent().parent().hasClass('selected')){
+         $('.item').removeClass('selected');
+         $('.item').removeAttr('id');
+       }
+       var link=stripPath2(pathName());
+       navTo(o,link,hashUrl(),relpath);
+     } else if (!animationInProgress) {
+       $('#doc-content').scrollTop(0);
+       $('.item').removeClass('selected');
+       $('.item').removeAttr('id');
+       navTo(o,toroot,hashUrl(),relpath);
+     }
+  })
+}
+/* @license-end */
diff --git a/ld_client/doc/pdoc/navtreedata.js b/ld_client/doc/pdoc/navtreedata.js
new file mode 100644
index 0000000..16cc445
--- /dev/null
+++ b/ld_client/doc/pdoc/navtreedata.js
@@ -0,0 +1,55 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+*/
+var NAVTREE =
+[
+  [ "LDClient", "index.html", [
+    [ "Packages", "namespaces.html", [
+      [ "Package List", "namespaces.html", "namespaces_dup" ],
+      [ "Package Members", "namespacemembers.html", [
+        [ "All", "namespacemembers.html", null ],
+        [ "Enumerations", "namespacemembers_enum.html", null ]
+      ] ]
+    ] ],
+    [ "Classes", "annotated.html", [
+      [ "Class List", "annotated.html", "annotated_dup" ],
+      [ "Class Index", "classes.html", null ],
+      [ "Class Hierarchy", "hierarchy.html", "hierarchy" ],
+      [ "Class Members", "functions.html", [
+        [ "All", "functions.html", null ],
+        [ "Functions", "functions_func.html", null ],
+        [ "Variables", "functions_vars.html", null ],
+        [ "Properties", "functions_prop.html", null ]
+      ] ]
+    ] ]
+  ] ]
+];
+
+var NAVTREEINDEX =
+[
+"annotated.html"
+];
+
+var SYNCONMSG = 'click to disable panel synchronisation';
+var SYNCOFFMSG = 'click to enable panel synchronisation';
\ No newline at end of file
diff --git a/ld_client/doc/pdoc/navtreeindex0.js b/ld_client/doc/pdoc/navtreeindex0.js
new file mode 100644
index 0000000..b8626c9
--- /dev/null
+++ b/ld_client/doc/pdoc/navtreeindex0.js
@@ -0,0 +1,163 @@
+var NAVTREEINDEX0 =
+{
+"annotated.html":[1,0],
+"class_file_logger.html":[1,0,1],
+"class_file_logger.html#ad39844b2267623f858ab77e6f5433896":[1,0,1,0],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html":[0,0,0,0,1],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html":[1,0,0,0,1],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f":[0,0,0,0,1,5],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f":[1,0,0,0,1,5],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c":[1,0,0,0,1,1],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c":[0,0,0,0,1,1],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8":[0,0,0,0,1,3],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8":[1,0,0,0,1,3],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26":[1,0,0,0,1,0],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26":[0,0,0,0,1,0],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140":[1,0,0,0,1,2],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140":[0,0,0,0,1,2],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d":[1,0,0,0,1,4],
+"class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d":[0,0,0,0,1,4],
+"class_l_d_client_1_1detection_1_1_process_detection.html":[0,0,0,0,3],
+"class_l_d_client_1_1detection_1_1_process_detection.html":[1,0,0,0,3],
+"class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679":[0,0,0,0,3,0],
+"class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679":[1,0,0,0,3,0],
+"class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6":[0,0,0,0,3,2],
+"class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6":[1,0,0,0,3,2],
+"class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8":[0,0,0,0,3,1],
+"class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8":[1,0,0,0,3,1],
+"class_l_d_client_1_1detection_1_1_process_utils.html":[0,0,0,0,4],
+"class_l_d_client_1_1detection_1_1_process_utils.html":[1,0,0,0,4],
+"class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4":[0,0,0,0,4,1],
+"class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4":[1,0,0,0,4,1],
+"class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557":[1,0,0,0,4,0],
+"class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557":[0,0,0,0,4,0],
+"class_l_d_client_1_1network_1_1_api_client.html":[1,0,0,1,1],
+"class_l_d_client_1_1network_1_1_api_client.html":[0,0,0,1,1],
+"class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d":[1,0,0,1,1,3],
+"class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d":[0,0,0,1,1,3],
+"class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1":[1,0,0,1,1,4],
+"class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1":[0,0,0,1,1,4],
+"class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55":[1,0,0,1,1,2],
+"class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55":[0,0,0,1,1,2],
+"class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73":[1,0,0,1,1,0],
+"class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73":[0,0,0,1,1,0],
+"class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979":[1,0,0,1,1,1],
+"class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979":[0,0,0,1,1,1],
+"class_l_d_client_1_1network_1_1_http_client.html":[1,0,0,1,2],
+"class_l_d_client_1_1network_1_1_http_client.html":[0,0,0,1,2],
+"class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d":[1,0,0,1,2,1],
+"class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d":[0,0,0,1,2,1],
+"class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3":[0,0,0,1,2,0],
+"class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3":[1,0,0,1,2,0],
+"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html":[1,0,0,1,0,0],
+"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html":[0,0,0,1,0,0],
+"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb":[1,0,0,1,0,0,0],
+"class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb":[0,0,0,1,0,0,0],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html":[0,0,0,1,0,1],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html":[1,0,0,1,0,1],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481":[1,0,0,1,0,1,5],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481":[0,0,0,1,0,1,5],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208":[1,0,0,1,0,1,2],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208":[0,0,0,1,0,1,2],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65":[1,0,0,1,0,1,7],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65":[0,0,0,1,0,1,7],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72":[1,0,0,1,0,1,4],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72":[0,0,0,1,0,1,4],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57":[0,0,0,1,0,1,0],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57":[1,0,0,1,0,1,0],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297":[1,0,0,1,0,1,6],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297":[0,0,0,1,0,1,6],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148":[1,0,0,1,0,1,1],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148":[0,0,0,1,0,1,1],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5":[1,0,0,1,0,1,3],
+"class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5":[0,0,0,1,0,1,3],
+"class_l_d_client_1_1utils_1_1_file_utils.html":[0,0,0,2,1],
+"class_l_d_client_1_1utils_1_1_file_utils.html":[1,0,0,2,1],
+"class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737":[0,0,0,2,1,0],
+"class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737":[1,0,0,2,1,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html":[0,0,0,2,0,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html":[1,0,0,2,0,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b":[0,0,0,2,0,0,1],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b":[1,0,0,2,0,0,1],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453":[0,0,0,2,0,0,8],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453":[1,0,0,2,0,0,8],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3":[0,0,0,2,0,0,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3":[1,0,0,2,0,0,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81":[0,0,0,2,0,0,2],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81":[1,0,0,2,0,0,2],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433":[0,0,0,2,0,0,3],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433":[1,0,0,2,0,0,3],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea":[0,0,0,2,0,0,9],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea":[1,0,0,2,0,0,9],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504":[1,0,0,2,0,0,5],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504":[0,0,0,2,0,0,5],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2":[1,0,0,2,0,0,4],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2":[0,0,0,2,0,0,4],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4":[1,0,0,2,0,0,6],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4":[0,0,0,2,0,0,6],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e":[0,0,0,2,0,0,7],
+"class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e":[1,0,0,2,0,0,7],
+"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html":[0,0,0,2,0,1],
+"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html":[1,0,0,2,0,1],
+"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7":[0,0,0,2,0,1,0],
+"class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7":[1,0,0,2,0,1,0],
+"classes.html":[1,1],
+"functions.html":[1,3,0],
+"functions_func.html":[1,3,1],
+"functions_prop.html":[1,3,3],
+"functions_vars.html":[1,3,2],
+"hierarchy.html":[1,2],
+"index.html":[],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html":[0,0,0,0,0],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html":[1,0,0,0,0],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9":[1,0,0,0,0,0],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9":[0,0,0,0,0,0],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0":[1,0,0,0,0,2],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0":[0,0,0,0,0,2],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9":[1,0,0,0,0,1],
+"interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9":[0,0,0,0,0,1],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html":[1,0,0,0,2],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html":[0,0,0,0,2],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662":[0,0,0,0,2,0],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662":[1,0,0,0,2,0],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0":[0,0,0,0,2,1],
+"interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0":[1,0,0,0,2,1],
+"interface_l_d_client_1_1network_1_1_i_api_client.html":[1,0,0,1,3],
+"interface_l_d_client_1_1network_1_1_i_api_client.html":[0,0,0,1,3],
+"interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f":[1,0,0,1,3,1],
+"interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f":[0,0,0,1,3,1],
+"interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb":[0,0,0,1,3,0],
+"interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb":[1,0,0,1,3,0],
+"interface_l_d_client_1_1network_1_1_i_http_client.html":[1,0,0,1,4],
+"interface_l_d_client_1_1network_1_1_i_http_client.html":[0,0,0,1,4],
+"interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f":[1,0,0,1,4,0],
+"interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f":[0,0,0,1,4,0],
+"interface_l_d_client_1_1utils_1_1_i_file_utils.html":[0,0,0,2,2],
+"interface_l_d_client_1_1utils_1_1_i_file_utils.html":[1,0,0,2,2],
+"interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3":[0,0,0,2,2,0],
+"interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3":[1,0,0,2,2,0],
+"namespace_l_d_client.html":[0,0,0],
+"namespace_l_d_client_1_1detection.html":[0,0,0,0],
+"namespace_l_d_client_1_1network.html":[0,0,0,1],
+"namespace_l_d_client_1_1network_1_1data.html":[0,0,0,1,0],
+"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60":[0,0,0,1,0,2],
+"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7":[0,0,0,1,0,2,0],
+"namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0":[0,0,0,1,0,2,1],
+"namespace_l_d_client_1_1utils.html":[0,0,0,2],
+"namespace_l_d_client_1_1utils_1_1loggers.html":[0,0,0,2,0],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345":[0,0,0,2,0,2],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e":[0,0,0,2,0,2,1],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f":[0,0,0,2,0,2,0],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d":[0,0,0,2,0,4],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944da6adf97f83acf6453d4a6a4b1070f3754":[0,0,0,2,0,4,0],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dabbd47109890259c0127154db1af26c75":[0,0,0,2,0,4,2],
+"namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944dad5f1381c5f97f928df4ef8d18c2a27c0":[0,0,0,2,0,4,1],
+"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c":[0,0,0,2,0,3],
+"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca4059b0251f66a18cb56f544728796875":[0,0,0,2,0,3,0],
+"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37ca902b0d55fddef6f8d651fe1035b7d4bd":[0,0,0,2,0,3,2],
+"namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37caa603905470e2a5b8c13e96b579ef0dba":[0,0,0,2,0,3,1],
+"namespacemembers.html":[0,1,0],
+"namespacemembers_enum.html":[0,1,1],
+"namespaces.html":[0,0],
+"pages.html":[]
+};
diff --git a/ld_client/doc/pdoc/open.png b/ld_client/doc/pdoc/open.png
new file mode 100644
index 0000000000000000000000000000000000000000..30f75c7efe2dd0c9e956e35b69777a02751f048b
GIT binary patch
literal 123
zcmeAS@N?(olHy`uVBq!ia0vp^oFL4>1|%O$WD@{VPM$7~Ar*{o?;hlAFyLXmaDC0y
znK1_#cQqJWPES%4Uujug^TE?jMft$}Eq^WaR~)%f)vSNs&gek&x%A9X9sM<Rdl=8h
W@EqZ{ytxBt8iS{+pUXO@geCxcDJg#d

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/resize.js b/ld_client/doc/pdoc/resize.js
new file mode 100644
index 0000000..7fe30d1
--- /dev/null
+++ b/ld_client/doc/pdoc/resize.js
@@ -0,0 +1,150 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+ */
+function initResizable()
+{
+  var cookie_namespace = 'doxygen';
+  var sidenav,navtree,content,header,collapsed,collapsedWidth=0,barWidth=6,desktop_vp=768,titleHeight;
+
+  function readCookie(cookie)
+  {
+    var myCookie = cookie_namespace+"_"+cookie+"=";
+    if (document.cookie) {
+      var index = document.cookie.indexOf(myCookie);
+      if (index != -1) {
+        var valStart = index + myCookie.length;
+        var valEnd = document.cookie.indexOf(";", valStart);
+        if (valEnd == -1) {
+          valEnd = document.cookie.length;
+        }
+        var val = document.cookie.substring(valStart, valEnd);
+        return val;
+      }
+    }
+    return 0;
+  }
+
+  function writeCookie(cookie, val, expiration)
+  {
+    if (val==undefined) return;
+    if (expiration == null) {
+      var date = new Date();
+      date.setTime(date.getTime()+(10*365*24*60*60*1000)); // default expiration is one week
+      expiration = date.toGMTString();
+    }
+    document.cookie = cookie_namespace + "_" + cookie + "=" + val + "; SameSite=Lax; expires=" + expiration+"; path=/";
+  }
+
+  function resizeWidth()
+  {
+    var windowWidth = $(window).width() + "px";
+    var sidenavWidth = $(sidenav).outerWidth();
+    content.css({marginLeft:parseInt(sidenavWidth)+"px"});
+    writeCookie('width',sidenavWidth-barWidth, null);
+  }
+
+  function restoreWidth(navWidth)
+  {
+    var windowWidth = $(window).width() + "px";
+    content.css({marginLeft:parseInt(navWidth)+barWidth+"px"});
+    sidenav.css({width:navWidth + "px"});
+  }
+
+  function resizeHeight()
+  {
+    var headerHeight = header.outerHeight();
+    var footerHeight = footer.outerHeight();
+    var windowHeight = $(window).height();
+    var contentHeight,navtreeHeight,sideNavHeight;
+    if (typeof page_layout==='undefined' || page_layout==0) { /* DISABLE_INDEX=NO */
+      contentHeight = windowHeight - headerHeight - footerHeight;
+      navtreeHeight = contentHeight;
+      sideNavHeight = contentHeight;
+    } else if (page_layout==1) { /* DISABLE_INDEX=YES */
+      contentHeight = windowHeight - footerHeight;
+      navtreeHeight = windowHeight - headerHeight;
+      sideNavHeight = windowHeight;
+    }
+    content.css({height:contentHeight + "px"});
+    navtree.css({height:navtreeHeight + "px"});
+    sidenav.css({height:sideNavHeight + "px"});
+    var width=$(window).width();
+    if (width!=collapsedWidth) {
+      if (width<desktop_vp && collapsedWidth>=desktop_vp) {
+        if (!collapsed) {
+          collapseExpand();
+        }
+      } else if (width>desktop_vp && collapsedWidth<desktop_vp) {
+        if (collapsed) {
+          collapseExpand();
+        }
+      }
+      collapsedWidth=width;
+    }
+    if (location.hash.slice(1)) {
+      (document.getElementById(location.hash.slice(1))||document.body).scrollIntoView();
+    }
+  }
+
+  function collapseExpand()
+  {
+    if (sidenav.width()>0) {
+      restoreWidth(0);
+      collapsed=true;
+    }
+    else {
+      var width = readCookie('width');
+      if (width>200 && width<$(window).width()) { restoreWidth(width); } else { restoreWidth(200); }
+      collapsed=false;
+    }
+  }
+
+  header  = $("#top");
+  sidenav = $("#side-nav");
+  content = $("#doc-content");
+  navtree = $("#nav-tree");
+  footer  = $("#nav-path");
+  $(".side-nav-resizable").resizable({resize: function(e, ui) { resizeWidth(); } });
+  $(sidenav).resizable({ minWidth: 0 });
+  $(window).resize(function() { resizeHeight(); });
+  var device = navigator.userAgent.toLowerCase();
+  var touch_device = device.match(/(iphone|ipod|ipad|android)/);
+  if (touch_device) { /* wider split bar for touch only devices */
+    $(sidenav).css({ paddingRight:'20px' });
+    $('.ui-resizable-e').css({ width:'20px' });
+    $('#nav-sync').css({ right:'34px' });
+    barWidth=20;
+  }
+  var width = readCookie('width');
+  if (width) { restoreWidth(width); } else { resizeWidth(); }
+  resizeHeight();
+  var url = location.href;
+  var i=url.indexOf("#");
+  if (i>=0) window.location.hash=url.substr(i);
+  var _preventDefault = function(evt) { evt.preventDefault(); };
+  $("#splitbar").bind("dragstart", _preventDefault).bind("selectstart", _preventDefault);
+  $(".ui-resizable-handle").dblclick(collapseExpand);
+  $(window).on('load',resizeHeight);
+}
+/* @license-end */
diff --git a/ld_client/doc/pdoc/search/all_0.html b/ld_client/doc/pdoc/search/all_0.html
new file mode 100644
index 0000000..bb9e364
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_0.js b/ld_client/doc/pdoc/search/all_0.js
new file mode 100644
index 0000000..3d59743
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_0.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['_5fclient_0',['_client',['../class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d',1,'LDClient::network::ApiClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_1.html b/ld_client/doc/pdoc/search/all_1.html
new file mode 100644
index 0000000..8989416
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_1.js b/ld_client/doc/pdoc/search/all_1.js
new file mode 100644
index 0000000..bd62760
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_1.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3',1,'LDClient.utils.loggers.ALogger.ALogger()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',1,'LDClient.utils.loggers.ALogger']]],
+  ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73',1,'LDClient.network.ApiClient.ApiClient()'],['../class_l_d_client_1_1network_1_1_api_client.html',1,'LDClient.network.ApiClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_2.html b/ld_client/doc/pdoc/search/all_2.html
new file mode 100644
index 0000000..98e648c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_2.js b/ld_client/doc/pdoc/search/all_2.js
new file mode 100644
index 0000000..4ff2bab
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_2.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['bodydevice_0',['BodyDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208',1,'LDClient::network::data::Payload']]],
+  ['bodyserialnumber_1',['BodySerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9',1,'LDClient.detection.IInfoFetcher.BodySerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d',1,'LDClient.detection.InfoFetcher.BodySerialNumber()']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_3.html b/ld_client/doc/pdoc/search/all_3.html
new file mode 100644
index 0000000..f4e8da7
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_3.js b/ld_client/doc/pdoc/search/all_3.js
new file mode 100644
index 0000000..fd4c764
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_3.js
@@ -0,0 +1,11 @@
+var searchData=
+[
+  ['clientrunning_0',['ClientRunning',['../class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1',1,'LDClient::network::ApiClient']]],
+  ['composelogrow_1',['ComposeLogRow',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b',1,'LDClient::utils::loggers::ALogger']]],
+  ['connected_2',['Connected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7',1,'LDClient::network::data']]],
+  ['connectionstatus_3',['ConnectionStatus',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60',1,'LDClient::network::data']]],
+  ['console_4',['Console',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f',1,'LDClient::utils::loggers']]],
+  ['consolelogger_5',['ConsoleLogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',1,'LDClient::utils::loggers']]],
+  ['createlog_6',['CreateLog',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7',1,'LDClient.utils.loggers.ConsoleLogger.CreateLog()'],['../class_file_logger.html#ad39844b2267623f858ab77e6f5433896',1,'FileLogger.CreateLog()']]],
+  ['current_7',['Current',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_4.html b/ld_client/doc/pdoc/search/all_4.html
new file mode 100644
index 0000000..678d3a2
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_4.js b/ld_client/doc/pdoc/search/all_4.js
new file mode 100644
index 0000000..626ce5a
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_4.js
@@ -0,0 +1,8 @@
+var searchData=
+[
+  ['debug_0',['Debug',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81',1,'LDClient::utils::loggers::ALogger']]],
+  ['debuggerinfo_1',['DebuggerInfo',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',1,'LDClient::network::data']]],
+  ['detectionrunning_2',['DetectionRunning',['../class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6',1,'LDClient::detection::ProcessDetection']]],
+  ['disconnected_3',['Disconnected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0',1,'LDClient::network::data']]],
+  ['dispose_4',['Dispose',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_5.html b/ld_client/doc/pdoc/search/all_5.html
new file mode 100644
index 0000000..aa9af78
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_5.js b/ld_client/doc/pdoc/search/all_5.js
new file mode 100644
index 0000000..018d2dc
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_5.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['error_0',['Error',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504',1,'LDClient.utils.loggers.ALogger.Error(string message)'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2',1,'LDClient.utils.loggers.ALogger.Error(Exception e)']]],
+  ['executenewprocess_1',['ExecuteNewProcess',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662',1,'LDClient.detection.IProcessUtils.ExecuteNewProcess()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557',1,'LDClient.detection.ProcessUtils.ExecuteNewProcess()']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_6.html b/ld_client/doc/pdoc/search/all_6.html
new file mode 100644
index 0000000..d3026a7
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_6.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_6.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_6.js b/ld_client/doc/pdoc/search/all_6.js
new file mode 100644
index 0000000..c4d01bd
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_6.js
@@ -0,0 +1,8 @@
+var searchData=
+[
+  ['fetchdataasync_0',['FetchDataAsync',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9',1,'LDClient.detection.IInfoFetcher.FetchDataAsync()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c',1,'LDClient.detection.InfoFetcher.FetchDataAsync()']]],
+  ['file_1',['File',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e',1,'LDClient::utils::loggers']]],
+  ['filelogger_2',['FileLogger',['../class_file_logger.html',1,'']]],
+  ['fileutils_3',['FileUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140',1,'LDClient.detection.InfoFetcher.FileUtils()'],['../class_l_d_client_1_1utils_1_1_file_utils.html',1,'LDClient.utils.FileUtils']]],
+  ['flush_4',['Flush',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_7.html b/ld_client/doc/pdoc/search/all_7.html
new file mode 100644
index 0000000..b2ee042
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_7.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_7.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_7.js b/ld_client/doc/pdoc/search/all_7.js
new file mode 100644
index 0000000..59c5ac4
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_7.js
@@ -0,0 +1,7 @@
+var searchData=
+[
+  ['headdevice_0',['HeadDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5',1,'LDClient::network::data::Payload']]],
+  ['headserialnumber_1',['HeadSerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0',1,'LDClient.detection.IInfoFetcher.HeadSerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f',1,'LDClient.detection.InfoFetcher.HeadSerialNumber()']]],
+  ['hostname_2',['HostName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72',1,'LDClient::network::data::Payload']]],
+  ['httpclient_3',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3',1,'LDClient.network.HttpClient.HttpClient()'],['../class_l_d_client_1_1network_1_1_http_client.html',1,'LDClient.network.HttpClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_8.html b/ld_client/doc/pdoc/search/all_8.html
new file mode 100644
index 0000000..40a0b3f
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_8.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_8.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_8.js b/ld_client/doc/pdoc/search/all_8.js
new file mode 100644
index 0000000..0752101
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_8.js
@@ -0,0 +1,11 @@
+var searchData=
+[
+  ['iapiclient_0',['IApiClient',['../interface_l_d_client_1_1network_1_1_i_api_client.html',1,'LDClient::network']]],
+  ['ifileutils_1',['IFileUtils',['../interface_l_d_client_1_1utils_1_1_i_file_utils.html',1,'LDClient::utils']]],
+  ['ihttpclient_2',['IHttpClient',['../interface_l_d_client_1_1network_1_1_i_http_client.html',1,'LDClient::network']]],
+  ['iinfofetcher_3',['IInfoFetcher',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',1,'LDClient::detection']]],
+  ['info_4',['Info',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e',1,'LDClient::utils::loggers::ALogger']]],
+  ['infofetcher_5',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26',1,'LDClient.detection.InfoFetcher.InfoFetcher()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html',1,'LDClient.detection.InfoFetcher']]],
+  ['iprocessutils_6',['IProcessUtils',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html',1,'LDClient::detection']]],
+  ['isprocessrunning_7',['IsProcessRunning',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0',1,'LDClient.detection.IProcessUtils.IsProcessRunning()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4',1,'LDClient.detection.ProcessUtils.IsProcessRunning()']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_9.html b/ld_client/doc/pdoc/search/all_9.html
new file mode 100644
index 0000000..7c49144
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_9.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_9.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_9.js b/ld_client/doc/pdoc/search/all_9.js
new file mode 100644
index 0000000..5f15c1c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_9.js
@@ -0,0 +1,12 @@
+var searchData=
+[
+  ['data_0',['data',['../namespace_l_d_client_1_1network_1_1data.html',1,'LDClient::network']]],
+  ['detection_1',['detection',['../namespace_l_d_client_1_1detection.html',1,'LDClient']]],
+  ['ldclient_2',['LDClient',['../namespace_l_d_client.html',1,'']]],
+  ['logflow_3',['LogFlow',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345',1,'LDClient::utils::loggers']]],
+  ['loggers_4',['loggers',['../namespace_l_d_client_1_1utils_1_1loggers.html',1,'LDClient::utils']]],
+  ['logtype_5',['LogType',['../namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c',1,'LDClient::utils::loggers']]],
+  ['logverbosity_6',['LogVerbosity',['../namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d',1,'LDClient::utils::loggers']]],
+  ['network_7',['network',['../namespace_l_d_client_1_1network.html',1,'LDClient']]],
+  ['utils_8',['utils',['../namespace_l_d_client_1_1utils.html',1,'LDClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_a.html b/ld_client/doc/pdoc/search/all_a.html
new file mode 100644
index 0000000..fc9d79c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_a.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_a.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_a.js b/ld_client/doc/pdoc/search/all_a.js
new file mode 100644
index 0000000..1fe257c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_a.js
@@ -0,0 +1,8 @@
+var searchData=
+[
+  ['parsetojson_0',['ParseToJson',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57',1,'LDClient.network.data.Payload.ParseToJson()'],['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056',1,'LDClient.network.data.Payload.ParseToJson(Payload payload)']]],
+  ['payload_1',['Payload',['../class_l_d_client_1_1network_1_1data_1_1_payload.html',1,'LDClient::network::data']]],
+  ['postasjsonasync_2',['PostAsJsonAsync',['../class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d',1,'LDClient.network.HttpClient.PostAsJsonAsync()'],['../interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f',1,'LDClient.network.IHttpClient.PostAsJsonAsync()']]],
+  ['processdetection_3',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html',1,'LDClient.detection.ProcessDetection'],['../class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679',1,'LDClient.detection.ProcessDetection.ProcessDetection()']]],
+  ['processutils_4',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_process_utils.html',1,'LDClient.detection.ProcessUtils'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8',1,'LDClient.detection.InfoFetcher.ProcessUtils()']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_b.html b/ld_client/doc/pdoc/search/all_b.html
new file mode 100644
index 0000000..dafb1fa
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_b.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_b.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_b.js b/ld_client/doc/pdoc/search/all_b.js
new file mode 100644
index 0000000..fc6db8c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_b.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['readfilealllines_0',['ReadFileAllLines',['../class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737',1,'LDClient.utils.FileUtils.ReadFileAllLines()'],['../interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3',1,'LDClient.utils.IFileUtils.ReadFileAllLines()']]],
+  ['run_1',['Run',['../class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979',1,'LDClient.network.ApiClient.Run()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb',1,'LDClient.network.IApiClient.Run()']]],
+  ['runperiodicdetection_2',['RunPeriodicDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8',1,'LDClient::detection::ProcessDetection']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_c.html b/ld_client/doc/pdoc/search/all_c.html
new file mode 100644
index 0000000..9df619d
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_c.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_c.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_c.js b/ld_client/doc/pdoc/search/all_c.js
new file mode 100644
index 0000000..0787247
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_c.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['sendpayloadasync_0',['SendPayloadAsync',['../class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55',1,'LDClient.network.ApiClient.SendPayloadAsync()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f',1,'LDClient.network.IApiClient.SendPayloadAsync()']]],
+  ['serialnumber_1',['SerialNumber',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb',1,'LDClient::network::data::DebuggerInfo']]],
+  ['status_2',['Status',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_d.html b/ld_client/doc/pdoc/search/all_d.html
new file mode 100644
index 0000000..95d8eec
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_d.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_d.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_d.js b/ld_client/doc/pdoc/search/all_d.js
new file mode 100644
index 0000000..2d8b980
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_d.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['timestamp_0',['TimeStamp',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297',1,'LDClient::network::data::Payload']]],
+  ['tostring_1',['ToString',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148',1,'LDClient.network.data.Payload.ToString()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453',1,'LDClient.utils.loggers.ALogger.ToString()']]]
+];
diff --git a/ld_client/doc/pdoc/search/all_e.html b/ld_client/doc/pdoc/search/all_e.html
new file mode 100644
index 0000000..a54e120
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_e.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="all_e.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/all_e.js b/ld_client/doc/pdoc/search/all_e.js
new file mode 100644
index 0000000..94ddcc3
--- /dev/null
+++ b/ld_client/doc/pdoc/search/all_e.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['unwrapexceptionmessages_0',['UnwrapExceptionMessages',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea',1,'LDClient::utils::loggers::ALogger']]],
+  ['username_1',['UserName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_0.html b/ld_client/doc/pdoc/search/classes_0.html
new file mode 100644
index 0000000..9d4f871
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_0.js b/ld_client/doc/pdoc/search/classes_0.js
new file mode 100644
index 0000000..c2bc89b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_0.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html',1,'LDClient::utils::loggers']]],
+  ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html',1,'LDClient::network']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_1.html b/ld_client/doc/pdoc/search/classes_1.html
new file mode 100644
index 0000000..0557f9f
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_1.js b/ld_client/doc/pdoc/search/classes_1.js
new file mode 100644
index 0000000..24f6506
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_1.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['consolelogger_0',['ConsoleLogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html',1,'LDClient::utils::loggers']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_2.html b/ld_client/doc/pdoc/search/classes_2.html
new file mode 100644
index 0000000..fa20861
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_2.js b/ld_client/doc/pdoc/search/classes_2.js
new file mode 100644
index 0000000..3d9e4e9
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_2.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['debuggerinfo_0',['DebuggerInfo',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html',1,'LDClient::network::data']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_3.html b/ld_client/doc/pdoc/search/classes_3.html
new file mode 100644
index 0000000..98fbc87
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_3.js b/ld_client/doc/pdoc/search/classes_3.js
new file mode 100644
index 0000000..230c4a7
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_3.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['filelogger_0',['FileLogger',['../class_file_logger.html',1,'']]],
+  ['fileutils_1',['FileUtils',['../class_l_d_client_1_1utils_1_1_file_utils.html',1,'LDClient::utils']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_4.html b/ld_client/doc/pdoc/search/classes_4.html
new file mode 100644
index 0000000..3b6c51e
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_4.js b/ld_client/doc/pdoc/search/classes_4.js
new file mode 100644
index 0000000..7de16de
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_4.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['httpclient_0',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html',1,'LDClient::network']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_5.html b/ld_client/doc/pdoc/search/classes_5.html
new file mode 100644
index 0000000..51c2b30
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_5.js b/ld_client/doc/pdoc/search/classes_5.js
new file mode 100644
index 0000000..80f4a0d
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_5.js
@@ -0,0 +1,9 @@
+var searchData=
+[
+  ['iapiclient_0',['IApiClient',['../interface_l_d_client_1_1network_1_1_i_api_client.html',1,'LDClient::network']]],
+  ['ifileutils_1',['IFileUtils',['../interface_l_d_client_1_1utils_1_1_i_file_utils.html',1,'LDClient::utils']]],
+  ['ihttpclient_2',['IHttpClient',['../interface_l_d_client_1_1network_1_1_i_http_client.html',1,'LDClient::network']]],
+  ['iinfofetcher_3',['IInfoFetcher',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html',1,'LDClient::detection']]],
+  ['infofetcher_4',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html',1,'LDClient::detection']]],
+  ['iprocessutils_5',['IProcessUtils',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html',1,'LDClient::detection']]]
+];
diff --git a/ld_client/doc/pdoc/search/classes_6.html b/ld_client/doc/pdoc/search/classes_6.html
new file mode 100644
index 0000000..431fb05
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_6.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="classes_6.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/classes_6.js b/ld_client/doc/pdoc/search/classes_6.js
new file mode 100644
index 0000000..72a3395
--- /dev/null
+++ b/ld_client/doc/pdoc/search/classes_6.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['payload_0',['Payload',['../class_l_d_client_1_1network_1_1data_1_1_payload.html',1,'LDClient::network::data']]],
+  ['processdetection_1',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html',1,'LDClient::detection']]],
+  ['processutils_2',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_process_utils.html',1,'LDClient::detection']]]
+];
diff --git a/ld_client/doc/pdoc/search/close.svg b/ld_client/doc/pdoc/search/close.svg
new file mode 100644
index 0000000..a933eea
--- /dev/null
+++ b/ld_client/doc/pdoc/search/close.svg
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   viewBox="0 0 11 11"
+   height="11"
+   width="11"
+   id="svg2"
+   version="1.1">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6" />
+  <path
+     id="path12"
+     d="M 5.5 0.5 A 5 5 0 0 0 0.5 5.5 A 5 5 0 0 0 5.5 10.5 A 5 5 0 0 0 10.5 5.5 A 5 5 0 0 0 5.5 0.5 z M 3.5820312 3 A 0.58291923 0.58291923 0 0 1 4 3.1757812 L 5.5 4.6757812 L 7 3.1757812 A 0.58291923 0.58291923 0 0 1 7.4003906 3 A 0.58291923 0.58291923 0 0 1 7.8242188 4 L 6.3242188 5.5 L 7.8242188 7 A 0.58291923 0.58291923 0 1 1 7 7.8242188 L 5.5 6.3242188 L 4 7.8242188 A 0.58291923 0.58291923 0 1 1 3.1757812 7 L 4.6757812 5.5 L 3.1757812 4 A 0.58291923 0.58291923 0 0 1 3.5820312 3 z "
+     style="stroke-width:1.09870648;fill:#bababa;fill-opacity:1" />
+</svg>
diff --git a/ld_client/doc/pdoc/search/enums_0.html b/ld_client/doc/pdoc/search/enums_0.html
new file mode 100644
index 0000000..ec25efd
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enums_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enums_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/enums_0.js b/ld_client/doc/pdoc/search/enums_0.js
new file mode 100644
index 0000000..cf8256f
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enums_0.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['connectionstatus_0',['ConnectionStatus',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60',1,'LDClient::network::data']]]
+];
diff --git a/ld_client/doc/pdoc/search/enums_1.html b/ld_client/doc/pdoc/search/enums_1.html
new file mode 100644
index 0000000..cc99a33
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enums_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enums_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/enums_1.js b/ld_client/doc/pdoc/search/enums_1.js
new file mode 100644
index 0000000..98425df
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enums_1.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['logflow_0',['LogFlow',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345',1,'LDClient::utils::loggers']]],
+  ['logtype_1',['LogType',['../namespace_l_d_client_1_1utils_1_1loggers.html#afeef5648c4f78e32623be5fa2b27f37c',1,'LDClient::utils::loggers']]],
+  ['logverbosity_2',['LogVerbosity',['../namespace_l_d_client_1_1utils_1_1loggers.html#a98b0cc04a019c9d28b7a9bd5737f944d',1,'LDClient::utils::loggers']]]
+];
diff --git a/ld_client/doc/pdoc/search/enumvalues_0.html b/ld_client/doc/pdoc/search/enumvalues_0.html
new file mode 100644
index 0000000..71e9b7c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enumvalues_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/enumvalues_0.js b/ld_client/doc/pdoc/search/enumvalues_0.js
new file mode 100644
index 0000000..3830bdb
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_0.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['connected_0',['Connected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60a2ec0d16e4ca169baedb9b2d50ec5c6d7',1,'LDClient::network::data']]],
+  ['console_1',['Console',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345abccaa4aa80831b76c11240a16447975f',1,'LDClient::utils::loggers']]]
+];
diff --git a/ld_client/doc/pdoc/search/enumvalues_1.html b/ld_client/doc/pdoc/search/enumvalues_1.html
new file mode 100644
index 0000000..595aa8c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enumvalues_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/enumvalues_1.js b/ld_client/doc/pdoc/search/enumvalues_1.js
new file mode 100644
index 0000000..ae0f7a4
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_1.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['disconnected_0',['Disconnected',['../namespace_l_d_client_1_1network_1_1data.html#a0c6d481eff113dd190f5a162b6464e60aef70e46fd3bbc21e3e1f0b6815e750c0',1,'LDClient::network::data']]]
+];
diff --git a/ld_client/doc/pdoc/search/enumvalues_2.html b/ld_client/doc/pdoc/search/enumvalues_2.html
new file mode 100644
index 0000000..5343504
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="enumvalues_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/enumvalues_2.js b/ld_client/doc/pdoc/search/enumvalues_2.js
new file mode 100644
index 0000000..a5f557f
--- /dev/null
+++ b/ld_client/doc/pdoc/search/enumvalues_2.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['file_0',['File',['../namespace_l_d_client_1_1utils_1_1loggers.html#a8a6f0dbee11cb125ee34af8fcc8bc345a0b27918290ff5323bea1e3b78a9cf04e',1,'LDClient::utils::loggers']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_0.html b/ld_client/doc/pdoc/search/functions_0.html
new file mode 100644
index 0000000..3b739c7
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_0.js b/ld_client/doc/pdoc/search/functions_0.js
new file mode 100644
index 0000000..356c8b6
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_0.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['alogger_0',['ALogger',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a0a42ccc73ba8693a90da6a3a9bfca8f3',1,'LDClient::utils::loggers::ALogger']]],
+  ['apiclient_1',['ApiClient',['../class_l_d_client_1_1network_1_1_api_client.html#a9dc8bd923651fcbac08b72ae6165aa73',1,'LDClient::network::ApiClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_1.html b/ld_client/doc/pdoc/search/functions_1.html
new file mode 100644
index 0000000..2cef5e3
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_1.js b/ld_client/doc/pdoc/search/functions_1.js
new file mode 100644
index 0000000..f94987c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_1.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['composelogrow_0',['ComposeLogRow',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a06814df4864ce7784647d15966eb1b4b',1,'LDClient::utils::loggers::ALogger']]],
+  ['createlog_1',['CreateLog',['../class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html#aca7d10ea902e782733adaa53713f66b7',1,'LDClient.utils.loggers.ConsoleLogger.CreateLog()'],['../class_file_logger.html#ad39844b2267623f858ab77e6f5433896',1,'FileLogger.CreateLog()']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_2.html b/ld_client/doc/pdoc/search/functions_2.html
new file mode 100644
index 0000000..3308c65
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_2.js b/ld_client/doc/pdoc/search/functions_2.js
new file mode 100644
index 0000000..8fdccce
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_2.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['debug_0',['Debug',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a5c626205a03a7829c6dd195ee18d8e81',1,'LDClient::utils::loggers::ALogger']]],
+  ['dispose_1',['Dispose',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a60bb1691cc7cc543d94a34da86b91433',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_3.html b/ld_client/doc/pdoc/search/functions_3.html
new file mode 100644
index 0000000..43ac697
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_3.js b/ld_client/doc/pdoc/search/functions_3.js
new file mode 100644
index 0000000..018d2dc
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_3.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['error_0',['Error',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a7f041d300e6d06dc58f969c4c0afd504',1,'LDClient.utils.loggers.ALogger.Error(string message)'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8be19175b75b9e09ce307a251a0358f2',1,'LDClient.utils.loggers.ALogger.Error(Exception e)']]],
+  ['executenewprocess_1',['ExecuteNewProcess',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ab7e48a228ebaf7dddc671e5af2325662',1,'LDClient.detection.IProcessUtils.ExecuteNewProcess()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a863da05a6d25ead94a6eb0bd00f91557',1,'LDClient.detection.ProcessUtils.ExecuteNewProcess()']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_4.html b/ld_client/doc/pdoc/search/functions_4.html
new file mode 100644
index 0000000..d12c2df
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_4.js b/ld_client/doc/pdoc/search/functions_4.js
new file mode 100644
index 0000000..77b0446
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_4.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['fetchdataasync_0',['FetchDataAsync',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a115b4d4fb74bd4eb09d8eeb4716793f9',1,'LDClient.detection.IInfoFetcher.FetchDataAsync()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a2192ceaf45e724814bdfde96fc0e544c',1,'LDClient.detection.InfoFetcher.FetchDataAsync()']]],
+  ['flush_1',['Flush',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a8cb167cc304b1fb7fc581271f1465ca4',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_5.html b/ld_client/doc/pdoc/search/functions_5.html
new file mode 100644
index 0000000..7266236
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_5.js b/ld_client/doc/pdoc/search/functions_5.js
new file mode 100644
index 0000000..a4088a6
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_5.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['httpclient_0',['HttpClient',['../class_l_d_client_1_1network_1_1_http_client.html#a7ec70d89410863e423ea2bcabaedc9a3',1,'LDClient::network::HttpClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_6.html b/ld_client/doc/pdoc/search/functions_6.html
new file mode 100644
index 0000000..7f9fc45
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_6.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_6.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_6.js b/ld_client/doc/pdoc/search/functions_6.js
new file mode 100644
index 0000000..cf45353
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_6.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['info_0',['Info',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#ac8f52ab4e431a47107d30db51615237e',1,'LDClient::utils::loggers::ALogger']]],
+  ['infofetcher_1',['InfoFetcher',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#abadca27b2740339ac6c1fd5c5e08bb26',1,'LDClient::detection::InfoFetcher']]],
+  ['isprocessrunning_2',['IsProcessRunning',['../interface_l_d_client_1_1detection_1_1_i_process_utils.html#ad86c09b9bd71f7087ada92851b07e1a0',1,'LDClient.detection.IProcessUtils.IsProcessRunning()'],['../class_l_d_client_1_1detection_1_1_process_utils.html#a851a0af6188cf17614870a94ddb87fc4',1,'LDClient.detection.ProcessUtils.IsProcessRunning()']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_7.html b/ld_client/doc/pdoc/search/functions_7.html
new file mode 100644
index 0000000..ad0f88b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_7.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_7.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_7.js b/ld_client/doc/pdoc/search/functions_7.js
new file mode 100644
index 0000000..689681a
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_7.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['parsetojson_0',['ParseToJson',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acd1a2d92945c91d22c262ce7b5a75d57',1,'LDClient.network.data.Payload.ParseToJson()'],['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a481fbe5952888d2dd7b6df0ff67ef056',1,'LDClient.network.data.Payload.ParseToJson(Payload payload)']]],
+  ['postasjsonasync_1',['PostAsJsonAsync',['../class_l_d_client_1_1network_1_1_http_client.html#a553187973e0f43053af43bdae239ef4d',1,'LDClient.network.HttpClient.PostAsJsonAsync()'],['../interface_l_d_client_1_1network_1_1_i_http_client.html#a241d7baceaf176b341c46844e235bd0f',1,'LDClient.network.IHttpClient.PostAsJsonAsync()']]],
+  ['processdetection_2',['ProcessDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#a586a1c6d9a48f2f7aa5389699bb4c679',1,'LDClient::detection::ProcessDetection']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_8.html b/ld_client/doc/pdoc/search/functions_8.html
new file mode 100644
index 0000000..ea7fa74
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_8.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_8.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_8.js b/ld_client/doc/pdoc/search/functions_8.js
new file mode 100644
index 0000000..fc6db8c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_8.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['readfilealllines_0',['ReadFileAllLines',['../class_l_d_client_1_1utils_1_1_file_utils.html#a411ef16d3be50fea59473b160d801737',1,'LDClient.utils.FileUtils.ReadFileAllLines()'],['../interface_l_d_client_1_1utils_1_1_i_file_utils.html#ae4d668d0e5850831680c8793cecd89a3',1,'LDClient.utils.IFileUtils.ReadFileAllLines()']]],
+  ['run_1',['Run',['../class_l_d_client_1_1network_1_1_api_client.html#ade3b671e7561fbc4c560d3e3a7a79979',1,'LDClient.network.ApiClient.Run()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#ab668a6e4e3f1d219c38f5e323d8735cb',1,'LDClient.network.IApiClient.Run()']]],
+  ['runperiodicdetection_2',['RunPeriodicDetection',['../class_l_d_client_1_1detection_1_1_process_detection.html#adc7f2823d21a1fbbddfe0328d05df3a8',1,'LDClient::detection::ProcessDetection']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_9.html b/ld_client/doc/pdoc/search/functions_9.html
new file mode 100644
index 0000000..d831dc7
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_9.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_9.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_9.js b/ld_client/doc/pdoc/search/functions_9.js
new file mode 100644
index 0000000..358fa79
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_9.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['sendpayloadasync_0',['SendPayloadAsync',['../class_l_d_client_1_1network_1_1_api_client.html#a8e78939c5ab5b2f2f417ba280584cb55',1,'LDClient.network.ApiClient.SendPayloadAsync()'],['../interface_l_d_client_1_1network_1_1_i_api_client.html#a8edc6823e4fb6f476a88af2da18e3b7f',1,'LDClient.network.IApiClient.SendPayloadAsync()']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_a.html b/ld_client/doc/pdoc/search/functions_a.html
new file mode 100644
index 0000000..7018fc6
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_a.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_a.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_a.js b/ld_client/doc/pdoc/search/functions_a.js
new file mode 100644
index 0000000..1a5397b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_a.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['tostring_0',['ToString',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad81cd8c8c44f80a75d0fbea3aa8d0148',1,'LDClient.network.data.Payload.ToString()'],['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a08558ed797aa0cf2efbba7ff6c868453',1,'LDClient.utils.loggers.ALogger.ToString()']]]
+];
diff --git a/ld_client/doc/pdoc/search/functions_b.html b/ld_client/doc/pdoc/search/functions_b.html
new file mode 100644
index 0000000..c0660b0
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_b.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="functions_b.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/functions_b.js b/ld_client/doc/pdoc/search/functions_b.js
new file mode 100644
index 0000000..b788fa0
--- /dev/null
+++ b/ld_client/doc/pdoc/search/functions_b.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['unwrapexceptionmessages_0',['UnwrapExceptionMessages',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a6bcc70a878ba68230afcdcac45855eea',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/mag_sel.svg b/ld_client/doc/pdoc/search/mag_sel.svg
new file mode 100644
index 0000000..03626f6
--- /dev/null
+++ b/ld_client/doc/pdoc/search/mag_sel.svg
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="svg2"
+   width="20"
+   height="19"
+   viewBox="0 0 20 19"
+   sodipodi:docname="mag_sel.svg"
+   inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="2096"
+     id="namedview4"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:zoom="32"
+     inkscape:cx="5.9792688"
+     inkscape:cy="1.1436277"
+     inkscape:window-x="1920"
+     inkscape:window-y="27"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <circle
+     style="fill:#000000;fill-opacity:0;stroke:#656565;stroke-width:1.4;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+     id="path4611"
+     cx="5.5"
+     cy="8.5"
+     r="3.5" />
+  <path
+     style="fill:#656565;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="M 11,7 13.5,10 16,7 Z"
+     id="path4609"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccc" />
+  <path
+     style="fill:none;stroke:#656565;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+     d="m 8.1085854,11.109059 2.7823556,2.782356"
+     id="path4630"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/ld_client/doc/pdoc/search/namespaces_0.html b/ld_client/doc/pdoc/search/namespaces_0.html
new file mode 100644
index 0000000..b2d68fe
--- /dev/null
+++ b/ld_client/doc/pdoc/search/namespaces_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="namespaces_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/namespaces_0.js b/ld_client/doc/pdoc/search/namespaces_0.js
new file mode 100644
index 0000000..7472a95
--- /dev/null
+++ b/ld_client/doc/pdoc/search/namespaces_0.js
@@ -0,0 +1,9 @@
+var searchData=
+[
+  ['data_0',['data',['../namespace_l_d_client_1_1network_1_1data.html',1,'LDClient::network']]],
+  ['detection_1',['detection',['../namespace_l_d_client_1_1detection.html',1,'LDClient']]],
+  ['ldclient_2',['LDClient',['../namespace_l_d_client.html',1,'']]],
+  ['loggers_3',['loggers',['../namespace_l_d_client_1_1utils_1_1loggers.html',1,'LDClient::utils']]],
+  ['network_4',['network',['../namespace_l_d_client_1_1network.html',1,'LDClient']]],
+  ['utils_5',['utils',['../namespace_l_d_client_1_1utils.html',1,'LDClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/nomatches.html b/ld_client/doc/pdoc/search/nomatches.html
new file mode 100644
index 0000000..2b9360b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/nomatches.html
@@ -0,0 +1,13 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="NoMatches">No Matches</div>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_0.html b/ld_client/doc/pdoc/search/properties_0.html
new file mode 100644
index 0000000..e1b4f60
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_0.js b/ld_client/doc/pdoc/search/properties_0.js
new file mode 100644
index 0000000..4ff2bab
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_0.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['bodydevice_0',['BodyDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a82af1fdf887d86f81acfec3b51936208',1,'LDClient::network::data::Payload']]],
+  ['bodyserialnumber_1',['BodySerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#afff68b22c92585ba9169cd558bcb66b9',1,'LDClient.detection.IInfoFetcher.BodySerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af38c5cdb5dc206c65d5f018e0b30dd1d',1,'LDClient.detection.InfoFetcher.BodySerialNumber()']]]
+];
diff --git a/ld_client/doc/pdoc/search/properties_1.html b/ld_client/doc/pdoc/search/properties_1.html
new file mode 100644
index 0000000..dab619c
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_1.js b/ld_client/doc/pdoc/search/properties_1.js
new file mode 100644
index 0000000..a3e1d85
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_1.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['current_0',['Current',['../class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html#a614d0574928fa3f08452e753a263236f',1,'LDClient::utils::loggers::ALogger']]]
+];
diff --git a/ld_client/doc/pdoc/search/properties_2.html b/ld_client/doc/pdoc/search/properties_2.html
new file mode 100644
index 0000000..4492167
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_2.js b/ld_client/doc/pdoc/search/properties_2.js
new file mode 100644
index 0000000..e8a4bfa
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_2.js
@@ -0,0 +1,6 @@
+var searchData=
+[
+  ['headdevice_0',['HeadDevice',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad8926696e666228bfb9164fcbf430da5',1,'LDClient::network::data::Payload']]],
+  ['headserialnumber_1',['HeadSerialNumber',['../interface_l_d_client_1_1detection_1_1_i_info_fetcher.html#a196620b51706ff95e86dce886bd3d3a0',1,'LDClient.detection.IInfoFetcher.HeadSerialNumber()'],['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a053ba7e01a8cfcbebf2325a864e98e2f',1,'LDClient.detection.InfoFetcher.HeadSerialNumber()']]],
+  ['hostname_2',['HostName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#acbcdcd13f4cfd6074cabcbe1f39e9b72',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/properties_3.html b/ld_client/doc/pdoc/search/properties_3.html
new file mode 100644
index 0000000..2d5a4bb
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_3.js b/ld_client/doc/pdoc/search/properties_3.js
new file mode 100644
index 0000000..b8f186b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_3.js
@@ -0,0 +1,5 @@
+var searchData=
+[
+  ['serialnumber_0',['SerialNumber',['../class_l_d_client_1_1network_1_1data_1_1_debugger_info.html#acb364e62b03d8eea272ad6bed3dc9cdb',1,'LDClient::network::data::DebuggerInfo']]],
+  ['status_1',['Status',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#a47489fcc58ebc325d36de38db4d4e481',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/properties_4.html b/ld_client/doc/pdoc/search/properties_4.html
new file mode 100644
index 0000000..cc95ce5
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_4.js b/ld_client/doc/pdoc/search/properties_4.js
new file mode 100644
index 0000000..c46006b
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_4.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['timestamp_0',['TimeStamp',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ad79e14f0c9936a6e6581d72fca767297',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/properties_5.html b/ld_client/doc/pdoc/search/properties_5.html
new file mode 100644
index 0000000..94489a0
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_5.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="properties_5.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/properties_5.js b/ld_client/doc/pdoc/search/properties_5.js
new file mode 100644
index 0000000..4f0807e
--- /dev/null
+++ b/ld_client/doc/pdoc/search/properties_5.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['username_0',['UserName',['../class_l_d_client_1_1network_1_1data_1_1_payload.html#ab1d3b30416e011f29b7e82f284495f65',1,'LDClient::network::data::Payload']]]
+];
diff --git a/ld_client/doc/pdoc/search/search.css b/ld_client/doc/pdoc/search/search.css
new file mode 100644
index 0000000..648a792
--- /dev/null
+++ b/ld_client/doc/pdoc/search/search.css
@@ -0,0 +1,263 @@
+/*---------------- Search Box */
+
+#MSearchBox {
+    white-space : nowrap;
+    background: white;
+    border-radius: 0.65em;
+    box-shadow: inset 0.5px 0.5px 3px 0px #555;
+    z-index: 102;
+}
+
+#MSearchBox .left {
+    display: inline-block;
+    vertical-align: middle;
+    height: 1.4em;
+}
+
+#MSearchSelect {
+    display: inline-block;
+    vertical-align: middle;
+    height: 19px;
+    padding: 0 0 0 0.3em;
+    margin: 0;
+}
+
+#MSearchField {
+    display: inline-block;
+    vertical-align: middle;
+    width: 7.5em;
+    height: 19px;
+    margin: 0 0.15em;
+    padding: 0;
+    line-height: 1em;
+    border:none;
+    color: #909090;
+    outline: none;
+    font-family: Arial, Verdana, sans-serif;
+    -webkit-border-radius: 0px;
+    border-radius: 0px;
+    background: none;
+}
+
+@media(hover: none) {
+    /* to avoid zooming on iOS */
+    #MSearchField {
+        font-size: 16px;
+    }
+}
+
+#MSearchBox .right {
+    display: inline-block;
+    vertical-align: middle;
+    width: 1.4em;
+    height: 1.4em;
+}
+
+#MSearchClose {
+    display: none;
+    font-size: inherit;
+    background : none;
+    border: none;
+    margin: 0;
+    padding: 0;
+    outline: none;
+
+}
+
+#MSearchCloseImg {
+    height: 1.4em;
+    padding: 0.3em;
+    margin: 0;
+}
+
+.MSearchBoxActive #MSearchField {
+    color: #000000;
+}
+
+#main-menu > li:last-child {
+    /* This <li> object is the parent of the search bar */
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    height: 36px;
+    margin-right: 1em;
+}
+
+/*---------------- Search filter selection */
+
+#MSearchSelectWindow {
+    display: none;
+    position: absolute;
+    left: 0; top: 0;
+    border: 1px solid #90A5CE;
+    background-color: #F9FAFC;
+    z-index: 10001;
+    padding-top: 4px;
+    padding-bottom: 4px;
+    -moz-border-radius: 4px;
+    -webkit-border-top-left-radius: 4px;
+    -webkit-border-top-right-radius: 4px;
+    -webkit-border-bottom-left-radius: 4px;
+    -webkit-border-bottom-right-radius: 4px;
+    -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);
+}
+
+.SelectItem {
+    font: 8pt Arial, Verdana, sans-serif;
+    padding-left:  2px;
+    padding-right: 12px;
+    border: 0px;
+}
+
+span.SelectionMark {
+    margin-right: 4px;
+    font-family: monospace;
+    outline-style: none;
+    text-decoration: none;
+}
+
+a.SelectItem {
+    display: block;
+    outline-style: none;
+    color: #000000; 
+    text-decoration: none;
+    padding-left:   6px;
+    padding-right: 12px;
+}
+
+a.SelectItem:focus,
+a.SelectItem:active {
+    color: #000000; 
+    outline-style: none;
+    text-decoration: none;
+}
+
+a.SelectItem:hover {
+    color: #FFFFFF;
+    background-color: #3D578C;
+    outline-style: none;
+    text-decoration: none;
+    cursor: pointer;
+    display: block;
+}
+
+/*---------------- Search results window */
+
+iframe#MSearchResults {
+    /*width: 60ex;*/
+    height: 15em;
+}
+
+#MSearchResultsWindow {
+    display: none;
+    position: absolute;
+    left: 0; top: 0;
+    border: 1px solid #000;
+    background-color: #EEF1F7;
+    z-index:10000;
+}
+
+/* ----------------------------------- */
+
+
+#SRIndex {
+    clear:both; 
+    padding-bottom: 15px;
+}
+
+.SREntry {
+    font-size: 10pt;
+    padding-left: 1ex;
+}
+
+.SRPage .SREntry {
+    font-size: 8pt;
+    padding: 1px 5px;
+}
+
+body.SRPage {
+    margin: 5px 2px;
+}
+
+.SRChildren {
+    padding-left: 3ex; padding-bottom: .5em 
+}
+
+.SRPage .SRChildren {
+    display: none;
+}
+
+.SRSymbol {
+    font-weight: bold; 
+    color: #425E97;
+    font-family: Arial, Verdana, sans-serif;
+    text-decoration: none;
+    outline: none;
+}
+
+a.SRScope {
+    display: block;
+    color: #425E97; 
+    font-family: Arial, Verdana, sans-serif;
+    text-decoration: none;
+    outline: none;
+}
+
+a.SRSymbol:focus, a.SRSymbol:active,
+a.SRScope:focus, a.SRScope:active {
+    text-decoration: underline;
+}
+
+span.SRScope {
+    padding-left: 4px;
+    font-family: Arial, Verdana, sans-serif;
+}
+
+.SRPage .SRStatus {
+    padding: 2px 5px;
+    font-size: 8pt;
+    font-style: italic;
+    font-family: Arial, Verdana, sans-serif;
+}
+
+.SRResult {
+    display: none;
+}
+
+div.searchresults {
+    margin-left: 10px;
+    margin-right: 10px;
+}
+
+/*---------------- External search page results */
+
+.searchresult {
+    background-color: #F0F3F8;
+}
+
+.pages b {
+   color: white;
+   padding: 5px 5px 3px 5px;
+   background-image: url("../tab_a.png");
+   background-repeat: repeat-x;
+   text-shadow: 0 1px 1px #000000;
+}
+
+.pages {
+    line-height: 17px;
+    margin-left: 4px;
+    text-decoration: none;
+}
+
+.hl {
+    font-weight: bold;
+}
+
+#searchresults {
+    margin-bottom: 20px;
+}
+
+.searchpages {
+    margin-top: 10px;
+}
+
diff --git a/ld_client/doc/pdoc/search/search.js b/ld_client/doc/pdoc/search/search.js
new file mode 100644
index 0000000..607f4e1
--- /dev/null
+++ b/ld_client/doc/pdoc/search/search.js
@@ -0,0 +1,802 @@
+/*
+ @licstart  The following is the entire license notice for the JavaScript code in this file.
+
+ The MIT License (MIT)
+
+ Copyright (C) 1997-2020 by Dimitri van Heesch
+
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
+ and associated documentation files (the "Software"), to deal in the Software without restriction,
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
+ furnished to do so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be included in all copies or
+ substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
+ DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ @licend  The above is the entire license notice for the JavaScript code in this file
+ */
+function convertToId(search)
+{
+  var result = '';
+  for (i=0;i<search.length;i++)
+  {
+    var c = search.charAt(i);
+    var cn = c.charCodeAt(0);
+    if (c.match(/[a-z0-9\u0080-\uFFFF]/))
+    {
+      result+=c;
+    }
+    else if (cn<16)
+    {
+      result+="_0"+cn.toString(16);
+    }
+    else
+    {
+      result+="_"+cn.toString(16);
+    }
+  }
+  return result;
+}
+
+function getXPos(item)
+{
+  var x = 0;
+  if (item.offsetWidth)
+  {
+    while (item && item!=document.body)
+    {
+      x   += item.offsetLeft;
+      item = item.offsetParent;
+    }
+  }
+  return x;
+}
+
+function getYPos(item)
+{
+  var y = 0;
+  if (item.offsetWidth)
+  {
+     while (item && item!=document.body)
+     {
+       y   += item.offsetTop;
+       item = item.offsetParent;
+     }
+  }
+  return y;
+}
+
+/* A class handling everything associated with the search panel.
+
+   Parameters:
+   name - The name of the global variable that will be
+          storing this instance.  Is needed to be able to set timeouts.
+   resultPath - path to use for external files
+*/
+function SearchBox(name, resultsPath, label, extension)
+{
+  if (!name || !resultsPath) {  alert("Missing parameters to SearchBox."); }
+  if (!extension || extension == "") { extension = ".html"; }
+
+  // ---------- Instance variables
+  this.name                  = name;
+  this.resultsPath           = resultsPath;
+  this.keyTimeout            = 0;
+  this.keyTimeoutLength      = 500;
+  this.closeSelectionTimeout = 300;
+  this.lastSearchValue       = "";
+  this.lastResultsPage       = "";
+  this.hideTimeout           = 0;
+  this.searchIndex           = 0;
+  this.searchActive          = false;
+  this.searchLabel           = label;
+  this.extension             = extension;
+
+  // ----------- DOM Elements
+
+  this.DOMSearchField = function()
+  {  return document.getElementById("MSearchField");  }
+
+  this.DOMSearchSelect = function()
+  {  return document.getElementById("MSearchSelect");  }
+
+  this.DOMSearchSelectWindow = function()
+  {  return document.getElementById("MSearchSelectWindow");  }
+
+  this.DOMPopupSearchResults = function()
+  {  return document.getElementById("MSearchResults");  }
+
+  this.DOMPopupSearchResultsWindow = function()
+  {  return document.getElementById("MSearchResultsWindow");  }
+
+  this.DOMSearchClose = function()
+  {  return document.getElementById("MSearchClose"); }
+
+  this.DOMSearchBox = function()
+  {  return document.getElementById("MSearchBox");  }
+
+  // ------------ Event Handlers
+
+  // Called when focus is added or removed from the search field.
+  this.OnSearchFieldFocus = function(isActive)
+  {
+    this.Activate(isActive);
+  }
+
+  this.OnSearchSelectShow = function()
+  {
+    var searchSelectWindow = this.DOMSearchSelectWindow();
+    var searchField        = this.DOMSearchSelect();
+
+    var left = getXPos(searchField);
+    var top  = getYPos(searchField);
+    top += searchField.offsetHeight;
+
+    // show search selection popup
+    searchSelectWindow.style.display='block';
+    searchSelectWindow.style.left =  left + 'px';
+    searchSelectWindow.style.top  =  top  + 'px';
+
+    // stop selection hide timer
+    if (this.hideTimeout)
+    {
+      clearTimeout(this.hideTimeout);
+      this.hideTimeout=0;
+    }
+    return false; // to avoid "image drag" default event
+  }
+
+  this.OnSearchSelectHide = function()
+  {
+    this.hideTimeout = setTimeout(this.name +".CloseSelectionWindow()",
+                                  this.closeSelectionTimeout);
+  }
+
+  // Called when the content of the search field is changed.
+  this.OnSearchFieldChange = function(evt)
+  {
+    if (this.keyTimeout) // kill running timer
+    {
+      clearTimeout(this.keyTimeout);
+      this.keyTimeout = 0;
+    }
+
+    var e  = (evt) ? evt : window.event; // for IE
+    if (e.keyCode==40 || e.keyCode==13)
+    {
+      if (e.shiftKey==1)
+      {
+        this.OnSearchSelectShow();
+        var win=this.DOMSearchSelectWindow();
+        for (i=0;i<win.childNodes.length;i++)
+        {
+          var child = win.childNodes[i]; // get span within a
+          if (child.className=='SelectItem')
+          {
+            child.focus();
+            return;
+          }
+        }
+        return;
+      }
+      else
+      {
+        window.frames.MSearchResults.postMessage("take_focus", "*");
+      }
+    }
+    else if (e.keyCode==27) // Escape out of the search field
+    {
+      this.DOMSearchField().blur();
+      this.DOMPopupSearchResultsWindow().style.display = 'none';
+      this.DOMSearchClose().style.display = 'none';
+      this.lastSearchValue = '';
+      this.Activate(false);
+      return;
+    }
+
+    // strip whitespaces
+    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+
+    if (searchValue != this.lastSearchValue) // search value has changed
+    {
+      if (searchValue != "") // non-empty search
+      {
+        // set timer for search update
+        this.keyTimeout = setTimeout(this.name + '.Search()',
+                                     this.keyTimeoutLength);
+      }
+      else // empty search field
+      {
+        this.DOMPopupSearchResultsWindow().style.display = 'none';
+        this.DOMSearchClose().style.display = 'none';
+        this.lastSearchValue = '';
+      }
+    }
+  }
+
+  this.SelectItemCount = function(id)
+  {
+    var count=0;
+    var win=this.DOMSearchSelectWindow();
+    for (i=0;i<win.childNodes.length;i++)
+    {
+      var child = win.childNodes[i]; // get span within a
+      if (child.className=='SelectItem')
+      {
+        count++;
+      }
+    }
+    return count;
+  }
+
+  this.SelectItemSet = function(id)
+  {
+    var i,j=0;
+    var win=this.DOMSearchSelectWindow();
+    for (i=0;i<win.childNodes.length;i++)
+    {
+      var child = win.childNodes[i]; // get span within a
+      if (child.className=='SelectItem')
+      {
+        var node = child.firstChild;
+        if (j==id)
+        {
+          node.innerHTML='&#8226;';
+        }
+        else
+        {
+          node.innerHTML='&#160;';
+        }
+        j++;
+      }
+    }
+  }
+
+  // Called when an search filter selection is made.
+  // set item with index id as the active item
+  this.OnSelectItem = function(id)
+  {
+    this.searchIndex = id;
+    this.SelectItemSet(id);
+    var searchValue = this.DOMSearchField().value.replace(/ +/g, "");
+    if (searchValue!="" && this.searchActive) // something was found -> do a search
+    {
+      this.Search();
+    }
+  }
+
+  this.OnSearchSelectKey = function(evt)
+  {
+    var e = (evt) ? evt : window.event; // for IE
+    if (e.keyCode==40 && this.searchIndex<this.SelectItemCount()) // Down
+    {
+      this.searchIndex++;
+      this.OnSelectItem(this.searchIndex);
+    }
+    else if (e.keyCode==38 && this.searchIndex>0) // Up
+    {
+      this.searchIndex--;
+      this.OnSelectItem(this.searchIndex);
+    }
+    else if (e.keyCode==13 || e.keyCode==27)
+    {
+      this.OnSelectItem(this.searchIndex);
+      this.CloseSelectionWindow();
+      this.DOMSearchField().focus();
+    }
+    return false;
+  }
+
+  // --------- Actions
+
+  // Closes the results window.
+  this.CloseResultsWindow = function()
+  {
+    this.DOMPopupSearchResultsWindow().style.display = 'none';
+    this.DOMSearchClose().style.display = 'none';
+    this.Activate(false);
+  }
+
+  this.CloseSelectionWindow = function()
+  {
+    this.DOMSearchSelectWindow().style.display = 'none';
+  }
+
+  // Performs a search.
+  this.Search = function()
+  {
+    this.keyTimeout = 0;
+
+    // strip leading whitespace
+    var searchValue = this.DOMSearchField().value.replace(/^ +/, "");
+
+    var code = searchValue.toLowerCase().charCodeAt(0);
+    var idxChar = searchValue.substr(0, 1).toLowerCase();
+    if ( 0xD800 <= code && code <= 0xDBFF && searchValue > 1) // surrogate pair
+    {
+      idxChar = searchValue.substr(0, 2);
+    }
+
+    var resultsPage;
+    var resultsPageWithSearch;
+    var hasResultsPage;
+
+    var idx = indexSectionsWithContent[this.searchIndex].indexOf(idxChar);
+    if (idx!=-1)
+    {
+       var hexCode=idx.toString(16);
+       resultsPage = this.resultsPath + '/' + indexSectionNames[this.searchIndex] + '_' + hexCode + this.extension;
+       resultsPageWithSearch = resultsPage+'?'+escape(searchValue);
+       hasResultsPage = true;
+    }
+    else // nothing available for this search term
+    {
+       resultsPage = this.resultsPath + '/nomatches' + this.extension;
+       resultsPageWithSearch = resultsPage;
+       hasResultsPage = false;
+    }
+
+    window.frames.MSearchResults.location = resultsPageWithSearch;
+    var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow();
+
+    if (domPopupSearchResultsWindow.style.display!='block')
+    {
+       var domSearchBox = this.DOMSearchBox();
+       this.DOMSearchClose().style.display = 'inline-block';
+       var domPopupSearchResults = this.DOMPopupSearchResults();
+       var left = getXPos(domSearchBox) + 150; // domSearchBox.offsetWidth;
+       var top  = getYPos(domSearchBox) + 20;  // domSearchBox.offsetHeight + 1;
+       domPopupSearchResultsWindow.style.display = 'block';
+       left -= domPopupSearchResults.offsetWidth;
+       var maxWidth = document.body.clientWidth;
+       var width = 400;
+       if (left<10) left=10;
+       if (width+left+8>maxWidth) width=maxWidth-left-8;
+       domPopupSearchResultsWindow.style.top     = top  + 'px';
+       domPopupSearchResultsWindow.style.left    = left + 'px';
+       domPopupSearchResultsWindow.style.width   = width + 'px';
+    }
+
+    this.lastSearchValue = searchValue;
+    this.lastResultsPage = resultsPage;
+  }
+
+  // -------- Activation Functions
+
+  // Activates or deactivates the search panel, resetting things to
+  // their default values if necessary.
+  this.Activate = function(isActive)
+  {
+    if (isActive || // open it
+        this.DOMPopupSearchResultsWindow().style.display == 'block'
+       )
+    {
+      this.DOMSearchBox().className = 'MSearchBoxActive';
+
+      var searchField = this.DOMSearchField();
+
+      if (searchField.value == this.searchLabel) // clear "Search" term upon entry
+      {
+        searchField.value = '';
+        this.searchActive = true;
+      }
+    }
+    else if (!isActive) // directly remove the panel
+    {
+      this.DOMSearchBox().className = 'MSearchBoxInactive';
+      this.DOMSearchField().value   = this.searchLabel;
+      this.searchActive             = false;
+      this.lastSearchValue          = ''
+      this.lastResultsPage          = '';
+    }
+  }
+}
+
+// -----------------------------------------------------------------------
+
+// The class that handles everything on the search results page.
+function SearchResults(name)
+{
+    // The number of matches from the last run of <Search()>.
+    this.lastMatchCount = 0;
+    this.lastKey = 0;
+    this.repeatOn = false;
+
+    // Toggles the visibility of the passed element ID.
+    this.FindChildElement = function(id)
+    {
+      var parentElement = document.getElementById(id);
+      var element = parentElement.firstChild;
+
+      while (element && element!=parentElement)
+      {
+        if (element.nodeName.toLowerCase() == 'div' && element.className == 'SRChildren')
+        {
+          return element;
+        }
+
+        if (element.nodeName.toLowerCase() == 'div' && element.hasChildNodes())
+        {
+           element = element.firstChild;
+        }
+        else if (element.nextSibling)
+        {
+           element = element.nextSibling;
+        }
+        else
+        {
+          do
+          {
+            element = element.parentNode;
+          }
+          while (element && element!=parentElement && !element.nextSibling);
+
+          if (element && element!=parentElement)
+          {
+            element = element.nextSibling;
+          }
+        }
+      }
+    }
+
+    this.Toggle = function(id)
+    {
+      var element = this.FindChildElement(id);
+      if (element)
+      {
+        if (element.style.display == 'block')
+        {
+          element.style.display = 'none';
+        }
+        else
+        {
+          element.style.display = 'block';
+        }
+      }
+    }
+
+    // Searches for the passed string.  If there is no parameter,
+    // it takes it from the URL query.
+    //
+    // Always returns true, since other documents may try to call it
+    // and that may or may not be possible.
+    this.Search = function(search)
+    {
+      if (!search) // get search word from URL
+      {
+        search = window.location.search;
+        search = search.substring(1);  // Remove the leading '?'
+        search = unescape(search);
+      }
+
+      search = search.replace(/^ +/, ""); // strip leading spaces
+      search = search.replace(/ +$/, ""); // strip trailing spaces
+      search = search.toLowerCase();
+      search = convertToId(search);
+
+      var resultRows = document.getElementsByTagName("div");
+      var matches = 0;
+
+      var i = 0;
+      while (i < resultRows.length)
+      {
+        var row = resultRows.item(i);
+        if (row.className == "SRResult")
+        {
+          var rowMatchName = row.id.toLowerCase();
+          rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); // strip 'sr123_'
+
+          if (search.length<=rowMatchName.length &&
+             rowMatchName.substr(0, search.length)==search)
+          {
+            row.style.display = 'block';
+            matches++;
+          }
+          else
+          {
+            row.style.display = 'none';
+          }
+        }
+        i++;
+      }
+      document.getElementById("Searching").style.display='none';
+      if (matches == 0) // no results
+      {
+        document.getElementById("NoMatches").style.display='block';
+      }
+      else // at least one result
+      {
+        document.getElementById("NoMatches").style.display='none';
+      }
+      this.lastMatchCount = matches;
+      return true;
+    }
+
+    // return the first item with index index or higher that is visible
+    this.NavNext = function(index)
+    {
+      var focusItem;
+      while (1)
+      {
+        var focusName = 'Item'+index;
+        focusItem = document.getElementById(focusName);
+        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+        {
+          break;
+        }
+        else if (!focusItem) // last element
+        {
+          break;
+        }
+        focusItem=null;
+        index++;
+      }
+      return focusItem;
+    }
+
+    this.NavPrev = function(index)
+    {
+      var focusItem;
+      while (1)
+      {
+        var focusName = 'Item'+index;
+        focusItem = document.getElementById(focusName);
+        if (focusItem && focusItem.parentNode.parentNode.style.display=='block')
+        {
+          break;
+        }
+        else if (!focusItem) // last element
+        {
+          break;
+        }
+        focusItem=null;
+        index--;
+      }
+      return focusItem;
+    }
+
+    this.ProcessKeys = function(e)
+    {
+      if (e.type == "keydown")
+      {
+        this.repeatOn = false;
+        this.lastKey = e.keyCode;
+      }
+      else if (e.type == "keypress")
+      {
+        if (!this.repeatOn)
+        {
+          if (this.lastKey) this.repeatOn = true;
+          return false; // ignore first keypress after keydown
+        }
+      }
+      else if (e.type == "keyup")
+      {
+        this.lastKey = 0;
+        this.repeatOn = false;
+      }
+      return this.lastKey!=0;
+    }
+
+    this.Nav = function(evt,itemIndex)
+    {
+      var e  = (evt) ? evt : window.event; // for IE
+      if (e.keyCode==13) return true;
+      if (!this.ProcessKeys(e)) return false;
+
+      if (this.lastKey==38) // Up
+      {
+        var newIndex = itemIndex-1;
+        var focusItem = this.NavPrev(newIndex);
+        if (focusItem)
+        {
+          var child = this.FindChildElement(focusItem.parentNode.parentNode.id);
+          if (child && child.style.display == 'block') // children visible
+          {
+            var n=0;
+            var tmpElem;
+            while (1) // search for last child
+            {
+              tmpElem = document.getElementById('Item'+newIndex+'_c'+n);
+              if (tmpElem)
+              {
+                focusItem = tmpElem;
+              }
+              else // found it!
+              {
+                break;
+              }
+              n++;
+            }
+          }
+        }
+        if (focusItem)
+        {
+          focusItem.focus();
+        }
+        else // return focus to search field
+        {
+           parent.document.getElementById("MSearchField").focus();
+        }
+      }
+      else if (this.lastKey==40) // Down
+      {
+        var newIndex = itemIndex+1;
+        var focusItem;
+        var item = document.getElementById('Item'+itemIndex);
+        var elem = this.FindChildElement(item.parentNode.parentNode.id);
+        if (elem && elem.style.display == 'block') // children visible
+        {
+          focusItem = document.getElementById('Item'+itemIndex+'_c0');
+        }
+        if (!focusItem) focusItem = this.NavNext(newIndex);
+        if (focusItem)  focusItem.focus();
+      }
+      else if (this.lastKey==39) // Right
+      {
+        var item = document.getElementById('Item'+itemIndex);
+        var elem = this.FindChildElement(item.parentNode.parentNode.id);
+        if (elem) elem.style.display = 'block';
+      }
+      else if (this.lastKey==37) // Left
+      {
+        var item = document.getElementById('Item'+itemIndex);
+        var elem = this.FindChildElement(item.parentNode.parentNode.id);
+        if (elem) elem.style.display = 'none';
+      }
+      else if (this.lastKey==27) // Escape
+      {
+        parent.searchBox.CloseResultsWindow();
+        parent.document.getElementById("MSearchField").focus();
+      }
+      else if (this.lastKey==13) // Enter
+      {
+        return true;
+      }
+      return false;
+    }
+
+    this.NavChild = function(evt,itemIndex,childIndex)
+    {
+      var e  = (evt) ? evt : window.event; // for IE
+      if (e.keyCode==13) return true;
+      if (!this.ProcessKeys(e)) return false;
+
+      if (this.lastKey==38) // Up
+      {
+        if (childIndex>0)
+        {
+          var newIndex = childIndex-1;
+          document.getElementById('Item'+itemIndex+'_c'+newIndex).focus();
+        }
+        else // already at first child, jump to parent
+        {
+          document.getElementById('Item'+itemIndex).focus();
+        }
+      }
+      else if (this.lastKey==40) // Down
+      {
+        var newIndex = childIndex+1;
+        var elem = document.getElementById('Item'+itemIndex+'_c'+newIndex);
+        if (!elem) // last child, jump to parent next parent
+        {
+          elem = this.NavNext(itemIndex+1);
+        }
+        if (elem)
+        {
+          elem.focus();
+        }
+      }
+      else if (this.lastKey==27) // Escape
+      {
+        parent.searchBox.CloseResultsWindow();
+        parent.document.getElementById("MSearchField").focus();
+      }
+      else if (this.lastKey==13) // Enter
+      {
+        return true;
+      }
+      return false;
+    }
+}
+
+function setKeyActions(elem,action)
+{
+  elem.setAttribute('onkeydown',action);
+  elem.setAttribute('onkeypress',action);
+  elem.setAttribute('onkeyup',action);
+}
+
+function setClassAttr(elem,attr)
+{
+  elem.setAttribute('class',attr);
+  elem.setAttribute('className',attr);
+}
+
+function createResults()
+{
+  var results = document.getElementById("SRResults");
+  for (var e=0; e<searchData.length; e++)
+  {
+    var id = searchData[e][0];
+    var srResult = document.createElement('div');
+    srResult.setAttribute('id','SR_'+id);
+    setClassAttr(srResult,'SRResult');
+    var srEntry = document.createElement('div');
+    setClassAttr(srEntry,'SREntry');
+    var srLink = document.createElement('a');
+    srLink.setAttribute('id','Item'+e);
+    setKeyActions(srLink,'return searchResults.Nav(event,'+e+')');
+    setClassAttr(srLink,'SRSymbol');
+    srLink.innerHTML = searchData[e][1][0];
+    srEntry.appendChild(srLink);
+    if (searchData[e][1].length==2) // single result
+    {
+      srLink.setAttribute('href',searchData[e][1][1][0]);
+      srLink.setAttribute('onclick','parent.searchBox.CloseResultsWindow()');
+      if (searchData[e][1][1][1])
+      {
+       srLink.setAttribute('target','_parent');
+      }
+      else
+      {
+       srLink.setAttribute('target','_blank');
+      }
+      var srScope = document.createElement('span');
+      setClassAttr(srScope,'SRScope');
+      srScope.innerHTML = searchData[e][1][1][2];
+      srEntry.appendChild(srScope);
+    }
+    else // multiple results
+    {
+      srLink.setAttribute('href','javascript:searchResults.Toggle("SR_'+id+'")');
+      var srChildren = document.createElement('div');
+      setClassAttr(srChildren,'SRChildren');
+      for (var c=0; c<searchData[e][1].length-1; c++)
+      {
+        var srChild = document.createElement('a');
+        srChild.setAttribute('id','Item'+e+'_c'+c);
+        setKeyActions(srChild,'return searchResults.NavChild(event,'+e+','+c+')');
+        setClassAttr(srChild,'SRScope');
+        srChild.setAttribute('href',searchData[e][1][c+1][0]);
+        srChild.setAttribute('onclick','parent.searchBox.CloseResultsWindow()');
+        if (searchData[e][1][c+1][1])
+        {
+         srChild.setAttribute('target','_parent');
+        }
+        else
+        {
+         srChild.setAttribute('target','_blank');
+        }
+        srChild.innerHTML = searchData[e][1][c+1][2];
+        srChildren.appendChild(srChild);
+      }
+      srEntry.appendChild(srChildren);
+    }
+    srResult.appendChild(srEntry);
+    results.appendChild(srResult);
+  }
+}
+
+function init_search()
+{
+  var results = document.getElementById("MSearchSelectWindow");
+  for (var key in indexSectionLabels)
+  {
+    var link = document.createElement('a');
+    link.setAttribute('class','SelectItem');
+    link.setAttribute('onclick','searchBox.OnSelectItem('+key+')');
+    link.href='javascript:void(0)';
+    link.innerHTML='<span class="SelectionMark">&#160;</span>'+indexSectionLabels[key];
+    results.appendChild(link);
+  }
+  searchBox.OnSelectItem(0);
+}
+/* @license-end */
diff --git a/ld_client/doc/pdoc/search/search_l.png b/ld_client/doc/pdoc/search/search_l.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd5f7daa41a4c79b4ae9bea5aa7bdfb94e14084b
GIT binary patch
literal 567
zcmeAS@N?(olHy`uVBq!ia0vp^B0wz6!2%?$TA$hhDVB6cUq=Rpjs4tz5?O(Kg=CK)
zUj~NU84L`?eGCi_EEpJ?t}-xGu`@87+QPtK?83kxQ`TapwHK(CDaqU2h2ejD|C#+j
z9%q3^WHAE+w=f7ZGR&GI0Tg5}@$_|Nf5gMiEhFgvHvB#V1EZFwi(`n!`QAxqy_^C?
z+`jj!^>(R!W8j_r#qQ#gnr4kAxdU#F0+OBry<A_XEfSiTFv~GuLE}}0iFF6&H>$Z+
z_0PMi;P|#{d%mw(dnw=jM%@$onTJa%@6Nm3`;2S#nwtVFJI#`U@2Q@@JCCctagvF-
z8H=anvo~dTmJ2<pSnM=aYQ7mur_Vc=KQ;l29JyWDZCN~fev0|+o3}F2P%CNIx5trL
z8gA}<cc1qPiOH&eRG9J7<ifc}f%_b|eRo%1h+kMg?QxbQD_=Y#XWHp4|L@3Yv6bBq
zd~oOD{y#VJ78Z8RC_Y*B*FLF4Y09bOg^5e_I(Ak>YA%wA6IHRv%{vxvUm|R)kgZeo
zmX%Zb;mpflGZdXCTAgit`||AFzkI#z&(3d4(htA?U2FOL4WF6wY&TB#n3n*I4+hl|
z*NBpo#FA92<f2p{#b9J$XrXIpq-$UvVrXb(WMO4!u5DmoWniFd?|d6YLvDUbW?Cg~
V4KYc-(}5ZoJYD@<);T3K0RU@P%k2OF

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/search/search_m.png b/ld_client/doc/pdoc/search/search_m.png
new file mode 100644
index 0000000000000000000000000000000000000000..b429a16ba641960da1e52e5da85dc80fd82635c8
GIT binary patch
literal 158
zcmeAS@N?(olHy`uVBq!ia0vp^Oh7Em0U}M~ynTTbOS+@4BLl;=8&~`zjDUQ}64!{5
z;QX|b^2DN42FH~Aq*MjZ+{E<Mpwz^a%EFVWHb6xNo-U3d6}OUf^!3vd5)y3c{#bPU
z`teb@<JbTH_7jql7?`61bOfX$^6u_pUBbY`!?2W{-=^-N>vEu822WQ%mvv4FO#qs`
BFGc_W

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/search/search_r.png b/ld_client/doc/pdoc/search/search_r.png
new file mode 100644
index 0000000000000000000000000000000000000000..1af5d21ee13e070d7600f1c4657fde843b953a69
GIT binary patch
literal 553
zcmeAS@N?(olHy`uVBq!ia0vp^LO?9c!2%@BXHTsJQY`6?zK#qG8~eHcB(ehe3dtTp
zz6=bxGZ+|(`xqD=STHa&U1eaXVrO7DwS|Gf*oA>XrmV$GYcEhOQ<As43&a2R{xkc5
zJkA1-$YKTtZeb8+WSBKa0w~B{;_2(k{)mU2TSn0TZTNi#21XfA7sn8d^R1H{y_o_<
z+~hsAIakGYPy5?E?QfIV-)Ulw-A&uvc6(^?XfA18cvfYFtH_Fg-3MA$nhAz1;G4nQ
z)c5(>T(QLuS{~ooZ2P@v=Xc@RKW@Irliv8_;wroU0*)0O?temdsA~70jrdux+`@W7
z-N(<(C)L?hOO?KV{>8(jC{h<AlVfGFV&cS)C3al`J({hH{AZi%%{daMX%zO!rQPhj
zO4O~O1uR{5ym@yvujLfdunGzN6vJTAIO%M=m#VrSQ@h&By8@n<o)p=ZT$+AnU5ifM
z=cKe}PAc7}R+@<xE&raDXZb+)aQF4y<?OdioGN6^Ufq9RRdf1xc5a~x>pKsws)#Fh
zvsO>IB+gb@b+rGWaO&!a9Z{!U+fV*s7TS>fdt&j$L%^U@Epd$~Nl7e8wMs5Z1yT$~
z28I^8hDN#u<{^fLRz?<9hUVG^237_Jy7tbuQ8eV{r(~v8;?@w8^gA7>fx*+&&t;uc
GLK6VEQpiUD

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/search/searchdata.js b/ld_client/doc/pdoc/search/searchdata.js
new file mode 100644
index 0000000..d2dc55d
--- /dev/null
+++ b/ld_client/doc/pdoc/search/searchdata.js
@@ -0,0 +1,36 @@
+var indexSectionsWithContent =
+{
+  0: "_abcdefhilprstu",
+  1: "acdfhip",
+  2: "l",
+  3: "acdefhiprstu",
+  4: "_cdfp",
+  5: "cl",
+  6: "cdf",
+  7: "bchstu"
+};
+
+var indexSectionNames =
+{
+  0: "all",
+  1: "classes",
+  2: "namespaces",
+  3: "functions",
+  4: "variables",
+  5: "enums",
+  6: "enumvalues",
+  7: "properties"
+};
+
+var indexSectionLabels =
+{
+  0: "All",
+  1: "Classes",
+  2: "Namespaces",
+  3: "Functions",
+  4: "Variables",
+  5: "Enumerations",
+  6: "Enumerator",
+  7: "Properties"
+};
+
diff --git a/ld_client/doc/pdoc/search/variables_0.html b/ld_client/doc/pdoc/search/variables_0.html
new file mode 100644
index 0000000..fd893a6
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_0.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_0.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/variables_0.js b/ld_client/doc/pdoc/search/variables_0.js
new file mode 100644
index 0000000..3d59743
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_0.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['_5fclient_0',['_client',['../class_l_d_client_1_1network_1_1_api_client.html#a052df6039a9aed754761e3c62209f37d',1,'LDClient::network::ApiClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/variables_1.html b/ld_client/doc/pdoc/search/variables_1.html
new file mode 100644
index 0000000..5f8e440
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_1.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_1.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/variables_1.js b/ld_client/doc/pdoc/search/variables_1.js
new file mode 100644
index 0000000..2214017
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_1.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['clientrunning_0',['ClientRunning',['../class_l_d_client_1_1network_1_1_api_client.html#a5ea6642309925c666e39db7f3ac103c1',1,'LDClient::network::ApiClient']]]
+];
diff --git a/ld_client/doc/pdoc/search/variables_2.html b/ld_client/doc/pdoc/search/variables_2.html
new file mode 100644
index 0000000..77a7f48
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_2.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_2.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/variables_2.js b/ld_client/doc/pdoc/search/variables_2.js
new file mode 100644
index 0000000..657a0dd
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_2.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['detectionrunning_0',['DetectionRunning',['../class_l_d_client_1_1detection_1_1_process_detection.html#acb2ce395f8b608c48165ae01677aa2a6',1,'LDClient::detection::ProcessDetection']]]
+];
diff --git a/ld_client/doc/pdoc/search/variables_3.html b/ld_client/doc/pdoc/search/variables_3.html
new file mode 100644
index 0000000..3ee62ba
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_3.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_3.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/variables_3.js b/ld_client/doc/pdoc/search/variables_3.js
new file mode 100644
index 0000000..faeaae4
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_3.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['fileutils_0',['FileUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#af30dbfb7559215ee29998f00ef5ea140',1,'LDClient::detection::InfoFetcher']]]
+];
diff --git a/ld_client/doc/pdoc/search/variables_4.html b/ld_client/doc/pdoc/search/variables_4.html
new file mode 100644
index 0000000..640713f
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_4.html
@@ -0,0 +1,37 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head><title></title>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<link rel="stylesheet" type="text/css" href="search.css"/>
+<script type="text/javascript" src="variables_4.js"></script>
+<script type="text/javascript" src="search.js"></script>
+</head>
+<body class="SRPage">
+<div id="SRIndex">
+<div class="SRStatus" id="Loading">Loading...</div>
+<div id="SRResults"></div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+createResults();
+/* @license-end */
+</script>
+<div class="SRStatus" id="Searching">Searching...</div>
+<div class="SRStatus" id="NoMatches">No Matches</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+document.getElementById("Loading").style.display="none";
+document.getElementById("NoMatches").style.display="none";
+var searchResults = new SearchResults("searchResults");
+searchResults.Search();
+window.addEventListener("message", function(event) {
+  if (event.data == "take_focus") {
+    var elem = searchResults.NavNext(0);
+    if (elem) elem.focus();
+  }
+});
+/* @license-end */
+</script>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/search/variables_4.js b/ld_client/doc/pdoc/search/variables_4.js
new file mode 100644
index 0000000..626a4f2
--- /dev/null
+++ b/ld_client/doc/pdoc/search/variables_4.js
@@ -0,0 +1,4 @@
+var searchData=
+[
+  ['processutils_0',['ProcessUtils',['../class_l_d_client_1_1detection_1_1_info_fetcher.html#a37f11db6d7bc81193b70015fc9192ed8',1,'LDClient::detection::InfoFetcher']]]
+];
diff --git a/ld_client/doc/pdoc/splitbar.png b/ld_client/doc/pdoc/splitbar.png
new file mode 100644
index 0000000000000000000000000000000000000000..fe895f2c58179b471a22d8320b39a4bd7312ec8e
GIT binary patch
literal 314
zcmeAS@N?(olHy`uVBq!ia0vp^Yzz!63>-{AmhX=Jf(#6djGiuzAr*{o?=JLmPLyc>
z_*`QK&+BH@jW<lVxsx`Ym~nPnqw$O~`M84{XS6<Mm0<Zit<Tk``D^RashfFq{wG<#
zZG2vRxL<$IhkFMSBd@N1`uRtp)t>rYJ7>r6%keRM@)Qyv8R=enp0jiI>aWlGyB58O
zFVR20d+y`K7vDw(hJF3;>dD*3-?v=<8M)@x|E<fHWtM%;-WUJ&>EGLnJsniYK!2U1
Y!`|5biEc?d1`HDhPgg&ebxsLQ02F6;9RL6T

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/sync_off.png b/ld_client/doc/pdoc/sync_off.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b443fc62892114406e3d399421b2a881b897acc
GIT binary patch
literal 853
zcmV-b1FHOqP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0009VNkl<ZcmeI*
zOK4PA7{KxW<S|JmGnqI|rb(KahDirA+8B+gVk8A)%pe9yF;+3L5iKZG7xuBS&@L(k
z33MTXOIxMHjirbWgs8M;qhM?(_-v^nS(KzU#%Ih_`hB-^XYSm&39)2*I6vmhow@fr
z=iKj{vvuv-e;!~uA+biR6pf-n<cdGVuox5<#BBg4c>oT|#XixUYy%lpuf3i8{fX!o
zUyDD0jOrAiT^tq>fLSOOABs-#u{dV^F$b{L9&!2=9&RmV;;8s^x&UqB$PCj4FdKbh
zoB1WTskPUPu05XzFbA}=KZ-GP1fPpAfSs>6AHb12UlR%-i&uOlTpFNS7{jm@mkU1V
zh`nrXr~+^lsV-s1dkZOaI|kYyVj3WBpPCY{n~yd%u%e+d=f%`N0FItMPtdgBb@py;
zq@v6NVArhyTC7)ULw-Jy8y42S1~4n(3LkrW8mW(F-4oXUP3E`e#g**YyqI7h-J2zK
zK{m9##m4ri!7N>CqQqCcnI3hqo1I;Yh&QLNY4T`*ptiQGozK>FF$!$+84Z`xwmeMh
zJ0WT+OH$WYFALEaGj2_l+#DC3t7_S`vHpSivNeFbP6+r50cO<q-Bsh$IuZaopT|9E
z-75alp&U9s%(|8uI^NA(#AD;nc=%{ivdZX(QFJ7~-yf%_Adjk`W@NhjJTyZ8*;|!n
z9=K#TJuZz+={YZ#>8iu)`7i%Z4BTPh@_m3Tk!nAm^)5Bqnr%Ov|Baunj#&RPtRuK&
z4RGz|D5HNrW83-#ydk}tVKJrNmyYt-sT<tBHx6XfOFDx2(ijpMiR>xLGlJY5nc&Re
zU4SgHNPx8~Yxwr$bsju?4q&%T1874xxzq+_%?h8_ofw~(bld=o3iC)LUNR*BY%c0y
zWd_jX{Y8`l%z+ol1$@Qa?Cy!(0CVIEeYpKZ`(9{z>3$CIe;pJDQk$m3p}$>xBm4lb
zKo{4S)`wdU9Ba9jJbVJ0C=SOefZe%d$8=2r={nu<_^a3~>c#t_U6dye5)JrR(_a^E
f@}b6j1K9lwFJq@>o)+Ry00000NkvXXu0mjfWa5j*

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/sync_on.png b/ld_client/doc/pdoc/sync_on.png
new file mode 100644
index 0000000000000000000000000000000000000000..e08320fb64e6fa33b573005ed6d8fe294e19db76
GIT binary patch
literal 845
zcmV-T1G4;yP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0009NNkl<ZcmeI*
zUr1D09KiAKIOC-Ar)j4&EoU~y1|7@QCTmeCsMH~fFw#|0OWK8m>Y;xxyHF2B5Wzm|
zOOGupOTn@c(JmBOl)e;XMNnZuiTJP>rM8<|Q`7I<ojWskx{8*sm){4kXJ+p2oO6HY
zoL5W7@h*VL_(ZL!7GaSmtl}SWU-XD;q7T4~4ZuW>_))aP?*T)ow&n59{}X4$3Goat
zgjs?*aasfbrokzG5cT4K=uG`E14xZl@z)F<o_Z}1zllSWC8!Z+rkFN>={P0Y^?$4t
z>v!teRnNZym<6h{7sLyF1V0HsfEl+l6TrZpsfr1}luH~F7L}ktXu|*uVX^RG$L0`K
zWs3j|0tIvVe(N%_?2{(iCPFGf#B6Hjy6o&}D$A%W%jfO8_W%ZO#-mh}EM$LMn7joJ
z05dHr!5Y92g+31l<%i1(=L1a1pXX+OYnalY>31V4K}BjyRe3)9n#;-cCVRD_IG1fT
zOKGeNY8q;TL@K{dj@D^scf&VCs*-Jb>8b>|`b*osv52-!A?BpbYtTQBns5EAU**$m
zSnVSm(teh>tQi*S*A>#ySc=n;`BHz`DuG4&g4Kf8lLhca+zvZ7t7RflD6-i-mcK=M
z!=^P$*u2)bkY5asG4gsss!Hn%u~>}kIW`vMs%lJLH+u*9<4PaV_c6U`KqWXQH%+Nu
zTv41O(^ZVi@qhjQdG!fbZw&y+2o!iYymO^?ud3{P*HdoX83YV*Uu_HB=?U&W9%AU#
z80}k1SS-CXTU7dcQlsm<^oYLxVSseqY6NO}dc`Nj?8vrhNuCdm@^{a3AQ_>6myOj+
z`1RsLUXF|dm|3k7s2jD(B{rzE>WI2scH8i1;=O5Cc9xB3^aJk%fQjqsu+kH#0=_5a
z0nCE8@dbQa-|YIuUVvG0L_IwHMEhOj$M<u9&-IHqnYs=DL+lbi3lG2ysF!p!_2H=p
zj-g89hmThki^;JHknVE4V`@zS$(ZbTd?1=dsrXLRiJbUBq7weAmVjEk@rP>j4Uq05
X8=0q~qBNan00000NkvXXu0mjfptF>5

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/tab_a.png b/ld_client/doc/pdoc/tab_a.png
new file mode 100644
index 0000000000000000000000000000000000000000..3b725c41c5a527a3a3e40097077d0e206a681247
GIT binary patch
literal 142
zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QlXwMjv*C{Z|8b*H5dputLHD#
z=<0|*y7z(Vor?d;H&?EG&cXR}?!j-Lm&u1OOI7AIF5&c)RFE;&p0MYK>*Kl@eiymD
r@|NpwKX@^z+;{u_Z~trSBfrMKa%3`zocFjEXaR$#tDnm{r-UW|TZ1%4

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/tab_b.png b/ld_client/doc/pdoc/tab_b.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2b4a8638cb3496a016eaed9e16ffc12846dea18
GIT binary patch
literal 169
zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QU#tajv*C{Z}0l@H7kg?K0Lnr
z!j&C6_(~HV9oQ0Pa6x{-v0AGV_E?vLn<f<Rf3mJ=+uzfrOMlc%s`x4TZtnrR|B~W{
zyZP0m7vvtXV80W5^J2vvp97)4WrPK1-P<H^B$Ll|TGvzm;+92|BpdT89$b1Qf7x5g
UZ&RH}7SL`6Pgg&ebxsLQ0A}n&iU0rr

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/tab_h.png b/ld_client/doc/pdoc/tab_h.png
new file mode 100644
index 0000000000000000000000000000000000000000..fd5cb705488e60fcf30f56fcc951dee74f3b095b
GIT binary patch
literal 177
zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QWc&qjv*C{Z}0jF9dr<AdpNI7
zaOs_6=O($9b?lc?Qk=SJVv5%FA{O^TY1^*qJ@<p}E}!uH_1eoPJ&tpVl={bg{Skd2
zp1FO|;|R90%G3WYZM5AU=A4%H?3qaQhHt%H9G|xYJ)ff*|MmI*zD3`*Z|LP?7d&26
cn!ZiLK0QM$CeyB_80ZEDPgg&ebxsLQ0C?O;!~g&Q

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/tab_s.png b/ld_client/doc/pdoc/tab_s.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab478c95b67371d700a20869f7de1ddd73522d50
GIT binary patch
literal 184
zcmeAS@N?(olHy`uVBq!ia0vp^j6kfy!2~3aiye;!QuUrLjv*C{Z|^p8HaRdjTwH7)
zC?wLlL}}I{)n%R&r+1}IGmDnq;&J#%V6)9VsYhS`O^BVBQlxOUep0c$RENLq#g8A$
z)z7%K_bI&n@J+X_=x}fJoEKed-$<>=ZI-;YrdjIl`U`uzuDWSP?o#Dmo{%SgM#oan
kX~E1%D-|#H#QbHoIja2U-MgvsK&LQxy85}Sb4q9e0Efg%P5=M^

literal 0
HcmV?d00001

diff --git a/ld_client/doc/pdoc/tabs.css b/ld_client/doc/pdoc/tabs.css
new file mode 100644
index 0000000..00d1c60
--- /dev/null
+++ b/ld_client/doc/pdoc/tabs.css
@@ -0,0 +1 @@
+.sm{position:relative;z-index:9999}.sm,.sm ul,.sm li{display:block;list-style:none;margin:0;padding:0;line-height:normal;direction:ltr;text-align:left;-webkit-tap-highlight-color:rgba(0,0,0,0)}.sm-rtl,.sm-rtl ul,.sm-rtl li{direction:rtl;text-align:right}.sm>li>h1,.sm>li>h2,.sm>li>h3,.sm>li>h4,.sm>li>h5,.sm>li>h6{margin:0;padding:0}.sm ul{display:none}.sm li,.sm a{position:relative}.sm a{display:block}.sm a.disabled{cursor:not-allowed}.sm:after{content:"\00a0";display:block;height:0;font:0/0 serif;clear:both;visibility:hidden;overflow:hidden}.sm,.sm *,.sm *:before,.sm *:after{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.main-menu-btn{position:relative;display:inline-block;width:36px;height:36px;text-indent:36px;margin-left:8px;white-space:nowrap;overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:rgba(0,0,0,0)}.main-menu-btn-icon,.main-menu-btn-icon:before,.main-menu-btn-icon:after{position:absolute;top:50%;left:2px;height:2px;width:24px;background:#666;-webkit-transition:all .25s;transition:all .25s}.main-menu-btn-icon:before{content:'';top:-7px;left:0}.main-menu-btn-icon:after{content:'';top:7px;left:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon{height:0}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:before{top:0;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#main-menu-state:checked ~ .main-menu-btn .main-menu-btn-icon:after{top:0;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#main-menu-state{position:absolute;width:1px;height:1px;margin:-1px;border:0;padding:0;overflow:hidden;clip:rect(1px,1px,1px,1px)}#main-menu-state:not(:checked) ~ #main-menu{display:none}#main-menu-state:checked ~ #main-menu{display:block}@media(min-width:768px){.main-menu-btn{position:absolute;top:-99999px}#main-menu-state:not(:checked) ~ #main-menu{display:block}}.sm-dox{background-image:url("tab_b.png")}.sm-dox a,.sm-dox a:focus,.sm-dox a:hover,.sm-dox a:active{padding:0 12px;padding-right:43px;font-family:"Lucida Grande","Geneva","Helvetica",Arial,sans-serif;font-size:13px;font-weight:bold;line-height:36px;text-decoration:none;text-shadow:0 1px 1px rgba(255,255,255,0.9);color:#283a5d;outline:0}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a.current{color:#d23600}.sm-dox a.disabled{color:#bbb}.sm-dox a span.sub-arrow{position:absolute;top:50%;margin-top:-14px;left:auto;right:3px;width:28px;height:28px;overflow:hidden;font:bold 12px/28px monospace !important;text-align:center;text-shadow:none;background:rgba(255,255,255,0.5);-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox a span.sub-arrow:before{display:block;content:'+'}.sm-dox a.highlighted span.sub-arrow:before{display:block;content:'-'}.sm-dox>li:first-child>a,.sm-dox>li:first-child>:not(ul) a{-moz-border-radius:5px 5px 0 0;-webkit-border-radius:5px;border-radius:5px 5px 0 0}.sm-dox>li:last-child>a,.sm-dox>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul{-moz-border-radius:0 0 5px 5px;-webkit-border-radius:0;border-radius:0 0 5px 5px}.sm-dox>li:last-child>a.highlighted,.sm-dox>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>a.highlighted,.sm-dox>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>ul>li:last-child>*:not(ul) a.highlighted{-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox ul{background:rgba(162,162,162,0.1)}.sm-dox ul a,.sm-dox ul a:focus,.sm-dox ul a:hover,.sm-dox ul a:active{font-size:12px;border-left:8px solid transparent;line-height:36px;text-shadow:none;background-color:white;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul ul a,.sm-dox ul ul a:hover,.sm-dox ul ul a:focus,.sm-dox ul ul a:active{border-left:16px solid transparent}.sm-dox ul ul ul a,.sm-dox ul ul ul a:hover,.sm-dox ul ul ul a:focus,.sm-dox ul ul ul a:active{border-left:24px solid transparent}.sm-dox ul ul ul ul a,.sm-dox ul ul ul ul a:hover,.sm-dox ul ul ul ul a:focus,.sm-dox ul ul ul ul a:active{border-left:32px solid transparent}.sm-dox ul ul ul ul ul a,.sm-dox ul ul ul ul ul a:hover,.sm-dox ul ul ul ul ul a:focus,.sm-dox ul ul ul ul ul a:active{border-left:40px solid transparent}@media(min-width:768px){.sm-dox ul{position:absolute;width:12em}.sm-dox li{float:left}.sm-dox.sm-rtl li{float:right}.sm-dox ul li,.sm-dox.sm-rtl ul li,.sm-dox.sm-vertical li{float:none}.sm-dox a{white-space:nowrap}.sm-dox ul a,.sm-dox.sm-vertical a{white-space:normal}.sm-dox .sm-nowrap>li>a,.sm-dox .sm-nowrap>li>:not(ul) a{white-space:nowrap}.sm-dox{padding:0 10px;background-image:url("tab_b.png");line-height:36px}.sm-dox a span.sub-arrow{top:50%;margin-top:-2px;right:12px;width:0;height:0;border-width:4px;border-style:solid dashed dashed dashed;border-color:#283a5d transparent transparent transparent;background:transparent;-moz-border-radius:0;-webkit-border-radius:0;border-radius:0}.sm-dox a,.sm-dox a:focus,.sm-dox a:active,.sm-dox a:hover,.sm-dox a.highlighted{padding:0 12px;background-image:url("tab_s.png");background-repeat:no-repeat;background-position:right;-moz-border-radius:0 !important;-webkit-border-radius:0;border-radius:0 !important}.sm-dox a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox a:hover span.sub-arrow{border-color:white transparent transparent transparent}.sm-dox a.has-submenu{padding-right:24px}.sm-dox li{border-top:0}.sm-dox>li>ul:before,.sm-dox>li>ul:after{content:'';position:absolute;top:-18px;left:30px;width:0;height:0;overflow:hidden;border-width:9px;border-style:dashed dashed solid dashed;border-color:transparent transparent #bbb transparent}.sm-dox>li>ul:after{top:-16px;left:31px;border-width:8px;border-color:transparent transparent #fff transparent}.sm-dox ul{border:1px solid #bbb;padding:5px 0;background:#fff;-moz-border-radius:5px !important;-webkit-border-radius:5px;border-radius:5px !important;-moz-box-shadow:0 5px 9px rgba(0,0,0,0.2);-webkit-box-shadow:0 5px 9px rgba(0,0,0,0.2);box-shadow:0 5px 9px rgba(0,0,0,0.2)}.sm-dox ul a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-color:transparent transparent transparent #555;border-style:dashed dashed dashed solid}.sm-dox ul a,.sm-dox ul a:hover,.sm-dox ul a:focus,.sm-dox ul a:active,.sm-dox ul a.highlighted{color:#555;background-image:none;border:0 !important;color:#555;background-image:none}.sm-dox ul a:hover{background-image:url("tab_a.png");background-repeat:repeat-x;color:white;text-shadow:0 1px 1px black}.sm-dox ul a:hover span.sub-arrow{border-color:transparent transparent transparent white}.sm-dox span.scroll-up,.sm-dox span.scroll-down{position:absolute;display:none;visibility:hidden;overflow:hidden;background:#fff;height:36px}.sm-dox span.scroll-up:hover,.sm-dox span.scroll-down:hover{background:#eee}.sm-dox span.scroll-up:hover span.scroll-up-arrow,.sm-dox span.scroll-up:hover span.scroll-down-arrow{border-color:transparent transparent #d23600 transparent}.sm-dox span.scroll-down:hover span.scroll-down-arrow{border-color:#d23600 transparent transparent transparent}.sm-dox span.scroll-up-arrow,.sm-dox span.scroll-down-arrow{position:absolute;top:0;left:50%;margin-left:-6px;width:0;height:0;overflow:hidden;border-width:6px;border-style:dashed dashed solid dashed;border-color:transparent transparent #555 transparent}.sm-dox span.scroll-down-arrow{top:8px;border-style:solid dashed dashed dashed;border-color:#555 transparent transparent transparent}.sm-dox.sm-rtl a.has-submenu{padding-right:12px;padding-left:24px}.sm-dox.sm-rtl a span.sub-arrow{right:auto;left:12px}.sm-dox.sm-rtl.sm-vertical a.has-submenu{padding:10px 20px}.sm-dox.sm-rtl.sm-vertical a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-rtl>li>ul:before{left:auto;right:30px}.sm-dox.sm-rtl>li>ul:after{left:auto;right:31px}.sm-dox.sm-rtl ul a.has-submenu{padding:10px 20px !important}.sm-dox.sm-rtl ul a span.sub-arrow{right:auto;left:8px;border-style:dashed solid dashed dashed;border-color:transparent #555 transparent transparent}.sm-dox.sm-vertical{padding:10px 0;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px}.sm-dox.sm-vertical a{padding:10px 20px}.sm-dox.sm-vertical a:hover,.sm-dox.sm-vertical a:focus,.sm-dox.sm-vertical a:active,.sm-dox.sm-vertical a.highlighted{background:#fff}.sm-dox.sm-vertical a.disabled{background-image:url("tab_b.png")}.sm-dox.sm-vertical a span.sub-arrow{right:8px;top:50%;margin-top:-5px;border-width:5px;border-style:dashed dashed dashed solid;border-color:transparent transparent transparent #555}.sm-dox.sm-vertical>li>ul:before,.sm-dox.sm-vertical>li>ul:after{display:none}.sm-dox.sm-vertical ul a{padding:10px 20px}.sm-dox.sm-vertical ul a:hover,.sm-dox.sm-vertical ul a:focus,.sm-dox.sm-vertical ul a:active,.sm-dox.sm-vertical ul a.highlighted{background:#eee}.sm-dox.sm-vertical ul a.disabled{background:#fff}}
\ No newline at end of file
-- 
GitLab


From f09385a359d71f272b995ccb103422706ae0d8ed Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 12:48:17 +0200
Subject: [PATCH 53/67] re #9712 Added configuration properties of the t32 api

---
 ld_client/LDClient/LDClient.csproj       | 15 ++++++-----
 ld_client/LDClient/appsettings.json      | 33 +++++++++++++++++++++---
 ld_client/LDClient/utils/ConfigLoader.cs | 21 +++++++++++----
 3 files changed, 54 insertions(+), 15 deletions(-)

diff --git a/ld_client/LDClient/LDClient.csproj b/ld_client/LDClient/LDClient.csproj
index c575ea0..a63b79f 100644
--- a/ld_client/LDClient/LDClient.csproj
+++ b/ld_client/LDClient/LDClient.csproj
@@ -7,21 +7,24 @@
     <Nullable>enable</Nullable>
   </PropertyGroup>
 
-  <ItemGroup>
+	<PropertyGroup Condition=" '$(OS)' == 'Windows_NT' ">
+		<DefineConstants>_WINDOWS</DefineConstants>
+	</PropertyGroup>
+
+	<ItemGroup>
     <None Remove="appsettings.json" />
+    <None Remove="t32api64.dll" />
   </ItemGroup>
 
   <ItemGroup>
     <EmbeddedResource Include="appsettings.json">
       <CopyToOutputDirectory>Always</CopyToOutputDirectory>
     </EmbeddedResource>
+    <EmbeddedResource Include="lib\t32api64.dll">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+    </EmbeddedResource>
   </ItemGroup>
 
-  <ItemGroup>
-    <Reference Include="t32apinet">
-      <HintPath>..\dotnet\t32apinet\bin\Release\t32apinet.dll</HintPath>
-    </Reference>
-  </ItemGroup>
 
   <ItemGroup>
     <PackageReference Include="DiskQueue" Version="1.5.0" />
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index 3a3a702..ba3cadb 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -26,18 +26,43 @@
     "CacheFileName": "cache"
   },
   "DebuggerDetection": {
-    "F32RemArguments": [
+    "T32RemArguments": [
       "localhost port=20000 printer.filetype ASCIIE",
       "localhost port=20000 printer.open C:\\app\\result.txt",
       "localhost port=20000 WinPrint.version.hardware",
       "localhost port=20000 printer.close "
     ],
-    "F32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe",
+    "T32ApiAddress": "localhost",
+    "T32ApiPort": "20000",
+    "T32ApiPacketLen": "1024",
+    "T32ApiCommands": [
+      "AREA.Create TWOWIRE",
+      "AREA.Select TWOWIRE",
+      "AREA.clear TWOWIRE",
+
+      "WinPOS 1. 1. 50. 3. 0. 0. MYAREA",
+      "Print \"TwoWire:\"",
+      "Print.cable.twowire()",
+      "Area.View TWOWIRE",
+
+      "PRinTer.FileType ASCIIE",
+      "PRinTer.OPEN C:\\app\\result.txt",
+      "WinPrint.license.list",
+      "screen.wait",
+      "WinPrint.Area.View TWOWIRE",
+      "WinPrint.version.hardware",
+      "Printer.CLOSE",
+
+      "Area.delete TWOWIRE",
+
+      "enddo"
+    ],
+    "T32RemExecutable": "c:\\app\\tools\\T32\\bin\\windows64\\t32rem.exe",
     "T32ProcessName": "t32mtc",
     "T32InfoLocation": "C:\\app\\result.txt",
     "DetectionPeriod": 5000,
-    "FetchInfoMaxAttempts": 5,
-    "FetchInfoAttemptPeriod": 1000,
+    "FetchInfoMaxAttempts": 15,
+    "FetchInfoAttemptPeriod": 4000,
     "T32RemSuccessExitCode": 0,
     "T32RemWaitTimeoutMs": 2000
   }
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 6dc3cf7..f585cce 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -38,8 +38,14 @@ namespace LDClient.utils {
         /// </summary>
         private const string DdSection = "DebuggerDetection";
 
+
+        public string[] T32ApiCommands { get; private set; } = null!;
+        public string T32ApiAddress { get; private set; } = null!;
+        public string T32ApiPort { get; private set; } = null!;
+        public string T32ApiPacketLen { get; private set; } = null!;
+
         #region Logger
-        
+
         /// <summary>
         /// Maximum size of the log file (it will start to rotate when this limit is reached).
         /// </summary>
@@ -135,7 +141,7 @@ namespace LDClient.utils {
         /// <summary>
         /// Path to the t32rem.exe which is used to send commands to a debugger.
         /// </summary>
-        public string F32RemExecutable { get; private set; } = null!;
+        public string T32RemExecutable { get; private set; } = null!;
         
         /// <summary>
         /// How many times the application attempts to check if there
@@ -151,7 +157,7 @@ namespace LDClient.utils {
         /// <summary>
         /// Arguments (commands) sent to the t32rem.exe file.
         /// </summary>
-        public string[] F32RemArguments { get; private set; } = null!;
+        public string[] T32RemArguments { get; private set; } = null!;
         
         /// <summary>
         /// Status code indication successful execution of the t32rem.exe file.
@@ -251,12 +257,17 @@ namespace LDClient.utils {
                 T32ProcessName = debugger["T32ProcessName"];
                 T32InfoLocation = debugger["T32InfoLocation"];
                 DetectionPeriod = uint.Parse(debugger["DetectionPeriod"]);
-                F32RemExecutable = debugger["F32RemExecutable"];
+                T32RemExecutable = debugger["T32RemExecutable"];
                 FetchInfoMaxAttempts = uint.Parse(debugger["FetchInfoMaxAttempts"]);
                 FetchInfoAttemptPeriod = uint.Parse(debugger["FetchInfoAttemptPeriod"]);
                 T32RemSuccessExitCode = int.Parse(debugger["T32RemSuccessExitCode"]);
                 T32RemWaitTimeoutMs = int.Parse(debugger["T32RemWaitTimeoutMs"]);
-                F32RemArguments = configuration.GetSection($"{DdSection}:F32RemArguments").GetChildren().Select(key => key.Value).ToArray();
+                T32RemArguments = configuration.GetSection($"{DdSection}:T32RemArguments").GetChildren().Select(key => key.Value).ToArray();
+                T32ApiCommands = configuration.GetSection($"{DdSection}:T32ApiCommands").GetChildren().Select(key => key.Value).ToArray();
+                T32ApiAddress = debugger["T32ApiAddress"];
+                T32ApiPort = debugger["T32ApiPort"];
+                T32ApiPacketLen = debugger["T32ApiPacketLen"];
+                
             } catch (Exception e) {
                 Console.WriteLine(e);
                 Environment.Exit(ErrorExitCode);
-- 
GitLab


From 68087f99f168fb52dded94470ac3d67d582e31eb Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 12:49:38 +0200
Subject: [PATCH 54/67] re #9712 restructuring of info fetcher

---
 ld_client/LDClient/detection/AInfoFetcher.cs | 130 +++++++++++++
 ld_client/LDClient/detection/IT32Utils.cs    |  15 ++
 ld_client/LDClient/detection/InfoFetcher.cs  | 186 -------------------
 3 files changed, 145 insertions(+), 186 deletions(-)
 create mode 100644 ld_client/LDClient/detection/AInfoFetcher.cs
 create mode 100644 ld_client/LDClient/detection/IT32Utils.cs
 delete mode 100644 ld_client/LDClient/detection/InfoFetcher.cs

diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs
new file mode 100644
index 0000000..c41f581
--- /dev/null
+++ b/ld_client/LDClient/detection/AInfoFetcher.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using LDClient.utils;
+
+namespace LDClient.detection; 
+
+/// <summary>
+/// This abstract class implements the common functions of the IInfoFetcher interface
+/// which defines the functionality of an info fetcher.
+/// </summary>
+public abstract class AInfoFetcher : IInfoFetcher {
+
+    /// <summary>
+    /// Default value of a serial number (undefined).
+    /// </summary>
+    private const string UndefinedSerialNumber = "number";
+
+    /// <summary>
+    /// Returns the head serial number of the debugger.
+    /// </summary>
+    public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;
+
+    /// <summary>
+    /// Returns the body serial number of the debugger.
+    /// </summary>
+    public string BodySerialNumber { get; set; } = UndefinedSerialNumber;
+
+    /// <summary>
+    /// Instance of FileUtils which encapsulates common functionality
+    /// when it comes to dealing with files (limited by the needs of this application).
+    /// </summary>
+    public IFileUtils FileUtils;
+
+    /// <summary>
+    /// Maximum number of attempts to locate and parse the .txt file.
+    /// </summary>
+    protected readonly uint _maxAttempts;
+
+    /// <summary>
+    /// Period (how often) the application tries to locate and parse the .txt file.
+    /// </summary>
+    protected readonly uint _waitPeriodMs;
+
+    /// <summary>
+    /// Path to the .txt file which is generated from the debugger.
+    /// </summary>
+    protected readonly string _infoFilePath;
+
+    /// <summary>
+    /// Abstract constructor of this class 
+    /// </summary>
+    /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
+    /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
+    /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
+
+    protected AInfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath) {
+        this.FileUtils = new FileUtils();
+        this._maxAttempts = maxAttempts;
+        this._waitPeriodMs = waitPeriodMs;
+        this._infoFilePath = infoFilePath;
+    }
+
+    /// <summary>
+    /// Abstract definition of the data fetching function
+    /// Function should send the commands to the debugger.
+    /// </summary>
+    /// <returns>true on success</returns>
+    protected abstract bool FetchData();
+
+    /// <summary>
+    /// Fetches data from the debugger. It sends the commands defined
+    /// in the appsettings.json file to the debugger and tries to
+    /// parse the .txt (contains the serial numbers).
+    /// </summary>
+    /// <returns>True, if data was fetched successfully. False otherwise.</returns>
+    public async Task<bool> FetchDataAsync() {
+        Program.DefaultLogger.Info("Fetching data from the debugger.");
+        // Send the commands to the debugger.
+        var success = FetchData();
+
+        // Make sure that all commands were sent and executed successfully.
+        if (!success) {
+            Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
+            return false;
+        }
+        // Periodically try to parse the .txt file. 
+        for (var i = 0; i < _maxAttempts; i++) {
+            Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");
+            // Try to parse .txt file.
+            if (RetrieveDebuggerInfo(_infoFilePath)) {
+                Program.DefaultLogger.Info($"Info file has been parsed successfully.");
+                return true;
+            }
+            // Wait for a specified number of milliseconds.
+            await Task.Delay((int)_waitPeriodMs);
+        }
+        Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
+        return false;
+    }
+
+    /// <summary>
+    /// Tries to retrieve information from the debugger.
+    /// </summary>
+    /// <param name="filePath">path to the .txt file that contains all information</param>
+    /// <returns>True if the information was retrieved successfully. False, otherwise.</returns>
+
+    protected bool RetrieveDebuggerInfo(string filePath) {
+        try {
+            // Read the content of the .txt file.
+            var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
+
+            // Parse it (try to find the serial numbers)
+            var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
+
+            // Store the serial numbers into class variables (properties)
+            HeadSerialNumber = headSerialNumber;
+            BodySerialNumber = bodySerialNumber;
+
+            // Finally, delete the file.
+            //File.Delete(filePath);
+        } catch (Exception exception) {
+            Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
+            return false;
+        }
+        return true;
+    }
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IT32Utils.cs b/ld_client/LDClient/detection/IT32Utils.cs
new file mode 100644
index 0000000..5904691
--- /dev/null
+++ b/ld_client/LDClient/detection/IT32Utils.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+    public interface IT32Utils {
+
+        public bool InitConnection();
+        public bool ExecuteCommands();
+        public bool CloseConnection();
+
+    }
+}
diff --git a/ld_client/LDClient/detection/InfoFetcher.cs b/ld_client/LDClient/detection/InfoFetcher.cs
deleted file mode 100644
index 7854ea6..0000000
--- a/ld_client/LDClient/detection/InfoFetcher.cs
+++ /dev/null
@@ -1,186 +0,0 @@
-using System.Diagnostics;
-using LDClient.utils;
-using LDClient.utils.loggers;
-
-namespace LDClient.detection {
-
-    /// <summary>
-    /// This class implements the IInfoFetcher interface
-    /// which defines the functionality of an info fetcher.
-    /// </summary>
-    public class InfoFetcher : IInfoFetcher {
-        
-        /// <summary>
-        /// Default value of a serial number (undefined).
-        /// </summary>
-        private const string UndefinedSerialNumber = "number";
-
-        /// <summary>
-        /// Path to the t32rem.exe file which is used to send commands to the debugger.
-        /// </summary>
-        private readonly string _f32RemExecutable;
-        
-        /// <summary>
-        /// Arguments (commands) sent to the debugger in order to generate a .txt file
-        /// containing all the desired information.
-        /// </summary>
-        private readonly string[] _f32RemArguments;
-        
-        /// <summary>
-        /// Status code indicating a successful termination of t32rem.exe
-        /// </summary>
-        private readonly int _f32SuccessExitCode;
-        
-        /// <summary>
-        /// Timeout used when waiting for the t32rem.exe to finish.
-        /// </summary>
-        private readonly int _f32WaitTimeoutMs;
-        
-        /// <summary>
-        /// Maximum number of attempts to locate and parse the .txt file.
-        /// </summary>
-        private readonly uint _maxAttempts;
-        
-        /// <summary>
-        /// Period (how often) the application tries to locate and parse the .txt file.
-        /// </summary>
-        private readonly uint _waitPeriodMs;
-        
-        /// <summary>
-        /// Path to the .txt file which is generated from the debugger.
-        /// </summary>
-        private readonly string _infoFilePath;
-
-        /// <summary>
-        /// Instance of ProcessUtils which encapsulates common functionality
-        /// when it comes to dealing with processes (limited by the needs of this application).
-        /// </summary>
-        public IProcessUtils ProcessUtils;
-        
-        /// <summary>
-        /// Instance of FileUtils which encapsulates common functionality
-        /// when it comes to dealing with files (limited by the needs of this application).
-        /// </summary>
-        public IFileUtils FileUtils;
-
-        /// <summary>
-        /// Returns the head serial number of the debugger.
-        /// </summary>
-        public string HeadSerialNumber { get; set; } = UndefinedSerialNumber;
-        
-        /// <summary>
-        /// Returns the body serial number of the debugger.
-        /// </summary>
-        public string BodySerialNumber { get; set; } = UndefinedSerialNumber;
-        
-        /// <summary>
-        /// Creates an instance of this class.
-        /// </summary>
-        /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
-        /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
-        /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
-        /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param>
-        /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param>
-        /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param>
-        /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param>
-        public InfoFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
-            string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) {
-            // Store the parameters into the class variables.
-            _maxAttempts = maxAttempts;
-            _waitPeriodMs = waitPeriodMs;
-            _infoFilePath = infoFilePath;
-            _f32RemExecutable = f32RemExecutable;
-            _f32RemArguments = f32RemArguments;
-            _f32SuccessExitCode = f32SuccessExitCode;
-            _f32WaitTimeoutMs = f32WaitTimeoutMs;
-            
-            // Create an instance of ProcessUtils.
-            ProcessUtils = new ProcessUtils();
-            
-            // Create an instance of FileUtils.
-            FileUtils = new FileUtils();
-        }
-
-        /// <summary>
-        /// Fetches data from the debugger. It sends the commands defined
-        /// in the appsettings.json file to the debugger and tries to
-        /// parse the .txt (contains the serial numbers).
-        /// </summary>
-        /// <returns>True, if data was fetched successfully. False otherwise.</returns>
-        public async Task<bool> FetchDataAsync() {
-            Program.DefaultLogger.Info("Fetching data from the debugger.");
-            
-            // Send the commands to the debugger.
-            var success = SendRetrieveInfoCommands(_f32RemExecutable, _f32RemArguments, _f32SuccessExitCode, _f32WaitTimeoutMs);
-            
-            // Make sure that all commands were sent and executed successfully.
-            if (!success) {
-                Program.DefaultLogger.Error("Failed to fetch data from the debugger.");
-                return false;
-            }
-            
-            // Periodically try to parse the .txt file. 
-            for (var i = 0; i < _maxAttempts; i++) {
-                Program.DefaultLogger.Info($"{i}. attempt to parse the info file.");
-                
-                // Try to parse .txt file.
-                if (RetrieveDebuggerInfo(_infoFilePath)) {
-                    Program.DefaultLogger.Info($"Info file has been parsed successfully.");
-                    return true;
-                }
-                // Wait for a specified number of milliseconds.
-                await Task.Delay((int)_waitPeriodMs);
-            }
-            Program.DefaultLogger.Error("Failed to parse the into file. It may have not been created.");
-            return false;
-        }
-
-        /// <summary>
-        /// Tries to retrieve information from the debugger.
-        /// </summary>
-        /// <param name="filePath">path to the .txt file that contains all information</param>
-        /// <returns>True if the information was retrieved successfully. False, otherwise.</returns>
-        private bool RetrieveDebuggerInfo(string filePath) {
-            try {
-                // Read the content of the .txt file.
-                var fileContent = FileUtils.ReadFileAllLines(filePath).Aggregate("", (current, line) => $"{current}{line}\n");
-                
-                // Parse it (try to find the serial numbers)
-                var (headSerialNumber, bodySerialNumber) = DebuggerInfoParser.Parse(fileContent);
-                
-                // Store the serial numbers into class variables (properties)
-                HeadSerialNumber = headSerialNumber;
-                BodySerialNumber = bodySerialNumber;
-                
-                // Finally, delete the file.
-                File.Delete(filePath);
-            } catch (Exception exception) {
-                Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
-                return false;
-            }
-            return true;
-        }
-
-        /// <summary>
-        /// Sends commands to the debugger.
-        /// </summary>
-        /// <param name="executableFile">Path to the t32rem.exe file</param>
-        /// <param name="arguments">Arguments sent to the debugger through t32rem.exe (one argument is one command)</param>
-        /// <param name="desiredExitCode">Status code indicating successful termination of t32rem.exe</param>
-        /// <param name="waitTimeoutMs">Timeout used when waiting for t32rem.exe to finish</param>
-        /// <returns>True if all the commands were executed successfully. False, otherwise.</returns>
-        private bool SendRetrieveInfoCommands(string executableFile, IReadOnlyList<string>? arguments, int desiredExitCode, int waitTimeoutMs) {
-            if (arguments == null) {
-                Program.DefaultLogger.Error($"Failed to run {executableFile} - no parameters were given");
-                return false;
-            }
-            // Execute one all arguments (commands) one by one.
-            foreach (var argument in arguments) {
-                if (!ProcessUtils.ExecuteNewProcess(executableFile, argument, waitTimeoutMs, desiredExitCode)) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-}
\ No newline at end of file
-- 
GitLab


From 6cde905ffbe816a629dfad1019221d2657874270 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 12:50:38 +0200
Subject: [PATCH 55/67] re #9712 Added t32 api fetcher

---
 ld_client/LDClient/detection/T32ApiFetcher.cs | 103 ++++++++++++++++++
 ld_client/LDClient/detection/T32RemFetcher.cs |  72 ++++++++++++
 2 files changed, 175 insertions(+)
 create mode 100644 ld_client/LDClient/detection/T32ApiFetcher.cs
 create mode 100644 ld_client/LDClient/detection/T32RemFetcher.cs

diff --git a/ld_client/LDClient/detection/T32ApiFetcher.cs b/ld_client/LDClient/detection/T32ApiFetcher.cs
new file mode 100644
index 0000000..50a5deb
--- /dev/null
+++ b/ld_client/LDClient/detection/T32ApiFetcher.cs
@@ -0,0 +1,103 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LDClient.detection {
+
+    public class T32ApiFetcher : AInfoFetcher, IT32Utils {
+#if _WINDOWS
+        private const string T32DllLibrary = "./lib/t32api64.dll";
+#else
+        private const string T32DllLibrary = "./lib/t32api64.so";
+#endif
+
+        private readonly string _t32Address;
+        private readonly string _t32Port;
+        private readonly string _t32PacketLength;
+        private readonly string[] _commands;
+
+        public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, 
+            string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) {
+            this._t32Address = t32Address;
+            this._t32Port = t32Port;
+            this._t32PacketLength = t32PacketLength;
+            this._commands = commands;
+        }
+
+
+        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+        private static extern int T32_Config(string s1, string s2);
+
+        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+        private static extern int T32_Init();
+
+        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+        private static extern int T32_Attach(int dev);
+
+        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+        private static extern int T32_Cmd(string command);
+
+        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+        private static extern int T32_Exit();
+        
+        public bool InitConnection() {
+            Program.DefaultLogger.Debug("Trace32 connection initialization");
+            var config1 = T32_Config("NODE=", _t32Address);
+            var config2 = T32_Config("PORT=", _t32Port);
+            var config3 = T32_Config("PACKLEN=", _t32PacketLength);
+
+            if (config1 != 0 || config2 != 0 || config3 != 0) {
+                Program.DefaultLogger.Error("Trace32 API connection configuration failed.");
+                return false;
+            }
+            var init = T32_Init();
+            if (init != 0) {
+                Program.DefaultLogger.Error("Trace32 API connection init failed.");
+                return false;
+            }
+
+            var attach = T32_Attach(1);
+            if (attach != 0) {
+                Program.DefaultLogger.Error("Trace32 API connection attach failed.");
+            }
+
+            Program.DefaultLogger.Info("Trace32 connection established");
+            return true;
+        }
+
+        public bool ExecuteCommands() {
+            Program.DefaultLogger.Info("Trace32 API commands execution.");
+            foreach (var command in _commands) {
+                Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'.");
+                var ret = T32_Cmd(command);
+                if (ret != 0) {
+                    Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}.");
+                    return false;
+                }
+            }
+            Program.DefaultLogger.Info("All Trace32 commands executed successfully.");
+            return true;
+        }
+
+        public bool CloseConnection() {
+            Program.DefaultLogger.Debug("Trace32 connection exit");
+            return T32_Exit() == 0;
+        }
+
+        protected override bool FetchData() {
+            var connected = false;
+            for (var i = 0; i < _maxAttempts; i++) {
+                connected = InitConnection();
+                if (connected) {
+                    break;
+                }
+                Thread.Sleep((int)_waitPeriodMs);
+
+            }
+            return connected && ExecuteCommands() && CloseConnection();
+        }
+    }
+}
diff --git a/ld_client/LDClient/detection/T32RemFetcher.cs b/ld_client/LDClient/detection/T32RemFetcher.cs
new file mode 100644
index 0000000..30dbeb0
--- /dev/null
+++ b/ld_client/LDClient/detection/T32RemFetcher.cs
@@ -0,0 +1,72 @@
+using System.Diagnostics;
+using LDClient.utils;
+using LDClient.utils.loggers;
+
+namespace LDClient.detection {
+
+    public class T32RemFetcher : AInfoFetcher{
+
+        /// <summary>
+        /// Path to the t32rem.exe file which is used to send commands to the debugger.
+        /// </summary>
+        private readonly string _f32RemExecutable;
+
+        /// <summary>
+        /// Arguments (commands) sent to the debugger in order to generate a .txt file
+        /// containing all the desired information.
+        /// </summary>
+        private readonly string[] _f32RemArguments;
+
+        /// <summary>
+        /// Status code indicating a successful termination of t32rem.exe
+        /// </summary>
+        private readonly int _f32SuccessExitCode;
+
+
+        /// <summary>
+        /// Timeout used when waiting for the t32rem.exe to finish.
+        /// </summary>
+        private readonly int _f32WaitTimeoutMs;
+
+        /// <summary>
+        /// Instance of ProcessUtils which encapsulates common functionality
+        /// when it comes to dealing with processes (limited by the needs of this application).
+        /// </summary>
+        public IProcessUtils ProcessUtils;
+
+        /// <summary>
+        /// Creates an instance of this class.
+        /// </summary>
+        /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
+        /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
+        /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
+        /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param>
+        /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param>
+        /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param>
+        /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param>
+
+        public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
+            string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) {
+            _f32RemExecutable = f32RemExecutable;
+            _f32RemArguments = f32RemArguments;
+            _f32SuccessExitCode = f32SuccessExitCode;
+            _f32WaitTimeoutMs = f32WaitTimeoutMs;
+            ProcessUtils = new ProcessUtils();
+
+        }
+
+        protected override bool FetchData() {
+            if (_f32RemArguments == null) {
+                Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given");
+                return false;
+            }
+            // Execute one all arguments (commands) one by one.
+            foreach (var argument in _f32RemArguments) {
+                if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+}
\ No newline at end of file
-- 
GitLab


From d49f4d79d28ae98f65c8a4bcaa354e2b6d181f23 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 12:52:57 +0200
Subject: [PATCH 56/67] re #9712 main new info fetcher redefinition

---
 ld_client/LDClient/Program.cs | 27 ++++++++++++++++++++++-----
 1 file changed, 22 insertions(+), 5 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 98a61b2..04c6099 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -33,20 +33,37 @@ internal static class Program {
     /// Instance of an API client.
     /// </summary>
     private static IApiClient? DefaultApiClient { get; set; }
-    
+
+    /*
+
+    It is possible to use previous info fetching method
+
     /// <summary>
     /// Instance of an info fetcher.
     /// </summary>
-    private static readonly InfoFetcher InfoFetcher = new(
+    private static readonly IInfoFetcher InfoFetcher = new(
         Config.FetchInfoMaxAttempts,
         Config.FetchInfoAttemptPeriod,
         Config.T32InfoLocation,
-        Config.F32RemExecutable,
-        Config.F32RemArguments,
+        Config.T32RemExecutable,
+        Config.T32RemArguments,
         Config.T32RemSuccessExitCode,
         Config.T32RemWaitTimeoutMs
     );
-    
+    */
+    /// <summary>
+    /// Instance of an info fetcher
+    /// </summary>
+    private static readonly IInfoFetcher InfoFetcher = new T32ApiFetcher(
+        Config.FetchInfoMaxAttempts,
+        Config.FetchInfoAttemptPeriod,
+        Config.T32InfoLocation,
+        Config.T32ApiAddress,
+        Config.T32ApiPort,
+        Config.T32ApiPacketLen,
+        Config.T32ApiCommands
+    );
+
     /// <summary>
     /// The main entry pint of the application.
     /// </summary>
-- 
GitLab


From e6a01bd8a1f18450fab43c329b955876f4aea7d6 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 13:25:41 +0200
Subject: [PATCH 57/67] re #9712 Added documentation of the newly implemented
 methods + refactoring

---
 ld_client/LDClient/detection/AInfoFetcher.cs  |   7 +-
 .../LDClient/detection/DebuggerInfoParser.cs  |  59 ++--
 ld_client/LDClient/detection/IInfoFetcher.cs  |  49 ++-
 .../LDClient/detection/IProcessDetection.cs   |  25 +-
 ld_client/LDClient/detection/IProcessUtils.cs |  51 ++-
 ld_client/LDClient/detection/IT32Utils.cs     |  38 ++-
 .../LDClient/detection/ProcessDetection.cs    | 304 +++++++++---------
 ld_client/LDClient/detection/ProcessUtils.cs  |  94 +++---
 ld_client/LDClient/detection/T32ApiFetcher.cs | 232 ++++++++-----
 ld_client/LDClient/detection/T32RemFetcher.cs | 111 ++++---
 ld_client/LDClient/utils/ConfigLoader.cs      |  26 +-
 11 files changed, 530 insertions(+), 466 deletions(-)

diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs
index c41f581..bdacb4a 100644
--- a/ld_client/LDClient/detection/AInfoFetcher.cs
+++ b/ld_client/LDClient/detection/AInfoFetcher.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using LDClient.utils;
+using LDClient.utils;
 
 namespace LDClient.detection; 
 
diff --git a/ld_client/LDClient/detection/DebuggerInfoParser.cs b/ld_client/LDClient/detection/DebuggerInfoParser.cs
index 27b80c6..a4cdee7 100644
--- a/ld_client/LDClient/detection/DebuggerInfoParser.cs
+++ b/ld_client/LDClient/detection/DebuggerInfoParser.cs
@@ -1,41 +1,40 @@
 using System.Text.RegularExpressions;
 
-namespace LDClient.detection {
+namespace LDClient.detection; 
+
+/// <summary>
+/// This class parses the .txt file generated from the debugger.
+/// Its primary interest is to find two serial numbers (head + body). 
+/// </summary>
+public static class DebuggerInfoParser {
 
     /// <summary>
-    /// This class parses the .txt file generated from the debugger.
-    /// Its primary interest is to find two serial numbers (head + body). 
+    /// Number of serial numbers expected to be in the .txt file (number of matches - regex).
     /// </summary>
-    public static class DebuggerInfoParser {
-
-        /// <summary>
-        /// Number of serial numbers expected to be in the .txt file (number of matches - regex).
-        /// </summary>
-        private const int ExpectedNumberOfMatches = 2;
+    private const int ExpectedNumberOfMatches = 2;
         
-        /// <summary>
-        /// Regular expression used to find the serial numbers.
-        /// </summary>
-        private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)");
+    /// <summary>
+    /// Regular expression used to find the serial numbers.
+    /// </summary>
+    private static readonly Regex SerialNumberRegex = new("(?<=Serial Number: )(.*)");
         
-        /// <summary>
-        /// Takes the content of a .txt file and tries to find the two serial numbers (head and body).
-        /// If it succeed, it will return the two numbers.
-        /// </summary>
-        /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param>
-        /// <returns>two serial numbers (head and body) of the debugger</returns>
-        /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception>
-        public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) {
-            // Find all matches in the content of the file that satisfy the regular expression.
-            var matches = SerialNumberRegex.Matches(dataTxt);
+    /// <summary>
+    /// Takes the content of a .txt file and tries to find the two serial numbers (head and body).
+    /// If it succeed, it will return the two numbers.
+    /// </summary>
+    /// <param name="dataTxt">the content of a .txt file (generated from the debugger)</param>
+    /// <returns>two serial numbers (head and body) of the debugger</returns>
+    /// <exception cref="ArgumentException">throws an exception if it fails to find the serial numbers</exception>
+    public static (string headSerialNumber, string bodySerialNumber) Parse(string dataTxt) {
+        // Find all matches in the content of the file that satisfy the regular expression.
+        var matches = SerialNumberRegex.Matches(dataTxt);
 
-            // Make sure an exact number of matches has been found.
-            if (matches.Count != ExpectedNumberOfMatches) {
-                throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})");
-            }
-            
-            // Return the two serial numbers (head and body).
-            return (matches[1].ToString().Trim(), matches[0].ToString().Trim());
+        // Make sure an exact number of matches has been found.
+        if (matches.Count != ExpectedNumberOfMatches) {
+            throw new ArgumentException($"Expected {ExpectedNumberOfMatches} matches to be found in the text (actually found: {matches.Count})");
         }
+            
+        // Return the two serial numbers (head and body).
+        return (matches[1].ToString().Trim(), matches[0].ToString().Trim());
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IInfoFetcher.cs b/ld_client/LDClient/detection/IInfoFetcher.cs
index f8c47a3..c5e871f 100644
--- a/ld_client/LDClient/detection/IInfoFetcher.cs
+++ b/ld_client/LDClient/detection/IInfoFetcher.cs
@@ -1,33 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace LDClient.detection; 
+
+/// <summary>
+/// This interface defines the functionality of an info fetcher which
+/// takes care of sending commands to the debugger. 
+/// </summary>
+public interface IInfoFetcher {
 
-namespace LDClient.detection {
-    
     /// <summary>
-    /// This interface defines the functionality of an info fetcher which
-    /// takes care of sending commands to the debugger. 
+    /// Returns the head serial number of the debugger.
     /// </summary>
-    public interface IInfoFetcher {
-
-        /// <summary>
-        /// Returns the head serial number of the debugger.
-        /// </summary>
-        public string HeadSerialNumber { get; set; }
+    public string HeadSerialNumber { get; set; }
         
-        /// <summary>
-        /// Returns the body serial number of the debugger.
-        /// </summary>
-        public string BodySerialNumber { get; set; }
+    /// <summary>
+    /// Returns the body serial number of the debugger.
+    /// </summary>
+    public string BodySerialNumber { get; set; }
 
-        /// <summary>
-        /// Fetches data from the debugger. It sends the commands defined
-        /// in the appsettings.json file to the debugger and tries to
-        /// parse the .txt (contains the serial numbers).
-        /// </summary>
-        /// <returns>True, if data was fetched successfully. False otherwise.</returns>
-        public Task<bool> FetchDataAsync();
-    }
-}
+    /// <summary>
+    /// Fetches data from the debugger. It sends the commands defined
+    /// in the appsettings.json file to the debugger and tries to
+    /// parse the .txt (contains the serial numbers).
+    /// </summary>
+    /// <returns>True, if data was fetched successfully. False otherwise.</returns>
+    public Task<bool> FetchDataAsync();
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IProcessDetection.cs b/ld_client/LDClient/detection/IProcessDetection.cs
index 27383f5..03a2398 100644
--- a/ld_client/LDClient/detection/IProcessDetection.cs
+++ b/ld_client/LDClient/detection/IProcessDetection.cs
@@ -1,16 +1,15 @@
-namespace LDClient.detection {
-    
+namespace LDClient.detection; 
+
+/// <summary>
+/// This interface defines the functionality of a process detector.
+/// A process detector is used to determine whether a user is currently
+/// using a debugger or not.
+/// </summary>
+internal interface IProcessDetection {
+        
     /// <summary>
-    /// This interface defines the functionality of a process detector.
-    /// A process detector is used to determine whether a user is currently
-    /// using a debugger or not.
+    /// Periodically runs process detection. This method is instantiated
+    /// as a thread from the main class (Program.cs).
     /// </summary>
-    internal interface IProcessDetection {
-        
-        /// <summary>
-        /// Periodically runs process detection. This method is instantiated
-        /// as a thread from the main class (Program.cs).
-        /// </summary>
-        public void RunPeriodicDetection();
-    }
+    public void RunPeriodicDetection();
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IProcessUtils.cs b/ld_client/LDClient/detection/IProcessUtils.cs
index d55a663..6759e14 100644
--- a/ld_client/LDClient/detection/IProcessUtils.cs
+++ b/ld_client/LDClient/detection/IProcessUtils.cs
@@ -1,33 +1,26 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace LDClient.detection; 
 
-namespace LDClient.detection {
-    
+/// <summary>
+/// This interface defines the functionality of all methods that
+/// are used to work with processes (within this project).
+/// </summary>
+public interface IProcessUtils {
+        
     /// <summary>
-    /// This interface defines the functionality of all methods that
-    /// are used to work with processes (within this project).
+    /// Checks if a process is running or not.
     /// </summary>
-    public interface IProcessUtils {
-        
-        /// <summary>
-        /// Checks if a process is running or not.
-        /// </summary>
-        /// <param name="name">Name of the process</param>
-        /// <returns>True, if the process is running. False otherwise.</returns>
-        public bool IsProcessRunning(string name);
+    /// <param name="name">Name of the process</param>
+    /// <returns>True, if the process is running. False otherwise.</returns>
+    public bool IsProcessRunning(string name);
 
-        /// <summary>
-        /// Executes a new process (t32rem.exe) with arguments which are passed in
-        /// as a parameter of the method.
-        /// </summary>
-        /// <param name="fileName">Path to the .exe file</param>
-        /// <param name="argument">Arguments passed into the .exe file</param>
-        /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
-        /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
-        /// <returns>True, if the command was executed successfully. False otherwise.</returns>
-        public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode);
-    }
-}
+    /// <summary>
+    /// Executes a new process (t32rem.exe) with arguments which are passed in
+    /// as a parameter of the method.
+    /// </summary>
+    /// <param name="fileName">Path to the .exe file</param>
+    /// <param name="argument">Arguments passed into the .exe file</param>
+    /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
+    /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
+    /// <returns>True, if the command was executed successfully. False otherwise.</returns>
+    public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode);
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/IT32Utils.cs b/ld_client/LDClient/detection/IT32Utils.cs
index 5904691..f33fb29 100644
--- a/ld_client/LDClient/detection/IT32Utils.cs
+++ b/ld_client/LDClient/detection/IT32Utils.cs
@@ -1,15 +1,29 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+namespace LDClient.detection;
 
-namespace LDClient.detection {
-    public interface IT32Utils {
 
-        public bool InitConnection();
-        public bool ExecuteCommands();
-        public bool CloseConnection();
+/// <summary>
+/// This interface defines the main functionality of an trace32 API
+/// which is mainly used to send commands to the debugger. 
+/// </summary>
+public interface IT32Utils {
+    
+    /// <summary>
+    /// This method initialized the connection with the trace32 application API.
+    /// It setups the standard connection configuration a tries to connect to the API
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool InitConnection();
 
-    }
-}
+    /// <summary>
+    /// Method executes all passed commands though the trace32 API
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool ExecuteCommands();
+
+    /// <summary>
+    /// This method closes the connection with the trace32 application api
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool CloseConnection();
+
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
index 4bde0fd..af47b38 100644
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -1,185 +1,183 @@
-using System.Diagnostics;
-using LDClient.network;
+using LDClient.network;
 using LDClient.network.data;
 
-namespace LDClient.detection {
+namespace LDClient.detection; 
+
+/// <summary>
+/// This class takes care of process detection. When t32mtc (process)
+/// is detected, it means that the debugger is currently being used.
+/// The class keeps track of the current state of a debugger.
+/// </summary>
+public sealed class ProcessDetection : IProcessDetection {
 
     /// <summary>
-    /// This class takes care of process detection. When t32mtc (process)
-    /// is detected, it means that the debugger is currently being used.
-    /// The class keeps track of the current state of a debugger.
+    /// Datetime format used when sending payloads to the server.
     /// </summary>
-    public sealed class ProcessDetection : IProcessDetection {
-
-        /// <summary>
-        /// Datetime format used when sending payloads to the server.
-        /// </summary>
-        private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
+    private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
 
-        /// <summary>
-        /// Name of the process the application detects.
-        /// </summary>
-        private readonly string _processName;
+    /// <summary>
+    /// Name of the process the application detects.
+    /// </summary>
+    private readonly string _processName;
         
-        /// <summary>
-        /// How often the application check the current status of the process (cunning / not running).
-        /// </summary>
-        private readonly uint _detectionPeriodMs;
+    /// <summary>
+    /// How often the application check the current status of the process (cunning / not running).
+    /// </summary>
+    private readonly uint _detectionPeriodMs;
         
-        /// <summary>
-        /// Instance of InfoFetcher used to fetch information from the debugger
-        /// (when the process is detected).
-        /// </summary>
-        private readonly IInfoFetcher _infoFetcher;
+    /// <summary>
+    /// Instance of InfoFetcher used to fetch information from the debugger
+    /// (when the process is detected).
+    /// </summary>
+    private readonly IInfoFetcher _infoFetcher;
         
-        /// <summary>
-        /// Instance of API clients used for sending data off to the server.
-        /// </summary>
-        private readonly IApiClient _apiClient;
+    /// <summary>
+    /// Instance of API clients used for sending data off to the server.
+    /// </summary>
+    private readonly IApiClient _apiClient;
         
-        /// <summary>
-        /// Instance of ProcessUtils which encapsulates common functionality
-        /// when it comes to dealing with processes (limited by the needs of this application).
-        /// </summary>
-        private readonly IProcessUtils _processUtils;
+    /// <summary>
+    /// Instance of ProcessUtils which encapsulates common functionality
+    /// when it comes to dealing with processes (limited by the needs of this application).
+    /// </summary>
+    private readonly IProcessUtils _processUtils;
 
-        /// <summary>
-        /// Flag indicating whether the process is currently running or not.
-        /// </summary>
-        private bool _processIsActive;
+    /// <summary>
+    /// Flag indicating whether the process is currently running or not.
+    /// </summary>
+    private bool _processIsActive;
         
-        /// <summary>
-        /// Flag if the application failed to retrieve data when the process was detected.
-        /// </summary>
-        private bool _failedToRetrieveData;
+    /// <summary>
+    /// Flag if the application failed to retrieve data when the process was detected.
+    /// </summary>
+    private bool _failedToRetrieveData;
         
-        /// <summary>
-        /// Last payload that was sent to the server.
-        /// </summary>
-        private Payload? _lastConnectedPayload;
+    /// <summary>
+    /// Last payload that was sent to the server.
+    /// </summary>
+    private Payload? _lastConnectedPayload;
 
-        /// <summary>
-        /// Flag used to stop the thread (process detection).
-        /// </summary>
-        public bool DetectionRunning = false;
+    /// <summary>
+    /// Flag used to stop the thread (process detection).
+    /// </summary>
+    public bool DetectionRunning = false;
         
-        /// <summary>
-        /// Creates an instance of this class.
-        /// </summary>
-        /// <param name="processName">Name of the process the application detects</param>
-        /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param>
-        /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param>
-        /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
-        /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
-        public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
-            IApiClient apiClient, IProcessUtils processUtils) {
-            _processName = processName;
-            _detectionPeriodMs = detectionPeriodMs;
-            _infoFetcher = infoFetcher;
-            _apiClient = apiClient;
-            _failedToRetrieveData = false;
-            _processUtils = processUtils;
-        }
+    /// <summary>
+    /// Creates an instance of this class.
+    /// </summary>
+    /// <param name="processName">Name of the process the application detects</param>
+    /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param>
+    /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param>
+    /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
+    /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
+    public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
+        IApiClient apiClient, IProcessUtils processUtils) {
+        _processName = processName;
+        _detectionPeriodMs = detectionPeriodMs;
+        _infoFetcher = infoFetcher;
+        _apiClient = apiClient;
+        _failedToRetrieveData = false;
+        _processUtils = processUtils;
+    }
 
-        /// <summary>
-        /// Retrieves data from the debugger.
-        /// </summary>
-        /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
-        private async Task<bool> RetrieveDataFromDebugger() {
-            // Try to fetch data from the debugger.
-            var success = await _infoFetcher.FetchDataAsync();
+    /// <summary>
+    /// Retrieves data from the debugger.
+    /// </summary>
+    /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
+    private async Task<bool> RetrieveDataFromDebugger() {
+        // Try to fetch data from the debugger.
+        var success = await _infoFetcher.FetchDataAsync();
             
-            // If the data was fetched successfully, send a payload off to the server.
-            if (success) {
-                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
-                    _infoFetcher.BodySerialNumber, DatetimeFormat);
-            }
-            return success;
+        // If the data was fetched successfully, send a payload off to the server.
+        if (success) {
+            _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
+                _infoFetcher.BodySerialNumber, DatetimeFormat);
         }
+        return success;
+    }
 
-        /// <summary>
-        /// Sends a payload to the server when a debugger gets disconnected.
-        /// </summary>
-        private async Task DebuggerDisconnected() {
-            // Make sure the debugger was connected in the first place.
-            if (_lastConnectedPayload is not null) {
-                // Update the status and timestamp of the last payload
-                // (the serial numbers remain the same).
-                _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
-                _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
+    /// <summary>
+    /// Sends a payload to the server when a debugger gets disconnected.
+    /// </summary>
+    private async Task DebuggerDisconnected() {
+        // Make sure the debugger was connected in the first place.
+        if (_lastConnectedPayload is not null) {
+            // Update the status and timestamp of the last payload
+            // (the serial numbers remain the same).
+            _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
+            _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
                 
-                // Send the data to the server.
-                await _apiClient.SendPayloadAsync(_lastConnectedPayload);
+            // Send the data to the server.
+            await _apiClient.SendPayloadAsync(_lastConnectedPayload);
                 
-                // Clear the last payload.
-                _lastConnectedPayload = null;
-            }
+            // Clear the last payload.
+            _lastConnectedPayload = null;
         }
+    }
 
-        /// <summary>
-        /// Checks if the t32mtc process is running or not. 
-        /// </summary>
-        private async Task DetectProcessAsync() {
-            // Check if the process is running.
-            var processExists = _processUtils.IsProcessRunning(_processName);
+    /// <summary>
+    /// Checks if the t32mtc process is running or not. 
+    /// </summary>
+    private async Task DetectProcessAsync() {
+        // Check if the process is running.
+        var processExists = _processUtils.IsProcessRunning(_processName);
 
-            // Check if the process was not running but now it is (flip flop ON). 
-            if (processExists && !_processIsActive) {
-                Program.DefaultLogger.Info($"Process started: {_processName}");
-                if (!_failedToRetrieveData) {
-                    _failedToRetrieveData = !await RetrieveDataFromDebugger();
-                }
-            }
-            // Check if the process was running but now it is not (fli flop OFF).
-            else if (!processExists && _processIsActive) {
-                Program.DefaultLogger.Info($"Process stopped: {_processName}");
-                _failedToRetrieveData = false;
-                await DebuggerDisconnected();
+        // Check if the process was not running but now it is (flip flop ON). 
+        if (processExists && !_processIsActive) {
+            Program.DefaultLogger.Info($"Process started: {_processName}");
+            if (!_failedToRetrieveData) {
+                _failedToRetrieveData = !await RetrieveDataFromDebugger();
             }
-
-            // Keep track of the current state of the debugger.
-            _processIsActive = processExists;
+        }
+        // Check if the process was running but now it is not (fli flop OFF).
+        else if (!processExists && _processIsActive) {
+            Program.DefaultLogger.Info($"Process stopped: {_processName}");
+            _failedToRetrieveData = false;
+            await DebuggerDisconnected();
         }
 
-        /// <summary>
-        /// Creates a payload and sends it to the server.
-        /// </summary>
-        /// <param name="headSerialNumber">serial number of the head of the debugger</param>
-        /// <param name="bodySerialNumber">serial number of the body of the debugger</param>
-        /// <param name="datetimeFormat">datetime format (timestamp)</param>
-        /// <returns>the newly-created payload</returns>
-        private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
-            // Create a new payload. 
-            Payload payload = new() {
-                UserName = Environment.UserName,
-                HostName = Environment.MachineName,
-                TimeStamp = DateTime.Now.ToString(datetimeFormat),
-                HeadDevice = new DebuggerInfo {
-                    SerialNumber = headSerialNumber
-                },
-                BodyDevice = new DebuggerInfo {
-                    SerialNumber = bodySerialNumber
-                },
-                Status = ConnectionStatus.Connected
-            };
+        // Keep track of the current state of the debugger.
+        _processIsActive = processExists;
+    }
+
+    /// <summary>
+    /// Creates a payload and sends it to the server.
+    /// </summary>
+    /// <param name="headSerialNumber">serial number of the head of the debugger</param>
+    /// <param name="bodySerialNumber">serial number of the body of the debugger</param>
+    /// <param name="datetimeFormat">datetime format (timestamp)</param>
+    /// <returns>the newly-created payload</returns>
+    private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
+        // Create a new payload. 
+        Payload payload = new() {
+            UserName = Environment.UserName,
+            HostName = Environment.MachineName,
+            TimeStamp = DateTime.Now.ToString(datetimeFormat),
+            HeadDevice = new DebuggerInfo {
+                SerialNumber = headSerialNumber
+            },
+            BodyDevice = new DebuggerInfo {
+                SerialNumber = bodySerialNumber
+            },
+            Status = ConnectionStatus.Connected
+        };
             
-            // Send it to the server and return it.
-            await _apiClient.SendPayloadAsync(payload);
-            return payload;
-        }
+        // Send it to the server and return it.
+        await _apiClient.SendPayloadAsync(payload);
+        return payload;
+    }
 
-        /// <summary>
-        /// Periodically runs process detection. This method is instantiated
-        /// as a thread from the main class (Program.cs).
-        /// </summary>
-        public async void RunPeriodicDetection() {
-            Program.DefaultLogger.Info("Process periodic detector has started");
-            DetectionRunning = true;
+    /// <summary>
+    /// Periodically runs process detection. This method is instantiated
+    /// as a thread from the main class (Program.cs).
+    /// </summary>
+    public async void RunPeriodicDetection() {
+        Program.DefaultLogger.Info("Process periodic detector has started");
+        DetectionRunning = true;
             
-            while (DetectionRunning) {
-                await DetectProcessAsync();
-                Thread.Sleep((int) _detectionPeriodMs);
-            }
+        while (DetectionRunning) {
+            await DetectProcessAsync();
+            Thread.Sleep((int) _detectionPeriodMs);
         }
     }
-}
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/ProcessUtils.cs b/ld_client/LDClient/detection/ProcessUtils.cs
index 5c448e7..af52955 100644
--- a/ld_client/LDClient/detection/ProcessUtils.cs
+++ b/ld_client/LDClient/detection/ProcessUtils.cs
@@ -1,60 +1,54 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
+using System.Diagnostics;
+
+namespace LDClient.detection; 
+
+/// <summary>
+/// This class implements the IProcessUtils interface.
+/// It implements methods that are used when dealing with processes.
+/// </summary>
+public class ProcessUtils : IProcessUtils {
 
-namespace LDClient.detection {
-    
     /// <summary>
-    /// This class implements the IProcessUtils interface.
-    /// It implements methods that are used when dealing with processes.
+    /// Checks if a process is running or not.
     /// </summary>
-    public class ProcessUtils : IProcessUtils {
-
-        /// <summary>
-        /// Checks if a process is running or not.
-        /// </summary>
-        /// <param name="name">Name of the process</param>
-        /// <returns>True, if the process is running. False otherwise.</returns>
-        public bool IsProcessRunning(string name) {
-            return Process.GetProcessesByName(name).Length > 0;
-        }
+    /// <param name="name">Name of the process</param>
+    /// <returns>True, if the process is running. False otherwise.</returns>
+    public bool IsProcessRunning(string name) {
+        return Process.GetProcessesByName(name).Length > 0;
+    }
         
-        /// <summary>
-        /// Executes a new process (t32rem.exe) with arguments which are passed in
-        /// as a parameter of the method.
-        /// </summary>
-        /// <param name="fileName">Path to the .exe file</param>
-        /// <param name="argument">Arguments passed into the .exe file</param>
-        /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
-        /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
-        /// <returns>True, if the command was executed successfully. False otherwise.</returns>
-        public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) {
-            // Create a new process.
-            var t32RemProcess = new Process();
-            t32RemProcess.StartInfo.FileName = fileName;
-            t32RemProcess.StartInfo.Arguments = argument;
+    /// <summary>
+    /// Executes a new process (t32rem.exe) with arguments which are passed in
+    /// as a parameter of the method.
+    /// </summary>
+    /// <param name="fileName">Path to the .exe file</param>
+    /// <param name="argument">Arguments passed into the .exe file</param>
+    /// <param name="timeout">Timeout used when waiting for the process to terminate</param>
+    /// <param name="desiredExitCode">Status code indicating a successful termination of the process.</param>
+    /// <returns>True, if the command was executed successfully. False otherwise.</returns>
+    public bool ExecuteNewProcess(string fileName, string argument, int timeout, int desiredExitCode) {
+        // Create a new process.
+        var t32RemProcess = new Process();
+        t32RemProcess.StartInfo.FileName = fileName;
+        t32RemProcess.StartInfo.Arguments = argument;
             
-            try {
-                // Execute the process and wait until it terminates or until the timeout is up.
-                t32RemProcess.Start();
-                if (!t32RemProcess.WaitForExit(timeout)) {
-                    Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms");
-                    return false;
-                }
+        try {
+            // Execute the process and wait until it terminates or until the timeout is up.
+            t32RemProcess.Start();
+            if (!t32RemProcess.WaitForExit(timeout)) {
+                Program.DefaultLogger.Error($"Execution has not terminated within a predefined timeout of {timeout} ms");
+                return false;
+            }
                 
-                // Check if the process terminated successfully.
-                if (t32RemProcess.ExitCode != desiredExitCode) {
-                    Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
-                    return false;
-                }
-            } catch (Exception exception) {
-                Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}");
+            // Check if the process terminated successfully.
+            if (t32RemProcess.ExitCode != desiredExitCode) {
+                Program.DefaultLogger.Error($"Execution terminated with an error code of {t32RemProcess.ExitCode}");
                 return false;
             }
-            return true;
+        } catch (Exception exception) {
+            Program.DefaultLogger.Error($"Failed to run {fileName} {argument}. {exception.Message}");
+            return false;
         }
+        return true;
     }
-}
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/T32ApiFetcher.cs b/ld_client/LDClient/detection/T32ApiFetcher.cs
index 50a5deb..893e95e 100644
--- a/ld_client/LDClient/detection/T32ApiFetcher.cs
+++ b/ld_client/LDClient/detection/T32ApiFetcher.cs
@@ -1,103 +1,167 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Runtime.InteropServices;
-using System.Text;
-using System.Threading.Tasks;
+using System.Runtime.InteropServices;
 
-namespace LDClient.detection {
+namespace LDClient.detection; 
 
-    public class T32ApiFetcher : AInfoFetcher, IT32Utils {
+public class T32ApiFetcher : AInfoFetcher, IT32Utils {
 #if _WINDOWS
-        private const string T32DllLibrary = "./lib/t32api64.dll";
+    /// <summary>
+    /// Path to the Trace32 API library
+    /// </summary>
+    private const string T32DllLibrary = "./lib/t32api64.dll";
 #else
         private const string T32DllLibrary = "./lib/t32api64.so";
 #endif
+    /// <summary>
+    /// Address of the listening t32 application
+    /// </summary>
+    private readonly string _t32Address;
+
+    /// <summary>
+    ///  Port of the listening t32 application
+    /// </summary>
+    private readonly string _t32Port;
+
+    /// <summary>
+    /// Size of the packets send/received from t32 application
+    /// </summary>
+    private readonly string _t32PacketLength;
+
+    /// <summary>
+    /// List of commands to be executed by though the t32 api
+    /// </summary>
+    private readonly string[] _commands;
+
+    /// <summary>
+    /// 
+    /// </summary>
+    /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
+    /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
+    /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
+    /// <param name="t32Address">Address of the listening t32 application</param>
+    /// <param name="t32Port">Port of the listening t32 application</param>
+    /// <param name="t32PacketLength"> Size of the packets send/received from t32 application </param>
+    /// <param name="commands"> List of commands to be executed by though the t32 api</param>
+    public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, 
+        string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) {
+        this._t32Address = t32Address;
+        this._t32Port = t32Port;
+        this._t32PacketLength = t32PacketLength;
+        this._commands = commands;
+    }
 
-        private readonly string _t32Address;
-        private readonly string _t32Port;
-        private readonly string _t32PacketLength;
-        private readonly string[] _commands;
-
-        public T32ApiFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string t32Address, 
-            string t32Port, string t32PacketLength, string[] commands) : base(maxAttempts, waitPeriodMs, infoFilePath) {
-            this._t32Address = t32Address;
-            this._t32Port = t32Port;
-            this._t32PacketLength = t32PacketLength;
-            this._commands = commands;
-        }
-
-
-        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
-        private static extern int T32_Config(string s1, string s2);
-
-        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
-        private static extern int T32_Init();
 
-        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
-        private static extern int T32_Attach(int dev);
+    /// <summary>
+    /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
+    /// </summary>
+    /// <param name="s1"></param>
+    /// <param name="s2"></param>
+    /// <returns>return code</returns>
+    [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+    private static extern int T32_Config(string s1, string s2);
+
+    /// <summary>
+    /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
+    /// </summary>
+    /// <returns>Return code</returns>
+    [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+    private static extern int T32_Init();
+
+    /// <summary>
+    /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
+    /// </summary>
+    /// <param name="dev"></param>
+    /// <returns>Return code</returns>
+    [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+    private static extern int T32_Attach(int dev);
+
+    /// <summary>
+    /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
+    /// </summary>
+    /// <param name="command"></param>
+    /// <returns>Return code</returns>
+    [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+    private static extern int T32_Cmd(string command);
+
+    /// <summary>
+    /// To see full documentation of following T32 API methods please check the https://www2.lauterbach.com/pdf/api_remote_c.pdf
+    /// </summary>
+    /// <returns>Return code</returns>
+    [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
+    private static extern int T32_Exit();
+
+
+    /// <summary>
+    /// This method initialized the connection with the trace32 application API.
+    /// It setups the standard connection configuration a tries to connect to the API
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool InitConnection() {
+        Program.DefaultLogger.Debug("Trace32 connection initialization");
+        var config1 = T32_Config("NODE=", _t32Address);
+        var config2 = T32_Config("PORT=", _t32Port);
+        var config3 = T32_Config("PACKLEN=", _t32PacketLength);
+
+        if (config1 != 0 || config2 != 0 || config3 != 0) {
+            Program.DefaultLogger.Error("Trace32 API connection configuration failed.");
+            return false;
+        }
+        var init = T32_Init();
+        if (init != 0) {
+            Program.DefaultLogger.Error("Trace32 API connection init failed.");
+            return false;
+        }
 
-        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
-        private static extern int T32_Cmd(string command);
+        var attach = T32_Attach(1);
+        if (attach != 0) {
+            Program.DefaultLogger.Error("Trace32 API connection attach failed.");
+        }
 
-        [DllImport(T32DllLibrary, CharSet = CharSet.Ansi)]
-        private static extern int T32_Exit();
-        
-        public bool InitConnection() {
-            Program.DefaultLogger.Debug("Trace32 connection initialization");
-            var config1 = T32_Config("NODE=", _t32Address);
-            var config2 = T32_Config("PORT=", _t32Port);
-            var config3 = T32_Config("PACKLEN=", _t32PacketLength);
+        Program.DefaultLogger.Info("Trace32 connection established");
+        return true;
+    }
 
-            if (config1 != 0 || config2 != 0 || config3 != 0) {
-                Program.DefaultLogger.Error("Trace32 API connection configuration failed.");
-                return false;
-            }
-            var init = T32_Init();
-            if (init != 0) {
-                Program.DefaultLogger.Error("Trace32 API connection init failed.");
+    /// <summary>
+    /// Method executes all passed commands though the trace32 API
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool ExecuteCommands() {
+        Program.DefaultLogger.Info("Trace32 API commands execution.");
+        foreach (var command in _commands) {
+            Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'.");
+            var ret = T32_Cmd(command);
+            if (ret != 0) {
+                Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}.");
                 return false;
             }
-
-            var attach = T32_Attach(1);
-            if (attach != 0) {
-                Program.DefaultLogger.Error("Trace32 API connection attach failed.");
-            }
-
-            Program.DefaultLogger.Info("Trace32 connection established");
-            return true;
-        }
-
-        public bool ExecuteCommands() {
-            Program.DefaultLogger.Info("Trace32 API commands execution.");
-            foreach (var command in _commands) {
-                Program.DefaultLogger.Debug($"Executing Trace32 command '{command}'.");
-                var ret = T32_Cmd(command);
-                if (ret != 0) {
-                    Program.DefaultLogger.Error($"Execution of command '{command}' failed. Return code {ret}.");
-                    return false;
-                }
-            }
-            Program.DefaultLogger.Info("All Trace32 commands executed successfully.");
-            return true;
-        }
-
-        public bool CloseConnection() {
-            Program.DefaultLogger.Debug("Trace32 connection exit");
-            return T32_Exit() == 0;
         }
+        Program.DefaultLogger.Info("All Trace32 commands executed successfully.");
+        return true;
+    }
 
-        protected override bool FetchData() {
-            var connected = false;
-            for (var i = 0; i < _maxAttempts; i++) {
-                connected = InitConnection();
-                if (connected) {
-                    break;
-                }
-                Thread.Sleep((int)_waitPeriodMs);
+    /// <summary>
+    /// This method closes the connection with the trace32 application api
+    /// </summary>
+    /// <returns>true on success</returns>
+    public bool CloseConnection() {
+        Program.DefaultLogger.Debug("Trace32 connection exit");
+        return T32_Exit() == 0;
+    }
 
+    /// <summary>
+    /// Method tries to fetch the data from the trace32 application.
+    /// Upon connection fail it tries again for specified number of times
+    /// </summary>
+    /// <returns>true on success</returns>
+    protected override bool FetchData() {
+        var connected = false;
+        for (var i = 0; i < _maxAttempts; i++) {
+            connected = InitConnection();
+            if (connected) {
+                break;
             }
-            return connected && ExecuteCommands() && CloseConnection();
+            Thread.Sleep((int)_waitPeriodMs);
+
         }
+        return connected && ExecuteCommands() && CloseConnection();
     }
-}
+}
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/T32RemFetcher.cs b/ld_client/LDClient/detection/T32RemFetcher.cs
index 30dbeb0..91bda8c 100644
--- a/ld_client/LDClient/detection/T32RemFetcher.cs
+++ b/ld_client/LDClient/detection/T32RemFetcher.cs
@@ -1,72 +1,71 @@
-using System.Diagnostics;
-using LDClient.utils;
-using LDClient.utils.loggers;
+namespace LDClient.detection; 
 
-namespace LDClient.detection {
+public class T32RemFetcher : AInfoFetcher{
 
-    public class T32RemFetcher : AInfoFetcher{
+    /// <summary>
+    /// Path to the t32rem.exe file which is used to send commands to the debugger.
+    /// </summary>
+    private readonly string _f32RemExecutable;
 
-        /// <summary>
-        /// Path to the t32rem.exe file which is used to send commands to the debugger.
-        /// </summary>
-        private readonly string _f32RemExecutable;
+    /// <summary>
+    /// Arguments (commands) sent to the debugger in order to generate a .txt file
+    /// containing all the desired information.
+    /// </summary>
+    private readonly string[] _f32RemArguments;
 
-        /// <summary>
-        /// Arguments (commands) sent to the debugger in order to generate a .txt file
-        /// containing all the desired information.
-        /// </summary>
-        private readonly string[] _f32RemArguments;
+    /// <summary>
+    /// Status code indicating a successful termination of t32rem.exe
+    /// </summary>
+    private readonly int _f32SuccessExitCode;
 
-        /// <summary>
-        /// Status code indicating a successful termination of t32rem.exe
-        /// </summary>
-        private readonly int _f32SuccessExitCode;
 
+    /// <summary>
+    /// Timeout used when waiting for the t32rem.exe to finish.
+    /// </summary>
+    private readonly int _f32WaitTimeoutMs;
 
-        /// <summary>
-        /// Timeout used when waiting for the t32rem.exe to finish.
-        /// </summary>
-        private readonly int _f32WaitTimeoutMs;
+    /// <summary>
+    /// Instance of ProcessUtils which encapsulates common functionality
+    /// when it comes to dealing with processes (limited by the needs of this application).
+    /// </summary>
+    public IProcessUtils ProcessUtils;
 
-        /// <summary>
-        /// Instance of ProcessUtils which encapsulates common functionality
-        /// when it comes to dealing with processes (limited by the needs of this application).
-        /// </summary>
-        public IProcessUtils ProcessUtils;
+    /// <summary>
+    /// Creates an instance of this class.
+    /// </summary>
+    /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
+    /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
+    /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
+    /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param>
+    /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param>
+    /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param>
+    /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param>
+    public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
+        string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) {
+        _f32RemExecutable = f32RemExecutable;
+        _f32RemArguments = f32RemArguments;
+        _f32SuccessExitCode = f32SuccessExitCode;
+        _f32WaitTimeoutMs = f32WaitTimeoutMs;
+        ProcessUtils = new ProcessUtils();
 
-        /// <summary>
-        /// Creates an instance of this class.
-        /// </summary>
-        /// <param name="maxAttempts">Maximum number of attempts to locate and parse the .txt file</param>
-        /// <param name="waitPeriodMs">Period (how often) the application tries to locate and parse the .txt file</param>
-        /// <param name="infoFilePath">Path to the .txt file which is generated from the debugger</param>
-        /// <param name="f32RemExecutable">Path to the t32rem.exe file which is used to send commands to the debugger</param>
-        /// <param name="f32RemArguments">Arguments (commands) sent to the debugger in order to generate a .txt file containing all the desired information.</param>
-        /// <param name="f32SuccessExitCode">Status code indicating a successful termination of t32rem.exe</param>
-        /// <param name="f32WaitTimeoutMs">Timeout used when waiting for the t32rem.exe to finish</param>
-
-        public T32RemFetcher(uint maxAttempts, uint waitPeriodMs, string infoFilePath, string f32RemExecutable,
-            string[] f32RemArguments, int f32SuccessExitCode, int f32WaitTimeoutMs) : base(maxAttempts, waitPeriodMs, infoFilePath) {
-            _f32RemExecutable = f32RemExecutable;
-            _f32RemArguments = f32RemArguments;
-            _f32SuccessExitCode = f32SuccessExitCode;
-            _f32WaitTimeoutMs = f32WaitTimeoutMs;
-            ProcessUtils = new ProcessUtils();
+    }
 
+    /// <summary>
+    /// Method tries to fetch the data from the trace32 application
+    /// via defined executable 
+    /// </summary>
+    /// <returns>true upon success</returns>
+    protected override bool FetchData() {
+        if (_f32RemArguments == null) {
+            Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given");
+            return false;
         }
-
-        protected override bool FetchData() {
-            if (_f32RemArguments == null) {
-                Program.DefaultLogger.Error($"Failed to run {_f32RemExecutable} - no parameters were given");
+        // Execute one all arguments (commands) one by one.
+        foreach (var argument in _f32RemArguments) {
+            if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) {
                 return false;
             }
-            // Execute one all arguments (commands) one by one.
-            foreach (var argument in _f32RemArguments) {
-                if (!ProcessUtils.ExecuteNewProcess(_f32RemExecutable, argument, _f32WaitTimeoutMs, _f32SuccessExitCode)) {
-                    return false;
-                }
-            }
-            return true;
         }
+        return true;
     }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index f585cce..3544c46 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -39,11 +39,6 @@ namespace LDClient.utils {
         private const string DdSection = "DebuggerDetection";
 
 
-        public string[] T32ApiCommands { get; private set; } = null!;
-        public string T32ApiAddress { get; private set; } = null!;
-        public string T32ApiPort { get; private set; } = null!;
-        public string T32ApiPacketLen { get; private set; } = null!;
-
         #region Logger
 
         /// <summary>
@@ -169,6 +164,27 @@ namespace LDClient.utils {
         /// </summary>
         public int T32RemWaitTimeoutMs { get; private set; }
 
+
+        /// <summary>
+        /// List of commands to be executed by though the t32 api
+        /// </summary>
+        public string[] T32ApiCommands { get; private set; } = null!;
+
+        /// <summary>
+        /// Address of the listening t32 application
+        /// </summary>
+        public string T32ApiAddress { get; private set; } = null!;
+
+        /// <summary>
+        /// Port of the listening t32 application
+        /// </summary>
+        public string T32ApiPort { get; private set; } = null!;
+
+        /// <summary>
+        /// Size of the packets send/received from t32 application
+        /// </summary>
+        public string T32ApiPacketLen { get; private set; } = null!;
+
         #endregion
 
         /// <summary>
-- 
GitLab


From 964ced30f4baafd27de935cc441139370c5e176b Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 13:27:01 +0200
Subject: [PATCH 58/67] re #9712 added tr32api dll

---
 ld_client/LDClient/lib/t32api64.dll | Bin 0 -> 250368 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 ld_client/LDClient/lib/t32api64.dll

diff --git a/ld_client/LDClient/lib/t32api64.dll b/ld_client/LDClient/lib/t32api64.dll
new file mode 100644
index 0000000000000000000000000000000000000000..45bed3b6a273e38e05df808560dcd9002e0e8ba5
GIT binary patch
literal 250368
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
aT!~a-?3Dz&MQ6X%*)d$;Uw{7TBJls)N99QX

literal 0
HcmV?d00001

-- 
GitLab


From 98bc5e43b474cf0d2971ff40ed90eab24b37444b Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Sun, 8 May 2022 13:32:03 +0200
Subject: [PATCH 59/67] re #9712 html doc generation

---
 ld_client/doc/pdoc/class_file_logger.html     |   2 +-
 ..._client_1_1detection_1_1_info_fetcher.html |   2 +-
 ...nt_1_1detection_1_1_process_detection.html |   2 +-
 ...client_1_1detection_1_1_process_utils.html |   2 +-
 ..._l_d_client_1_1network_1_1_api_client.html |   2 +-
 ...l_d_client_1_1network_1_1_http_client.html |   2 +-
 ..._1_1network_1_1data_1_1_debugger_info.html |   2 +-
 ...client_1_1network_1_1data_1_1_payload.html |   2 +-
 ...ss_l_d_client_1_1utils_1_1_file_utils.html |   2 +-
 ...ient_1_1utils_1_1loggers_1_1_a_logger.html |   2 +-
 ..._1utils_1_1loggers_1_1_console_logger.html |   2 +-
 .../dir_082f6a8deca2b2d1a7c77b6edd561a50.html |  99 ++++++++++++++++
 .../dir_3829590d4bc1496e3a509b2e3d199db3.html | 105 +++++++++++++++++
 .../dir_3ff60c654341cc744f8b6bad46bdfd33.html |  99 ++++++++++++++++
 .../dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html |  99 ++++++++++++++++
 .../dir_706db108f1db495156020bde23f92570.html | 105 +++++++++++++++++
 .../dir_760ce4e5796d28b3d0dd6e7840ecfe13.html |  99 ++++++++++++++++
 .../dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html | 105 +++++++++++++++++
 .../dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html | 109 ++++++++++++++++++
 .../dir_d13acb3f48e6aaa83bf47a5658d35ef4.html |  99 ++++++++++++++++
 .../dir_e995fcc46e5f182c24bd6fe0d90a742c.html |  99 ++++++++++++++++
 .../dir_eba1acdda5df661dbf6e514468df4101.html | 105 +++++++++++++++++
 .../dir_ebc798c9b1f11074fd71688d371864c0.html |  99 ++++++++++++++++
 ...lient_1_1detection_1_1_i_info_fetcher.html |   2 +-
 ...ient_1_1detection_1_1_i_process_utils.html |   2 +-
 ..._d_client_1_1network_1_1_i_api_client.html |   2 +-
 ...d_client_1_1network_1_1_i_http_client.html |   2 +-
 ..._l_d_client_1_1utils_1_1_i_file_utils.html |   2 +-
 28 files changed, 1238 insertions(+), 16 deletions(-)
 create mode 100644 ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html
 create mode 100644 ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html
 create mode 100644 ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html
 create mode 100644 ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html
 create mode 100644 ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html
 create mode 100644 ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html
 create mode 100644 ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html
 create mode 100644 ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html
 create mode 100644 ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html
 create mode 100644 ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html
 create mode 100644 ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html
 create mode 100644 ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html

diff --git a/ld_client/doc/pdoc/class_file_logger.html b/ld_client/doc/pdoc/class_file_logger.html
index a2ebfca..2de3c64 100644
--- a/ld_client/doc/pdoc/class_file_logger.html
+++ b/ld_client/doc/pdoc/class_file_logger.html
@@ -139,7 +139,7 @@ Protected Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>utils/loggers/FileLogger.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/FileLogger.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
index e719c11..d7ddd2e 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_info_fetcher.html
@@ -286,7 +286,7 @@ Properties</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>detection/InfoFetcher.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/InfoFetcher.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
index 7080b7a..107a82d 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_detection.html
@@ -173,7 +173,7 @@ bool&#160;</td><td class="memItemRight" valign="bottom"><b>DetectionRunning</b>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>detection/ProcessDetection.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/ProcessDetection.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
index 5bbf1df..dfeadef 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1detection_1_1_process_utils.html
@@ -195,7 +195,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>detection/ProcessUtils.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/ProcessUtils.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
index e8d1ec5..a3e8d6d 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_api_client.html
@@ -249,7 +249,7 @@ bool&#160;</td><td class="memItemRight" valign="bottom"><b>ClientRunning</b></td
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>network/ApiClient.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/ApiClient.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
index f885623..90e28a1 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1_http_client.html
@@ -165,7 +165,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>network/HttpClient.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/HttpClient.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
index f51c123..dd3362f 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_debugger_info.html
@@ -103,7 +103,7 @@ string?&#160;</td><td class="memItemRight" valign="bottom"><b>SerialNumber</b><c
 <a name="details" id="details"></a><h2 class="groupheader">Detailed Description</h2>
 <div class="textblock"><p >This class holds all the information about a specific part of a debugger (head/body). </p>
 </div><hr/>The documentation for this class was generated from the following file:<ul>
-<li>network/data/DebuggerInfo.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/data/DebuggerInfo.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
index 617cfb5..cf69e4d 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1network_1_1data_1_1_payload.html
@@ -216,7 +216,7 @@ string?&#160;</td><td class="memItemRight" valign="bottom"><b>TimeStamp</b><code
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>network/data/Payload.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/data/Payload.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
index 1d00aa1..fc1bb9e 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1_file_utils.html
@@ -135,7 +135,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>utils/FileUtils.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/FileUtils.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
index 09a6a5e..b592e10 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.html
@@ -380,7 +380,7 @@ static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.htm
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>utils/loggers/ALogger.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/ALogger.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
index 05a15b8..dbc5fbe 100644
--- a/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
+++ b/ld_client/doc/pdoc/class_l_d_client_1_1utils_1_1loggers_1_1_console_logger.html
@@ -179,7 +179,7 @@ static <a class="el" href="class_l_d_client_1_1utils_1_1loggers_1_1_a_logger.htm
 </div>
 </div>
 <hr/>The documentation for this class was generated from the following file:<ul>
-<li>utils/loggers/ConsoleLogger.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers/ConsoleLogger.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html b/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html
new file mode 100644
index 0000000..d3e9b32
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_082f6a8deca2b2d1a7c77b6edd561a50.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_082f6a8deca2b2d1a7c77b6edd561a50.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">obj Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html b/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html
new file mode 100644
index 0000000..3df66b7
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_3829590d4bc1496e3a509b2e3d199db3.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_3829590d4bc1496e3a509b2e3d199db3.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">ld_client Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html b/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html
new file mode 100644
index 0000000..f95438a
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_3ff60c654341cc744f8b6bad46bdfd33.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/utils/loggers Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_3ff60c654341cc744f8b6bad46bdfd33.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">loggers Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></li><li class="navelem"><a class="el" href="dir_3ff60c654341cc744f8b6bad46bdfd33.html">loggers</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html b/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html
new file mode 100644
index 0000000..920ca6f
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/detection Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">detection Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html">detection</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html b/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html
new file mode 100644
index 0000000..d1ce16c
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_706db108f1db495156020bde23f92570.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/network Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_706db108f1db495156020bde23f92570.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">network Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_760ce4e5796d28b3d0dd6e7840ecfe13.html">data</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html b/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html
new file mode 100644
index 0000000..3f7f15d
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_760ce4e5796d28b3d0dd6e7840ecfe13.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/network/data Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_760ce4e5796d28b3d0dd6e7840ecfe13.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">data Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></li><li class="navelem"><a class="el" href="dir_760ce4e5796d28b3d0dd6e7840ecfe13.html">data</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html b/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html
new file mode 100644
index 0000000..a03de9b
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/utils Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">utils Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_3ff60c654341cc744f8b6bad46bdfd33.html">loggers</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html b/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html
new file mode 100644
index 0000000..896e32e
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">LDClient Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_4c3ca6d7aeb2c237dc2aa04530b180a2.html">detection</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_706db108f1db495156020bde23f92570.html">network</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_8fe11425d4d91d0b901d0e1ac4a8df7f.html">utils</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html b/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html
new file mode 100644
index 0000000..9b27610
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_d13acb3f48e6aaa83bf47a5658d35ef4.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_d13acb3f48e6aaa83bf47a5658d35ef4.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">review Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html b/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html
new file mode 100644
index 0000000..e050ea2
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_e995fcc46e5f182c24bd6fe0d90a742c.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_e995fcc46e5f182c24bd6fe0d90a742c.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">aswi2022bug-thugs Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html b/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html
new file mode 100644
index 0000000..997200a
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_eba1acdda5df661dbf6e514468df4101.html
@@ -0,0 +1,105 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj/Debug Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_eba1acdda5df661dbf6e514468df4101.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">Debug Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+<table class="memberdecls">
+<tr class="heading"><td colspan="2"><h2 class="groupheader"><a id="subdirs" name="subdirs"></a>
+Directories</h2></td></tr>
+<tr class="memitem:"><td class="memItemLeft" align="right" valign="top">directory &#160;</td><td class="memItemRight" valign="bottom"><a class="el" href="dir_ebc798c9b1f11074fd71688d371864c0.html">net6.0</a></td></tr>
+<tr class="separator:"><td class="memSeparator" colspan="2">&#160;</td></tr>
+</table>
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li><li class="navelem"><a class="el" href="dir_eba1acdda5df661dbf6e514468df4101.html">Debug</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html b/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html
new file mode 100644
index 0000000..90e0b7c
--- /dev/null
+++ b/ld_client/doc/pdoc/dir_ebc798c9b1f11074fd71688d371864c0.html
@@ -0,0 +1,99 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
+<meta http-equiv="X-UA-Compatible" content="IE=11"/>
+<meta name="generator" content="Doxygen 1.9.4"/>
+<meta name="viewport" content="width=device-width, initial-scale=1"/>
+<title>LDClient: review/aswi2022bug-thugs/ld_client/LDClient/obj/Debug/net6.0 Directory Reference</title>
+<link href="tabs.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="jquery.js"></script>
+<script type="text/javascript" src="dynsections.js"></script>
+<link href="navtree.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="resize.js"></script>
+<script type="text/javascript" src="navtreedata.js"></script>
+<script type="text/javascript" src="navtree.js"></script>
+<link href="search/search.css" rel="stylesheet" type="text/css"/>
+<script type="text/javascript" src="search/searchdata.js"></script>
+<script type="text/javascript" src="search/search.js"></script>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+</head>
+<body>
+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
+<div id="titlearea">
+<table cellspacing="0" cellpadding="0">
+ <tbody>
+ <tr id="projectrow">
+  <td id="projectalign">
+   <div id="projectname">LDClient<span id="projectnumber">&#160;v.1</span>
+   </div>
+   <div id="projectbrief">Client application for the detection of Lauterbach debugger devices</div>
+  </td>
+ </tr>
+ </tbody>
+</table>
+</div>
+<!-- end header part -->
+<!-- Generated by Doxygen 1.9.4 -->
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+var searchBox = new SearchBox("searchBox", "search",'Search','.html');
+/* @license-end */
+</script>
+<script type="text/javascript" src="menudata.js"></script>
+<script type="text/javascript" src="menu.js"></script>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(function() {
+  initMenu('',true,false,'search.php','Search');
+  $(document).ready(function() { init_search(); });
+});
+/* @license-end */
+</script>
+<div id="main-nav"></div>
+</div><!-- top -->
+<div id="side-nav" class="ui-resizable side-nav-resizable">
+  <div id="nav-tree">
+    <div id="nav-tree-contents">
+      <div id="nav-sync" class="sync"></div>
+    </div>
+  </div>
+  <div id="splitbar" style="-moz-user-select:none;" 
+       class="ui-resizable-handle">
+  </div>
+</div>
+<script type="text/javascript">
+/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699&amp;dn=expat.txt MIT */
+$(document).ready(function(){initNavTree('dir_ebc798c9b1f11074fd71688d371864c0.html',''); initResizable(); });
+/* @license-end */
+</script>
+<div id="doc-content">
+<!-- window showing the filter options -->
+<div id="MSearchSelectWindow"
+     onmouseover="return searchBox.OnSearchSelectShow()"
+     onmouseout="return searchBox.OnSearchSelectHide()"
+     onkeydown="return searchBox.OnSearchSelectKey(event)">
+</div>
+
+<!-- iframe showing the search results (closed by default) -->
+<div id="MSearchResultsWindow">
+<iframe src="javascript:void(0)" frameborder="0" 
+        name="MSearchResults" id="MSearchResults">
+</iframe>
+</div>
+
+<div class="header">
+  <div class="headertitle"><div class="title">net6.0 Directory Reference</div></div>
+</div><!--header-->
+<div class="contents">
+</div><!-- contents -->
+</div><!-- doc-content -->
+<!-- start footer part -->
+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
+  <ul>
+    <li class="navelem"><a class="el" href="dir_d13acb3f48e6aaa83bf47a5658d35ef4.html">review</a></li><li class="navelem"><a class="el" href="dir_e995fcc46e5f182c24bd6fe0d90a742c.html">aswi2022bug-thugs</a></li><li class="navelem"><a class="el" href="dir_3829590d4bc1496e3a509b2e3d199db3.html">ld_client</a></li><li class="navelem"><a class="el" href="dir_c0ab93adfd4cbfb9e07de4a4a775fb83.html">LDClient</a></li><li class="navelem"><a class="el" href="dir_082f6a8deca2b2d1a7c77b6edd561a50.html">obj</a></li><li class="navelem"><a class="el" href="dir_eba1acdda5df661dbf6e514468df4101.html">Debug</a></li><li class="navelem"><a class="el" href="dir_ebc798c9b1f11074fd71688d371864c0.html">net6.0</a></li>
+    <li class="footer">Generated by <a href="https://www.doxygen.org/index.html"><img class="footer" src="doxygen.svg" width="104" height="31" alt="doxygen"/></a> 1.9.4 </li>
+  </ul>
+</div>
+</body>
+</html>
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
index 30955ae..754f8c0 100644
--- a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_info_fetcher.html
@@ -188,7 +188,7 @@ Properties</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this interface was generated from the following file:<ul>
-<li>detection/IInfoFetcher.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/IInfoFetcher.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
index 24e7373..9a8ab40 100644
--- a/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1detection_1_1_i_process_utils.html
@@ -189,7 +189,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this interface was generated from the following file:<ul>
-<li>detection/IProcessUtils.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/detection/IProcessUtils.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
index e333b90..ee2637d 100644
--- a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_api_client.html
@@ -155,7 +155,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this interface was generated from the following file:<ul>
-<li>network/IApiClient.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/IApiClient.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
index c09212a..7eb4cbd 100644
--- a/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1network_1_1_i_http_client.html
@@ -132,7 +132,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this interface was generated from the following file:<ul>
-<li>network/IHttpClient.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/network/IHttpClient.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
diff --git a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
index dd550a8..bbec061 100644
--- a/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
+++ b/ld_client/doc/pdoc/interface_l_d_client_1_1utils_1_1_i_file_utils.html
@@ -132,7 +132,7 @@ Public Member Functions</h2></td></tr>
 </div>
 </div>
 <hr/>The documentation for this interface was generated from the following file:<ul>
-<li>utils/IFileUtils.cs</li>
+<li>review/aswi2022bug-thugs/ld_client/LDClient/utils/IFileUtils.cs</li>
 </ul>
 </div><!-- contents -->
 </div><!-- doc-content -->
-- 
GitLab


From 2c9a5fda113e0b63aa67b92d228b5b6cdb40edd2 Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sat, 14 May 2022 10:30:19 +0200
Subject: [PATCH 60/67] re #9845 Added an outer loop for information retrieval

---
 ld_client/LDClient/Program.cs                 |  4 ++-
 ld_client/LDClient/appsettings.json           |  4 ++-
 .../LDClient/detection/ProcessDetection.cs    | 33 ++++++++++++++-----
 ld_client/LDClient/utils/ConfigLoader.cs      | 14 +++++++-
 4 files changed, 44 insertions(+), 11 deletions(-)

diff --git a/ld_client/LDClient/Program.cs b/ld_client/LDClient/Program.cs
index 04c6099..1fb5d96 100644
--- a/ld_client/LDClient/Program.cs
+++ b/ld_client/LDClient/Program.cs
@@ -92,7 +92,9 @@ internal static class Program {
             Config.DetectionPeriod,
             InfoFetcher,
             DefaultApiClient,
-            new ProcessUtils()
+            new ProcessUtils(),
+            Config.FetchInfoSuperiorMaxAttempts,
+            Config.FetchInfoSuperiorAttemptPeriod
         );
         
         // Create and start a new thread that periodically
diff --git a/ld_client/LDClient/appsettings.json b/ld_client/LDClient/appsettings.json
index ba3cadb..e07c78c 100644
--- a/ld_client/LDClient/appsettings.json
+++ b/ld_client/LDClient/appsettings.json
@@ -64,6 +64,8 @@
     "FetchInfoMaxAttempts": 15,
     "FetchInfoAttemptPeriod": 4000,
     "T32RemSuccessExitCode": 0,
-    "T32RemWaitTimeoutMs": 2000
+    "T32RemWaitTimeoutMs": 2000,
+    "FetchInfoSuperiorMaxAttempts": 5,
+    "FetchInfoSuperiorAttemptPeriod": 1000
   }
 }
\ No newline at end of file
diff --git a/ld_client/LDClient/detection/ProcessDetection.cs b/ld_client/LDClient/detection/ProcessDetection.cs
index af47b38..043361e 100644
--- a/ld_client/LDClient/detection/ProcessDetection.cs
+++ b/ld_client/LDClient/detection/ProcessDetection.cs
@@ -61,6 +61,16 @@ public sealed class ProcessDetection : IProcessDetection {
     /// Flag used to stop the thread (process detection).
     /// </summary>
     public bool DetectionRunning = false;
+
+    /// <summary>
+    /// Superior number of attempts to fetch the information (outer loop).
+    /// </summary>
+    private uint _fetchInfoSuperiorMaxAttempts;
+    
+    /// <summary>
+    /// Period of the superior (outer) loop to fetch the data.
+    /// </summary>
+    private uint _fetchInfoSuperiorAttemptPeriod;
         
     /// <summary>
     /// Creates an instance of this class.
@@ -71,13 +81,15 @@ public sealed class ProcessDetection : IProcessDetection {
     /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
     /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
     public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
-        IApiClient apiClient, IProcessUtils processUtils) {
+        IApiClient apiClient, IProcessUtils processUtils, uint fetchInfoSuperiorMaxAttempts, uint fetchInfoSuperiorAttemptPeriod) {
         _processName = processName;
         _detectionPeriodMs = detectionPeriodMs;
         _infoFetcher = infoFetcher;
         _apiClient = apiClient;
         _failedToRetrieveData = false;
         _processUtils = processUtils;
+        _fetchInfoSuperiorMaxAttempts = fetchInfoSuperiorMaxAttempts;
+        _fetchInfoSuperiorAttemptPeriod = fetchInfoSuperiorAttemptPeriod;
     }
 
     /// <summary>
@@ -86,14 +98,19 @@ public sealed class ProcessDetection : IProcessDetection {
     /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
     private async Task<bool> RetrieveDataFromDebugger() {
         // Try to fetch data from the debugger.
-        var success = await _infoFetcher.FetchDataAsync();
-            
-        // If the data was fetched successfully, send a payload off to the server.
-        if (success) {
-            _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
-                _infoFetcher.BodySerialNumber, DatetimeFormat);
+
+        for (var i = 0; i < _fetchInfoSuperiorMaxAttempts; i++) {
+            var success = await _infoFetcher.FetchDataAsync();
+
+            // If the data was fetched successfully, send a payload off to the server.
+            if (success) {
+                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
+                    _infoFetcher.BodySerialNumber, DatetimeFormat);
+                return true;
+            }
+            await Task.Delay((int)_fetchInfoSuperiorAttemptPeriod);
         }
-        return success;
+        return false;
     }
 
     /// <summary>
diff --git a/ld_client/LDClient/utils/ConfigLoader.cs b/ld_client/LDClient/utils/ConfigLoader.cs
index 3544c46..6093f45 100644
--- a/ld_client/LDClient/utils/ConfigLoader.cs
+++ b/ld_client/LDClient/utils/ConfigLoader.cs
@@ -185,6 +185,16 @@ namespace LDClient.utils {
         /// </summary>
         public string T32ApiPacketLen { get; private set; } = null!;
 
+        /// <summary>
+        /// Superior number of attempts to fetch the information (outer loop).
+        /// </summary>
+        public uint FetchInfoSuperiorMaxAttempts { get; private set; }
+        
+        /// <summary>
+        /// Period of the superior (outer) loop to fetch the data.
+        /// </summary>
+        public uint FetchInfoSuperiorAttemptPeriod { get; private set;  }
+
         #endregion
 
         /// <summary>
@@ -283,7 +293,9 @@ namespace LDClient.utils {
                 T32ApiAddress = debugger["T32ApiAddress"];
                 T32ApiPort = debugger["T32ApiPort"];
                 T32ApiPacketLen = debugger["T32ApiPacketLen"];
-                
+                FetchInfoSuperiorMaxAttempts = uint.Parse(debugger["FetchInfoSuperiorMaxAttempts"]);
+                FetchInfoSuperiorAttemptPeriod = uint.Parse(debugger["FetchInfoSuperiorAttemptPeriod"]);
+
             } catch (Exception e) {
                 Console.WriteLine(e);
                 Environment.Exit(ErrorExitCode);
-- 
GitLab


From 0728c021a2c66439583488eee61b84d702a9627a Mon Sep 17 00:00:00 2001
From: silhavyj <jakub.sil@seznam.cz>
Date: Sat, 14 May 2022 10:36:52 +0200
Subject: [PATCH 61/67] re #9845 Fixed some bugs in InfoFetcherTests.cs and
 ProcessDetectionTests.cs

---
 ld_client/LDClientTests/detection/InfoFetcherTests.cs     | 8 ++++----
 .../LDClientTests/detection/ProcessDetectionTests.cs      | 2 +-
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
index 03c62a9..3285226 100644
--- a/ld_client/LDClientTests/detection/InfoFetcherTests.cs
+++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
@@ -48,7 +48,7 @@ internal class InfoFetcherTests {
             Returns(DebuggerInfoParserTests.CorrectFileContent.Split("\n"));
 
 
-        var result = await _defaultFetcher.FetchDataAsync();
+        bool result = await _defaultFetcher.FetchDataAsync();
 
         Assert.IsTrue(result);
         _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
@@ -70,7 +70,7 @@ internal class InfoFetcherTests {
             Returns(new []{""});
 
 
-        var result = await _defaultFetcher.FetchDataAsync();
+        bool result = await _defaultFetcher.FetchDataAsync();
 
 
         Assert.IsFalse(result);
@@ -86,7 +86,7 @@ internal class InfoFetcherTests {
         _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).
             Returns(new[] { "" });
 
-        var result = await _fetcherWithoutPars.FetchDataAsync();
+        bool result = await _fetcherWithoutPars.FetchDataAsync();
             
         Assert.IsFalse(result);
         _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
@@ -102,7 +102,7 @@ internal class InfoFetcherTests {
             It.IsAny<int>(), It.IsAny<int>())).Returns(true);
         _mockFileUtils.Setup(x => x.ReadFileAllLines(It.IsAny<string>())).Throws(new FileNotFoundException());
 
-        var result = await _defaultFetcher.FetchDataAsync();
+        bool result = await _defaultFetcher.FetchDataAsync();
         Assert.IsFalse(result);
 
         _mockProcessUtils.Verify(x => x.ExecuteNewProcess(It.IsAny<string>(), It.IsAny<string>(),
diff --git a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs
index 6c6a2da..c0200db 100644
--- a/ld_client/LDClientTests/detection/ProcessDetectionTests.cs
+++ b/ld_client/LDClientTests/detection/ProcessDetectionTests.cs
@@ -33,7 +33,7 @@ public class ProcessDetectionTests {
         _mockProcessUtils = new Mock<IProcessUtils>(MockBehavior.Strict);
             
 
-        _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object);
+        _processDetection = new ProcessDetection("process", 50, _mockInfoFetcher.Object, _mockApiClient.Object, _mockProcessUtils.Object, 1, 0);
     }
 
 
-- 
GitLab


From 35168e5f93569072cba4fad064febc3917a673ff Mon Sep 17 00:00:00 2001
From: "zemanm98@students.zcu.cz" <Farnhait123*>
Date: Sat, 14 May 2022 16:16:40 +0200
Subject: [PATCH 62/67] Fixed minor issues. View on keyman devices changed.
 Changed database for new keyman x license connection.

---
 server/sql_app/api/devices_web.py             | 115 ++++++---
 server/sql_app/api/licenses_web.py            |  16 +-
 server/sql_app/api/pcs_web.py                 |  29 ---
 server/sql_app/api/teams_web.py               |  29 ++-
 server/sql_app/crud.py                        | 233 ++++++++++++++----
 server/sql_app/main.py                        |   2 +-
 server/sql_app/models.py                      |  17 +-
 server/sql_app/schemas.py                     |  18 +-
 .../templates/body-devices/body_devices.html  |   9 +-
 .../body-devices/body_devices_normal.html     |   9 +-
 server/templates/devices/devicelicense.html   |  33 ++-
 server/templates/devices/devices.html         | 107 +++++---
 server/templates/devices/devices_normal.html  |  69 ++++--
 server/templates/ld-logs/ldlogs.html          |   9 +-
 server/templates/ld-logs/ldlogs_normal.html   |   9 +-
 server/templates/licenses/license_create.html |   2 +
 server/templates/licenses/licenses.html       |  15 +-
 .../templates/licenses/licenses_normal.html   |   9 +-
 server/templates/pcs/pcs.html                 |  19 +-
 server/templates/pcs/pcs_normal.html          |  17 +-
 server/templates/teams/team_change.html       |  15 ++
 server/templates/teams/teams.html             |  15 +-
 server/templates/teams/teams_normal.html      |  13 +-
 server/templates/usb-logs/logs.html           |  11 +-
 server/templates/usb-logs/logs_normal.html    |  11 +-
 server/templates/users/users.html             |   7 +-
 26 files changed, 557 insertions(+), 281 deletions(-)
 create mode 100644 server/templates/teams/team_change.html

diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py
index 0d82a6b..73fdf61 100644
--- a/server/sql_app/api/devices_web.py
+++ b/server/sql_app/api/devices_web.py
@@ -8,7 +8,7 @@ from fastapi_jwt_auth import AuthJWT
 from pydantic import BaseModel
 from sqlalchemy.orm import Session
 from sql_app.api.auth import fake_users_db
-from sql_app import crud, models
+from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 
 models.Base.metadata.create_all(bind=engine)
@@ -38,23 +38,31 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
 
+    device_dict = []
     devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
+    for dev in devices:
+        if len(dev.licenses) > 0:
+            for lic in dev.licenses:
+                device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
-        return templates.TemplateResponse("devices.html", {"request": request, "devs": len(devices), "devices": devices,
-                                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict,
+                                                           "licenses": licenses, "devs": devices,
+                                                           "teams": teams, "user": current_user})
     else:
         current_user = "guest"
-        return templates.TemplateResponse("devices_normal.html", {"request": request, "devs": len(devices), "devices": devices,
-                                                                  "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict,
+                                                                  "licenses": licenses, "user": current_user})
 
 
 @device_web.post("/devices-web", response_class=HTMLResponse)
-async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"),
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         keyman_id: str = Form("all"), lic_name: str = Form("all"),
+                         lic_id: str = Form("all"), team: str = Form("all"),
                          db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint used for filtering devices by license. returns html template with only
@@ -62,28 +70,29 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic:
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    def_devices = []
+    device_dict = []
+    devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_devices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
     for dev in devices:
-        for l in dev.licenses:
-            if dev not in def_devices and l.licenses.name == lic:
-                def_devices.append(dev)
-    # if input was default all
-    if lic == "all":
-        def_devices = devices
-    statuses = []
-    for i in range(0, len(def_devices)):
-        statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status)
+        if len(dev.licenses) > 0:
+            for lic in dev.licenses:
+                device_dict.append({"device": dev, "license": lic.licenses, "log": dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
-        return templates.TemplateResponse("devices.html",
-                                          {"request": request, "devs": len(def_devices), "devices": def_devices,
-                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict,
+                                                           "licenses": licenses, "devs": devices,
+                                                           "teams": teams, "user": current_user})
     else:
         current_user = "guest"
-        return templates.TemplateResponse("devices_normal.html",
-                                          {"request": request, "devs": len(def_devices), "devices": def_devices,
-                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict,
+                                                                  "licenses": licenses, "user": current_user})
 
 
 @device_web.get("/device-license/{device_id}", response_class=HTMLResponse)
@@ -98,19 +107,21 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend
         return RedirectResponse(url=f"/logs-web", status_code=303)
     device = crud.get_device(db, device_id)
     dev_licenses = crud.get_device_licenses(db, device_id)
-    lic_names = []
+    lic_ids = []
     dev_lics = []
     for dev_lic in dev_licenses:
         dev_lics.append(dev_lic.licenses)
     for dev_lic in dev_licenses:
-        lic_names.append(dev_lic.licenses.name)
+        lic_ids.append(dev_lic.licenses.license_id)
     licenses = crud.get_licenses(db, 0, 100)
     lic_left = []
     for lic in licenses:
-        if lic.name not in lic_names and lic not in lic_left:
+        if lic.license_id not in lic_ids and lic not in lic_left:
             lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
     return templates.TemplateResponse("devicelicense.html",
-                                      {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics})
+                                      {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics,
+                                       "teams": teams})
 
 
 @device_web.post("/devices-web/{device_id}")
@@ -141,3 +152,45 @@ async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = De
         return RedirectResponse(url=f"/logs-web", status_code=303)
     crud.delete_device_license(db, device_id, int(lic_del))
     return RedirectResponse(url=f"/devices-web", status_code=303)
+
+@device_web.post("/devices-web-team/{device_id}")
+async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
+    table and redirects to devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_device(db, device_id, team_con)
+    return RedirectResponse(url=f"/devices-web", status_code=303)
+
+@device_web.post("/devices-web-inv/{device_id}")
+async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
+    table and redirects to devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_device_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f"/devices-web", status_code=303)
+
+@device_web.post("/devices-web-comment/{device_id}")
+async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
+    table and redirects to devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_device_com(db, device_id, dev_com)
+    return RedirectResponse(url=f"/devices-web", status_code=303)
diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py
index f402a1b..3d9bdf5 100644
--- a/server/sql_app/api/licenses_web.py
+++ b/server/sql_app/api/licenses_web.py
@@ -1,5 +1,5 @@
 from typing import List
-
+from typing import Optional
 from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
 from sqlalchemy.orm import Session
 from datetime import date
@@ -60,8 +60,8 @@ async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, d
                                                             "user": current_user})
 
 @licenses_web.post("/licenses-web")
-def create_license(name: str = Form(...), expdate: date = Form(...), db: Session = Depends(get_db),
-                   Authorize: AuthJWT = Depends()):
+def create_license(name: str = Form(...), lic_id: str = Form(...), expdate: Optional[date] = Form(None),
+                   db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint called from create license form. Creates new license and redirects to devices-web endpoint
     """
@@ -70,11 +70,11 @@ def create_license(name: str = Form(...), expdate: date = Form(...), db: Session
     if current_user != "admin":
         return RedirectResponse(url=f"/logs-web", status_code=303)
     licenses = crud.get_licenses(db, 0, 100)
-    licenses_names = []
+    licenses_ids = []
     for l in licenses:
-        licenses_names.append(l.name)
-    if name not in licenses_names:
-        db_license = crud.create_license(db, name, expdate)
+        licenses_ids.append(l.license_id)
+    if lic_id not in licenses_ids:
+        db_license = crud.create_license(db, name, lic_id, expdate)
         if db_license is None:
             print("something went wrong")
-    return RedirectResponse(url=f"/devices-web", status_code=303)
+    return RedirectResponse(url=f"/licenses-web", status_code=303)
diff --git a/server/sql_app/api/pcs_web.py b/server/sql_app/api/pcs_web.py
index 2779e46..39dfac5 100644
--- a/server/sql_app/api/pcs_web.py
+++ b/server/sql_app/api/pcs_web.py
@@ -42,32 +42,3 @@ async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Sessio
         current_user = "guest"
         return templates.TemplateResponse("pcs_normal.html", {"request": request, "pcs": pcs, "user": current_user})
 
-
-@pcs_web.get("/pc-team/{pc_id}", response_class=HTMLResponse)
-async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db),
-                          Authorize: AuthJWT = Depends()):
-    """
-    Returns template with Form for connecting pc with team
-    """
-    Authorize.jwt_optional()
-    current_user = Authorize.get_jwt_subject()
-    if current_user != "admin":
-        return RedirectResponse(url=f"/logs-web", status_code=303)
-    pc = crud.get_pc(db, pc_id)
-    teams = crud.get_teams(db, 0, 100)
-    return templates.TemplateResponse("pcteam.html",
-                                      {"request": request, "pc": pc, "teams": teams})
-
-
-@pcs_web.post("/pcs-web/{pc_id}")
-async def connect_post(pc_id: int, team: str = Form(...), db: Session = Depends(get_db),
-                       Authorize: AuthJWT = Depends()):
-    """
-    Endpoint called from within form for connecting pc with team. Updates certain pc with new team.
-    """
-    Authorize.jwt_optional()
-    current_user = Authorize.get_jwt_subject()
-    if current_user != "admin":
-        return RedirectResponse(url=f"/logs-web", status_code=303)
-    old_pc = crud.update_pc(db, pc_id, team)
-    return RedirectResponse(url=f"/pcs-web", status_code=303)
diff --git a/server/sql_app/api/teams_web.py b/server/sql_app/api/teams_web.py
index 616c1c7..15c44b7 100644
--- a/server/sql_app/api/teams_web.py
+++ b/server/sql_app/api/teams_web.py
@@ -59,7 +59,7 @@ async def team_create_web(request: Request, Authorize: AuthJWT = Depends()):
 @teams_web.post("/teams-web-con")
 def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from within form for creating new team. Creates new team and returns all teams in database
+    Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -74,3 +74,30 @@ def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize:
         if team is None:
             print("something went wrong")
     return RedirectResponse(url=f"/teams-web", status_code=303)
+
+
+@teams_web.get("/team-change/{team_id}", response_class=HTMLResponse)
+async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    """
+    Returns template with form for changing teams name
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    team = crud.get_team(db, team_id)
+    return templates.TemplateResponse("team_change.html", {"request": request, "team": team})
+
+@teams_web.post("/teams-change-process/{team_id}")
+async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...),
+                              Authorize: AuthJWT = Depends()):
+    """
+    Changes teams name to a new one given by user
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    team = crud.change_team(db, team_id, name)
+    return RedirectResponse(url=f"/teams-web", status_code=303)
\ No newline at end of file
diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py
index f2b3a9b..d20873b 100644
--- a/server/sql_app/crud.py
+++ b/server/sql_app/crud.py
@@ -19,21 +19,37 @@ def get_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.Device).offset(skip).limit(limit).all()
 
 
-def find_device(db: Session, device: schemas.DeviceBase):
+def find_device(db: Session, device: schemas.DeviceTemp):
     """
-    finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object
+    finds one device with  serial_number same as in given DeviceBase object
     """
-    return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id,
-                                               models.Device.vendor_id == device.vendor_id,
-                                               models.Device.serial_number == device.serial_number)).first()
+    return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first()
 
 
-def create_device(db: Session, device: schemas.DeviceBase):
+def find_device_by_serial(db: Session, ser: str):
+    """
+    finds one device with serial_number same as in given DeviceBase object
+    """
+    return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first()
+
+def get_devices_with_ids(db: Session, ids: []):
+    """
+    returns all devices with given ids
+    """
+    return db.query(models.Device).filter(models.Device.id.in_(ids)).all()
+
+def get_devices_by_team(db: Session, team: int):
+    """
+    returns all devices with same team
+    """
+    return db.query(models.Device).filter(models.Device.team_id == team).all()
+
+def create_device(db: Session, device: schemas.DeviceTemp):
     """
     creates new device with data from given DeviceBase object
     """
     db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id,
-                              serial_number=device.serial_number, assigned=False)
+                              serial_number=device.serial_number, inventory_number="", comment="")
     db.add(db_device)
     db.commit()
     db.refresh(db_device)
@@ -58,14 +74,18 @@ def find_license(db: Session, name: str):
     """
     finds one license by given string name
     """
-    return db.query(models.License).filter(models.License.name == name).first()
+    return db.query(models.License).filter(models.License.license_id == name).first()
+
 
+def get_licenses_by_name(db: Session, name: str):
+    return db.query(models.License).filter(models.License.name == name).all()
 
-def create_license(db: Session, name: str, expdate: date):
+
+def create_license(db: Session, name: str, lic_id: str, expdate: date):
     """
     creates new license with given name and expiration date
     """
-    db_license = models.License(name=name, expiration_date=expdate)
+    db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate)
     db.add(db_license)
     db.commit()
     db.refresh(db_license)
@@ -79,9 +99,16 @@ def get_license_devices(db: Session, license_id: int):
     return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all()
 
 
+def find_devicelicenses_by_licid_array(db: Session, lcs: []):
+    """
+    Finds all device_licenses with license_id in given id array
+    """
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all()
+
+
 def get_device_licenses(db: Session, device_id: int):
     """
-    returns all entries in devices_licenses table with given license_id
+    returns all entries in devices_licenses table with given device_id
     """
     return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all()
 
@@ -174,19 +201,61 @@ def get_pc(db: Session, pc_id: int):
     return db.query(models.PC).filter(models.PC.id == pc_id).first()
 
 
-def update_pc(db: Session, pc_id: int, team: str):
+def update_device(db: Session, device_id: int, team: str):
     """
     Updates team of one specific pc
     """
-    old_pc = get_pc(db, pc_id)
+    old_dev = get_device(db, device_id)
     team = get_team(db, int(team))
-    new = {'id': old_pc.id, 'username': old_pc.username, 'hostname': old_pc.hostname, 'assigned': True,
-           'team_id': team.id}
+    new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id,
+           'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': old_dev.comment, 'team_id': team.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_device_inv(db: Session, device_id: int, inv: str):
+    """
+    Updates inventory number of one specific pc
+    """
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id,
+           'serial_number': old_dev.serial_number, 'inventory_number': inv,
+           'comment': old_dev.comment, 'team_id': teamid}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_device_com(db: Session, device_id: int, comm: str):
+    """
+    Updates team of one specific pc
+    """
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {'id': old_dev.id, 'vendor_id': old_dev.vendor_id, 'product_id': old_dev.product_id,
+           'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': comm, 'team_id': teamid}
     for key, value in new.items():
-        setattr(old_pc, key, value)
+        setattr(old_dev, key, value)
     db.commit()
-    db.refresh(old_pc)
-    return old_pc
+    db.refresh(old_dev)
+    return old_dev
+
 
 def change_role(db: Session, usr_id: int, role: str):
     """
@@ -237,18 +306,11 @@ def find_pcs(db: Session, pcs: []):
     return db.query(models.PC).filter(models.PC.id.in_(pcs)).all()
 
 
-def get_pcs_by_team(db: Session, team_id: int):
-    """
-    returns all pcs in given team by team id
-    """
-    return db.query(models.PC).filter(models.PC.team_id == team_id).all()
-
-
 def create_pc(db: Session, user: str, host: str):
     """
     creates new pc with given username and hostname
     """
-    db_pc = models.PC(username=user, hostname=host, assigned=False)
+    db_pc = models.PC(username=user, hostname=host)
     db.add(db_pc)
     db.commit()
     db.refresh(db_pc)
@@ -287,6 +349,19 @@ def create_team(db: Session, name: str):
     return db_team
 
 
+def change_team(db: Session, team_id: int, name: str):
+    """
+    Updates name of one specific team
+    """
+    old_team = get_team(db, team_id)
+    new = {'id': old_team.id, 'name': name}
+    for key, value in new.items():
+        setattr(old_team, key, value)
+    db.commit()
+    db.refresh(old_team)
+    return old_team
+
+
 def get_head_device(db: Session, head_id: int):
     """
     Returns one specific head device by given id
@@ -410,19 +485,19 @@ def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str):
     if tema != "all":
         team = find_team(db, tema)
         if team is not None:
-            pcst = get_pcs_by_team(db, team.id)
-            pc_ids = "("
-            for p in pcst:
-                pc_ids += str(p.id) + ", "
-            def_pc_ids = pc_ids[:-2] + ")"
+            devs = get_devices_by_team(db, team.id)
+            d_ids = "("
+            for p in devs:
+                d_ids += str(p.id) + ", "
+            def_d_ids = d_ids[:-2] + ")"
             if pc != "all" and pcs is not None:
-                if len(def_pc_ids) > 1:
-                    execute_string += " AND logs.pc_id IN " + def_pc_ids
+                if len(def_d_ids) > 1:
+                    execute_string += " AND logs.device_id IN " + def_d_ids
             else:
-                if len(def_pc_ids) > 1:
-                    execute_string += " WHERE logs.pc_id IN " + def_pc_ids
+                if len(def_d_ids) > 1:
+                    execute_string += " WHERE logs.device_id IN " + def_d_ids
     if lic != "all":
-        license = find_license(db, lic)
+        license = get_licenses_by_name(db, lic)
         if license is not None:
             device_licenses = get_license_bodydevice(db, license.id)
             dev_ids = "("
@@ -454,19 +529,19 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
     if tema != "all":
         team = find_team(db, tema)
         if team is not None:
-            pcst = get_pcs_by_team(db, team.id)
-            pc_ids = "("
-            for p in pcst:
-                pc_ids += str(p.id) + ", "
-            def_pc_ids = pc_ids[:-2] + ")"
+            devs = get_devices_by_team(db, team.id)
+            d_ids = "("
+            for p in devs:
+                d_ids += str(p.id) + ", "
+            def_d_ids = d_ids[:-2] + ")"
             if pc != "all" and pcs is not None:
-                if len(def_pc_ids) > 1:
-                    execute_string += " AND logs.pc_id IN " + def_pc_ids
+                if len(def_d_ids) > 1:
+                    execute_string += " AND logs.device_id IN " + def_d_ids
             else:
-                if len(def_pc_ids) > 1:
-                    execute_string += " WHERE logs.pc_id IN " + def_pc_ids
+                if len(def_d_ids) > 1:
+                    execute_string += " WHERE logs.device_id IN " + def_d_ids
     if lic != "all":
-        license = find_license(db, lic)
+        license = get_licenses_by_name(db, lic)
         if license is not None:
             device_licenses = get_license_devices(db, license.id)
             dev_ids = "("
@@ -485,6 +560,72 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
     return result
 
 
+def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str):
+    """
+    returns filtered devices based on given atributes
+    """
+    execute_string = "SELECT * FROM devices AS device WHERE"
+    before_me = False
+    all_all = True
+    if keyman_id != "all":
+        all_all = False
+        keyman_dev = find_device_by_serial(db, keyman_id)
+        if keyman_dev != None:
+            if before_me:
+                execute_string += " AND device.id = " + str(keyman_dev.id)
+            else:
+                before_me = True
+                execute_string += " device.id = " + str(keyman_dev.id)
+    if license_name != "all":
+        all_all = False
+        license = get_licenses_by_name(db, license_name)
+        if len(license) > 0:
+            lic_ids = []
+            for l in license:
+                lic_ids.append(l.id)
+            dev_lics = find_devicelicenses_by_licid_array(db, lic_ids)
+            lic_ids = "("
+            for l in dev_lics:
+                lic_ids += str(l.device_id) + ", "
+            def_lic_ids = lic_ids[:-2] + ")"
+            if before_me:
+                execute_string += " AND device.id IN " + def_lic_ids
+            else:
+                before_me = True
+                execute_string += " device.id IN " + def_lic_ids
+    if license_id != "all":
+        all_all = False
+        license = find_license(db, license_id)
+        licen_devs = get_license_devices(db, license.id)
+        ids = "("
+        for lic in licen_devs:
+            ids += str(lic.device_id) + ", "
+        def_ids = ids[:-2] + ")"
+        if license != None:
+            if before_me:
+                execute_string += " AND device.id IN " + def_ids
+            else:
+                before_me = True
+                execute_string += " device.id IN " + def_ids
+    if team != "all":
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += " AND device.team_id = " + str(tem.id)
+            else:
+                before_me = True
+                execute_string += " device.team_id = " + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = "SELECT * FROM devices AS devices"
+
+    if not before_me:
+        execute_string = "SELECT * FROM devices AS devices WHERE devices.id = -1"
+    result = db.execute(execute_string)
+    return result
+
+
 def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_id: int, date: datetime):
     """
     Creates new USB log for usb_logs database table
diff --git a/server/sql_app/main.py b/server/sql_app/main.py
index 224d136..637bfaf 100644
--- a/server/sql_app/main.py
+++ b/server/sql_app/main.py
@@ -38,5 +38,5 @@ app.include_router(auth)
 
 '''
 if __name__ == "__main__":
-    uvicorn.run(app, host="192.168.0.22", port=8000)
+    uvicorn.run(app, host="192.168.64.1", port=8000)
 '''
diff --git a/server/sql_app/models.py b/server/sql_app/models.py
index d91cfa5..e3e40a5 100644
--- a/server/sql_app/models.py
+++ b/server/sql_app/models.py
@@ -14,13 +14,16 @@ class Device(Base):
     vendor_id = Column(String, index=True, nullable=False)
     product_id = Column(String, index=True, nullable=False)
     serial_number = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey("teams.id"))
 
     # relationships for foreign keys, thus connecting table with usb_logs and licenses
     # tables
     logs = relationship("USBLog", back_populates="device")
     licenses = relationship("DeviceLicense", back_populates="device_lic")
-
+    team = relationship("Team", back_populates="devices")
 
 class USBLog(Base):
     """
@@ -48,7 +51,8 @@ class License(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     name = Column(String, index=True, nullable=False)
-    expiration_date = Column(DateTime(timezone=True), server_default=func.now())
+    license_id = Column(String, index=True, nullable=False)
+    expiration_date = Column(DateTime(timezone=True), nullable=True)
 
     # relationships for foreign keys, thus connecting table with devices table
     devices = relationship("DeviceLicense", back_populates="licenses")
@@ -97,12 +101,9 @@ class PC(Base):
     id = Column(Integer, primary_key=True, index=True)
     username = Column(String, index=True, nullable=False)
     hostname = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
-    team_id = Column(Integer, ForeignKey("teams.id"))
 
     # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs
     # tables
-    team = relationship("Team", back_populates="pcs")
     logs_pc = relationship("USBLog", back_populates="pc")
     ld_pc = relationship("LDLog", back_populates="ldpc")
 
@@ -116,9 +117,7 @@ class Team(Base):
     id = Column(Integer, primary_key=True, index=True)
     name = Column(String, index=True, nullable=False)
 
-    # relationships for foreign keys, thus connecting table with pc table
-    pcs = relationship("PC", back_populates="team")
-
+    devices = relationship("Device", back_populates="team")
 
 class HeadDevice(Base):
     """
diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py
index 79becdc..4a7e381 100644
--- a/server/sql_app/schemas.py
+++ b/server/sql_app/schemas.py
@@ -48,6 +48,8 @@ class DeviceBase(BaseModel):
     vendor_id: str
     product_id: str
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class DeviceCreate(DeviceBase):
@@ -59,7 +61,6 @@ class Device(DeviceCreate):
     Class used for creating and reading devices entries
     """
     id: int
-    assigned: bool
     logs: List[USBLog] = []
     licenses: List[DeviceLicense] = []
 
@@ -67,6 +68,12 @@ class Device(DeviceCreate):
         orm_mode = True
 
 
+class DeviceTemp(BaseModel):
+    vendor_id: str
+    product_id: str
+    serial_number: str
+
+
 class LDLogBase(BaseModel):
     timestamp: datetime
     status: str
@@ -140,8 +147,8 @@ class PC(PCCreate):
     Class used for creating and reading pc entries
     """
     id: int
-    assigned: bool
     logs_pc: List[USBLog] = []
+    logs_ld: List[LDLog] = []
 
     class Config:
         orm_mode = True
@@ -160,7 +167,7 @@ class Team(TeamCreate):
     Class used for creating and reading team entries
     """
     id: int
-    pcs: List[PC] = []
+    devices: List[Device] = []
 
     class Config:
         orm_mode = True
@@ -168,6 +175,7 @@ class Team(TeamCreate):
 
 class LicenseBase(BaseModel):
     name: str
+    license_id: str
     expiration_date: date
 
 
@@ -193,7 +201,7 @@ class USBTempBase(BaseModel):
     username: str
     hostname: str
     timestamp: str
-    device: DeviceBase
+    device: DeviceTemp
     status: str
 
 
@@ -242,6 +250,7 @@ class UserBase(BaseModel):
     password: str
     role: str
 
+
 class UserCreate(UserBase):
     pass
 
@@ -251,3 +260,4 @@ class User(UserCreate):
 
     class Config:
         orm_mode = True
+
diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html
index b36a923..255a851 100644
--- a/server/templates/body-devices/body_devices.html
+++ b/server/templates/body-devices/body_devices.html
@@ -22,11 +22,10 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/body-devices-web" selected>Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -47,7 +46,7 @@
 <table>
     <TR>
         <TH>ID</TH>
-        <TH>Serial Number</TH>
+        <TH>Lauterbach Body ID</TH>
         <TH>Licenses</TH>
         <TH>Status</TH>
     </TR>
diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html
index ece156d..8a3452e 100644
--- a/server/templates/body-devices/body_devices_normal.html
+++ b/server/templates/body-devices/body_devices_normal.html
@@ -22,11 +22,10 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/body-devices-web" selected>Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -46,7 +45,7 @@
 <table>
     <TR>
         <TH>ID</TH>
-        <TH>Serial Number</TH>
+        <TH>Lauterbach Body ID</TH>
         <TH>Licenses</TH>
         <TH>Status</TH>
     </TR>
diff --git a/server/templates/devices/devicelicense.html b/server/templates/devices/devicelicense.html
index b8f8833..e72d585 100644
--- a/server/templates/devices/devicelicense.html
+++ b/server/templates/devices/devicelicense.html
@@ -7,25 +7,52 @@
 <body>
 <h6><p>Vendor ID: {{device.vendor_id}}</p>
     <p>Product ID: {{device.product_id}}</p>
-    <p>Serial Number: {{device.serial_number}}</p>
 </h6>
+<h4>Serial Number: {{device.serial_number}}</h4>
 <form action="/devices-web/{{device.id}}" method="post">
   <label for="lic">Licenses:</label>
   <select id="lic" name="lic">
       {% for license in licenses %}
-    <option value={{license.id}}>{{license.name}}</option>
+    <option value={{license.id}}>{{license.name}} : {{license.license_id}}</option>
       {% endfor %}
   </select>
   <input type="submit" value="Connect">
 </form>
+<div style='padding-top:20px'>
 <form action="/devices-web-del/{{device.id}}" method="post">
   <label for="lic_del">Licenses:</label>
   <select id="lic_del" name="lic_del">
       {% for license in dev_lic %}
-    <option value={{license.id}}>{{license.name}}</option>
+    <option value={{license.id}}>{{license.name}} : {{license.license_id}}</option>
       {% endfor %}
   </select>
   <input type="submit" value="Delete">
 </form>
+</div>
+<div style='padding-top:20px'>
+<form action="/devices-web-team/{{device.id}}" method="post">
+  <label for="team_con">Teams:</label>
+  <select id="team_con" name="team_con">
+      {% for team in teams %}
+    <option value={{team.id}}>{{team.name}}</option>
+      {% endfor %}
+  </select>
+  <input type="submit" value="Connect">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/devices-web-inv/{{device.id}}" method="post">
+  <label for="dev_inv">Inventory Number:</label><br>
+  <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}">
+  <input type="submit" value="Submit">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/devices-web-comment/{{device.id}}" method="post">
+  <label for="dev_com">Comment:</label><br>
+  <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}">
+  <input type="submit" value="Submit">
+</form>
+</div>
 </body>
 </html>
\ No newline at end of file
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index e2f0bb7..33a1a21 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Devices Details</title>
 </head>
 <body>
@@ -22,10 +46,9 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
-      <option value="/devices-web">Devices</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
+      <option value="/devices-web" selected>Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
@@ -35,49 +58,65 @@
   <input type="submit" value="OK">
 </form>
 <form action="/devices-web" method="post">
-    <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
-    <datalist id="licenses">
+    <label for="keyman_id">Keyman ID:</label>
+    <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="" placeholder="all">
+    <datalist id="keyman_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_name">License Name:</label>
+    <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all">
+    <datalist id="licenses_names">
         {% for license in licenses %}
         <option value="{{license.name}}"></option>
         {% endfor %}
     </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <datalist id="licenses_ids">
+        {% for license in licenses %}
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
+        {% endfor %}
+    </datalist>
   <input type="submit" value="Filter">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
-        <TH>Vendor ID</TH>
-        <TH>Product ID</TH>
-        <TH>Serial Number</TH>
-        <TH>Licenses</TH>
+        <TH>Keyman ID</TH>
+        <TH>License Type</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
         <TH>Status</TH>
+        <TH>Comment</TH>
     </TR>
-    {% for i in range(devs) %}
+    {% for dev in devices %}
     <TR>
-        <TD class="ID"><a href="/device-license/{{devices[i].id}}">{{devices[i].id}}</a></TD>
-        <TD class="Vendor ID">{{devices[i].vendor_id}}</TD>
-        <TD class="Product ID">{{devices[i].product_id}}</TD>
-        <TD class="Serial Number">{{devices[i].serial_number}}</TD>
-        <TD class="License">
-            {% for lic in devices[i].licenses %}
-                {{lic.licenses.name}}<BR>
-            {% endfor %}
-        </TD>
-        <TD class="Status">{{statuses[i]}}</TD>
+        <TD class="ID"><a href="/device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD>
+        <TD class="Serial Number">{{dev['device'].serial_number}}</TD>
+        <TD class="License">{{dev['license'].name}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].pc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].pc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
     </TR>
     {% endfor %}
-    <TR>
-        <TD class="ID"></TD>
-        <TD class="Vendor ID"></TD>
-        <TD class="Product ID"></TD>
-        <TD class="Serial Number"></TD>
-        <TD class="License">
-            <form action="/license-create" method="get">
-                <input type="submit" value="Add">
-            </form>
-        </TD>
-    </TR>
 </table>
 </body>
 </html>
diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html
index 4e0813f..ac38f54 100644
--- a/server/templates/devices/devices_normal.html
+++ b/server/templates/devices/devices_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Devices Details</title>
 </head>
 <body>
@@ -22,10 +46,9 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
-      <option value="/devices-web">Devices</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
+      <option value="/devices-web" selected>Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
@@ -43,27 +66,33 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
-        <TH>Vendor ID</TH>
-        <TH>Product ID</TH>
-        <TH>Serial Number</TH>
-        <TH>Licenses</TH>
+        <TH>Keyman ID</TH>
+        <TH>License Type</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
         <TH>Status</TH>
+        <TH>Comment</TH>
     </TR>
-    {% for i in range(devs) %}
+    {% for dev in devices %}
     <TR>
-        <TD class="ID">{{devices[i].id}}</TD>
-        <TD class="Vendor ID">{{devices[i].vendor_id}}</TD>
-        <TD class="Product ID">{{devices[i].product_id}}</TD>
-        <TD class="Serial Number">{{devices[i].serial_number}}</TD>
-        <TD class="License">
-            {% for lic in devices[i].licenses %}
-                {{lic.licenses.name}}<BR>
-            {% endfor %}
-        </TD>
-        <TD class="Status">{{statuses[i]}}</TD>
+        <TD class="ID">{{dev['device'].id}}</TD>
+        <TD class="Serial Number">{{dev['device'].serial_number}}</TD>
+        <TD class="License">{{dev['license'].name}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].pc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].pc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html
index deda9b0..f7afdf1 100644
--- a/server/templates/ld-logs/ldlogs.html
+++ b/server/templates/ld-logs/ldlogs.html
@@ -22,9 +22,8 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web" selected>Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
@@ -66,8 +65,8 @@
         <TH>Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
-        <TH>Head Device Serial Number</TH>
-        <TH>Body Device Serial Number</TH>
+        <TH>Lauterbach Head ID</TH>
+        <TH>Lauterbach Body ID</TH>
     </TR>
     {% for log in logs %}
     <TR>
diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html
index 0487981..27060e6 100644
--- a/server/templates/ld-logs/ldlogs_normal.html
+++ b/server/templates/ld-logs/ldlogs_normal.html
@@ -22,9 +22,8 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web" selected>Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
@@ -65,8 +64,8 @@
         <TH>Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
-        <TH>Head Device Serial Number</TH>
-        <TH>Body Device Serial Number</TH>
+        <TH>Lauterbach Head ID</TH>
+        <TH>Lauterbach Body ID</TH>
     </TR>
     {% for log in logs %}
     <TR>
diff --git a/server/templates/licenses/license_create.html b/server/templates/licenses/license_create.html
index 861174a..707ce4e 100644
--- a/server/templates/licenses/license_create.html
+++ b/server/templates/licenses/license_create.html
@@ -8,6 +8,8 @@
 <form action="/licenses-web" method="post">
   <label for="name">Name:</label><br>
   <input type="text" id="name" name="name"><br><br>
+    <label for="lic_id">License ID:</label><br>
+  <input type="text" id="lic_id" name="lic_id"><br><br>
     <label for="expdate">Expiration Date</label>
   <input type="date" id="expdate" name="expdate" min={{minimum_date}}>
   <input type="submit" value="Submit">
diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html
index 57a9b61..05c0f43 100644
--- a/server/templates/licenses/licenses.html
+++ b/server/templates/licenses/licenses.html
@@ -22,14 +22,13 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
-      <option value="/licenses-web">Licenses</option>
+      <option value="/licenses-web" selected>Licenses</option>
       <option value="/users-web">Users</option>
   </select>
   <input type="submit" value="OK">
@@ -37,14 +36,16 @@
 <table>
     <TR>
         <TH>ID</TH>
-        <TH>Name</TH>
+        <TH>License Type</TH>
+        <TH>License ID</TH>
         <TH>Expiration Date</TH>
     </TR>
     {% for license in licenses %}
     <TR>
         <TD class="ID">{{license.id}}</TD>
-        <TD class="Vendor ID">{{license.name}}</TD>
-        <TD class="Product ID">{{license.expiration_date}}</TD>
+        <TD class="License Type">{{license.name}}</TD>
+        <TD class="License ID">{{license.license_id}}</TD>
+        <TD class="Expiration Date">{{license.expiration_date}}</TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/licenses/licenses_normal.html b/server/templates/licenses/licenses_normal.html
index 2f580d4..63414bc 100644
--- a/server/templates/licenses/licenses_normal.html
+++ b/server/templates/licenses/licenses_normal.html
@@ -22,14 +22,13 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
-      <option value="/licenses-web">Licenses</option>
+      <option value="/licenses-web" selected>Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
@@ -37,12 +36,14 @@
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
+        <TH>License ID</TH>
         <TH>Expiration Date</TH>
     </TR>
     {% for license in licenses %}
     <TR>
         <TD class="ID">{{license.id}}</TD>
         <TD class="Vendor ID">{{license.name}}</TD>
+        <TD class="License ID">{{license.license_id}}</TD>
         <TD class="Product ID">{{license.expiration_date}}</TD>
     </TR>
     {% endfor %}
diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html
index 72295e2..89abe1a 100644
--- a/server/templates/pcs/pcs.html
+++ b/server/templates/pcs/pcs.html
@@ -22,13 +22,12 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
-      <option value="/pcs-web">PCs</option>
+      <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
       <option value="/users-web">Users</option>
   </select>
@@ -39,18 +38,12 @@
         <TH>ID</TH>
         <TH>Username</TH>
         <TH>Hostname</TH>
-        <TH>Team</TH>
     </TR>
     {% for pc in pcs %}
     <TR>
-        <TD class="ID"><a href="/pc-team/{{pc.id}}">{{pc.id}}</a></TD>
-        <TD class="Vendor ID">{{pc.username}}</TD>
-        <TD class="Product ID">{{pc.hostname}}</TD>
-        {% if pc.team == None %}
-            <TD class="Team">NONE</TD>
-        {% else %}
-            <TD class="Team">{{pc.team.name}}</TD>
-        {% endif %}
+        <TD class="ID">{{pc.id}}</TD>
+        <TD class="Username">{{pc.username}}</TD>
+        <TD class="Hostname">{{pc.hostname}}</TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html
index b6b6cd5..b41000e 100644
--- a/server/templates/pcs/pcs_normal.html
+++ b/server/templates/pcs/pcs_normal.html
@@ -22,13 +22,12 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
-      <option value="/pcs-web">PCs</option>
+      <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
@@ -38,18 +37,12 @@
         <TH>ID</TH>
         <TH>Username</TH>
         <TH>Hostname</TH>
-        <TH>Team</TH>
     </TR>
     {% for pc in pcs %}
     <TR>
         <TD class="ID">{{pc.id}}</TD>
-        <TD class="Vendor ID">{{pc.username}}</TD>
-        <TD class="Product ID">{{pc.hostname}}</TD>
-        {% if pc.team == None %}
-            <TD class="Team">NONE</TD>
-        {% else %}
-            <TD class="Team">{{pc.team.name}}</TD>
-        {% endif %}
+        <TD class="Username">{{pc.username}}</TD>
+        <TD class="Hostname">{{pc.hostname}}</TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/teams/team_change.html b/server/templates/teams/team_change.html
new file mode 100644
index 0000000..3ef6f23
--- /dev/null
+++ b/server/templates/teams/team_change.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Change team name</title>
+</head>
+<body>
+<h4>Team: {{team.name}}</h4>
+<form action="/teams-change-process/{{team.id}}" method="post">
+  <label for="name">Name:</label><br>
+  <input type="text" id="name" name="name"><br><br>
+  <input type="submit" value="Submit">
+</form>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html
index f6945e6..f16933b 100644
--- a/server/templates/teams/teams.html
+++ b/server/templates/teams/teams.html
@@ -22,12 +22,11 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
-      <option value="/teams-web">Teams</option>
+      <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
       <option value="/users-web">Users</option>
@@ -38,17 +37,11 @@
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
-        <TH>Members</TH>
     </TR>
     {% for team in teams %}
     <TR>
-        <TD class="ID">{{team.id}}</TD>
+        <TD class="ID"><a href="/team-change/{{team.id}}">{{team.id}}</a></TD>
         <TD class="Name">{{team.name}}</TD>
-        <TD class="Members">
-        {% for ppl in team.pcs %}
-            {{ppl.username}}<BR>
-        {% endfor %}
-        </TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html
index d25b5b9..a10f217 100644
--- a/server/templates/teams/teams_normal.html
+++ b/server/templates/teams/teams_normal.html
@@ -22,12 +22,11 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
-      <option value="/teams-web">Teams</option>
+      <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
   </select>
@@ -37,17 +36,11 @@
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
-        <TH>Members</TH>
     </TR>
     {% for team in teams %}
     <TR>
         <TD class="ID">{{team.id}}</TD>
         <TD class="Vendor ID">{{team.name}}</TD>
-        <TD class="Members">
-        {% for ppl in team.pcs %}
-            {{ppl.username}}<BR>
-        {% endfor %}
-        </TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index 4f1bb07..a9d6901 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -22,9 +22,8 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web" selected>Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
@@ -66,8 +65,7 @@
         <TH>Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
-        <TH>Device Product ID</TH>
-        <TH>Device Serial Number</TH>
+        <TH>Keyman ID</TH>
     </TR>
     {% for log in logs %}
     <TR>
@@ -77,11 +75,10 @@
         {% if log.pc.team == None %}
             <TD class="Team">NONE</TD>
         {% else %}
-            <TD class="Team">{{log.pc.team.name}}</TD>
+            <TD class="Team">{{log.device.team.name}}</TD>
         {% endif %}
         <TD class="Timestamp">{{log.timestamp}}</TD>
         <TD class="Status">{{log.status}}</TD>
-        <TD class="DeviceProductID">{{log.device.product_id}}</TD>
         <TD class="DeviceSerialNumber">{{log.device.serial_number}}</TD>
     </TR>
     {% endfor %}
diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html
index aaf52e8..5132d64 100644
--- a/server/templates/usb-logs/logs_normal.html
+++ b/server/templates/usb-logs/logs_normal.html
@@ -22,9 +22,8 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web" selected>Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
@@ -65,8 +64,7 @@
         <TH>Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
-        <TH>Device Product ID</TH>
-        <TH>Device Serial Number</TH>
+        <TH>Keyman ID</TH>
     </TR>
     {% for log in logs %}
     <TR>
@@ -76,11 +74,10 @@
         {% if log.pc.team == None %}
             <TD class="Team">NONE</TD>
         {% else %}
-            <TD class="Team">{{log.pc.team.name}}</TD>
+            <TD class="Team">{{log.device.team.name}}</TD>
         {% endif %}
         <TD class="Timestamp">{{log.timestamp}}</TD>
         <TD class="Status">{{log.status}}</TD>
-        <TD class="DeviceProductID">{{log.device.product_id}}</TD>
         <TD class="DeviceSerialNumber">{{log.device.serial_number}}</TD>
     </TR>
     {% endfor %}
diff --git a/server/templates/users/users.html b/server/templates/users/users.html
index dfb9e87..9952d85 100644
--- a/server/templates/users/users.html
+++ b/server/templates/users/users.html
@@ -19,15 +19,14 @@
 <form action="" method="get">
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
-      <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Devices</option>
       <option value="/body-devices-web">Body Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
-      <option value="/users-web">Users</option>
+      <option value="/users-web" selected>Users</option>
   </select>
   <input type="submit" value="OK">
 </form>
-- 
GitLab


From 6ad54e2e2e472842cac061f7627cdd35cb1f25da Mon Sep 17 00:00:00 2001
From: "zemanm98@students.zcu.cz" <Farnhait123*>
Date: Sat, 14 May 2022 21:22:15 +0200
Subject: [PATCH 63/67] Changed looks of tables with simple css. Added
 inventory number and comment to Lauterbach devices. Changed connection
 between lauterbach devices and license.

---
 server/sql_app/api/devices.py                 |  2 +-
 server/sql_app/api/licenses_web.py            |  2 +-
 server/sql_app/crud.py                        |  8 ++--
 server/sql_app/models.py                      | 43 ++++++++++---------
 server/sql_app/schemas.py                     | 19 ++++++--
 .../templates/body-devices/body_devices.html  | 30 +++++++++++--
 .../body-devices/body_devices_normal.html     | 30 +++++++++++--
 server/templates/devices/devices.html         |  6 +--
 server/templates/devices/devices_normal.html  |  4 +-
 server/templates/ld-logs/ldlogs.html          | 30 +++++++++++--
 server/templates/ld-logs/ldlogs_normal.html   | 30 +++++++++++--
 server/templates/licenses/licenses.html       | 30 +++++++++++--
 .../templates/licenses/licenses_normal.html   | 30 +++++++++++--
 server/templates/pcs/pcs.html                 | 30 +++++++++++--
 server/templates/pcs/pcs_normal.html          | 30 +++++++++++--
 server/templates/teams/teams.html             | 30 +++++++++++--
 server/templates/teams/teams_normal.html      | 30 +++++++++++--
 server/templates/usb-logs/crossroad.html      |  8 ++--
 server/templates/usb-logs/logs.html           | 30 +++++++++++--
 server/templates/usb-logs/logs_normal.html    | 30 +++++++++++--
 server/templates/users/users.html             | 30 +++++++++++--
 21 files changed, 405 insertions(+), 77 deletions(-)

diff --git a/server/sql_app/api/devices.py b/server/sql_app/api/devices.py
index ec5f3dc..24b6c17 100644
--- a/server/sql_app/api/devices.py
+++ b/server/sql_app/api/devices.py
@@ -21,7 +21,7 @@ def get_db():
 
 
 @device.post("/device", response_model=schemas.Device)
-def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
+def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)):
     """
     Endpoint used for creating new device
     """
diff --git a/server/sql_app/api/licenses_web.py b/server/sql_app/api/licenses_web.py
index 3d9bdf5..64a4ec7 100644
--- a/server/sql_app/api/licenses_web.py
+++ b/server/sql_app/api/licenses_web.py
@@ -60,7 +60,7 @@ async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, d
                                                             "user": current_user})
 
 @licenses_web.post("/licenses-web")
-def create_license(name: str = Form(...), lic_id: str = Form(...), expdate: Optional[date] = Form(None),
+def create_license(name: Optional[str] = Form(""), lic_id: str = Form(...), expdate: Optional[date] = Form(None),
                    db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint called from create license form. Creates new license and redirects to devices-web endpoint
diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py
index d20873b..6892343 100644
--- a/server/sql_app/crud.py
+++ b/server/sql_app/crud.py
@@ -376,14 +376,14 @@ def get_head_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.HeadDevice).offset(skip).limit(limit).all()
 
 
-def find_head_device(db: Session, serial: schemas.HeadDeviceBase):
+def find_head_device(db: Session, serial: schemas.HeadDeviceTemp):
     """
     Finds one head device by its serial number
     """
     return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()
 
 
-def create_head_device(db: Session, log: schemas.HeadDeviceBase):
+def create_head_device(db: Session, log: schemas.HeadDeviceTemp):
     """
     Creates new head device
     """
@@ -408,14 +408,14 @@ def get_body_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.BodyDevice).offset(skip).limit(limit).all()
 
 
-def find_body_device(db: Session, serial: schemas.BodyDeviceBase):
+def find_body_device(db: Session, serial: schemas.BodyDeviceTemp):
     """
     Finds one body device by its serial number
     """
     return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()
 
 
-def create_body_device(db: Session, log: schemas.BodyDeviceBase):
+def create_body_device(db: Session, log: schemas.BodyDeviceTemp):
     """
     Creates new Body device
     """
diff --git a/server/sql_app/models.py b/server/sql_app/models.py
index e3e40a5..9c8225b 100644
--- a/server/sql_app/models.py
+++ b/server/sql_app/models.py
@@ -25,6 +25,7 @@ class Device(Base):
     licenses = relationship("DeviceLicense", back_populates="device_lic")
     team = relationship("Team", back_populates="devices")
 
+
 class USBLog(Base):
     """
     Class defining database table usb_logs
@@ -50,13 +51,15 @@ class License(Base):
     __tablename__ = "licenses"
 
     id = Column(Integer, primary_key=True, index=True)
-    name = Column(String, index=True, nullable=False)
+    name = Column(String, index=True, nullable=True)
     license_id = Column(String, index=True, nullable=False)
     expiration_date = Column(DateTime(timezone=True), nullable=True)
 
     # relationships for foreign keys, thus connecting table with devices table
     devices = relationship("DeviceLicense", back_populates="licenses")
-    body_devices = relationship("BodyDeviceLicense", back_populates="b_licenses")
+    bodydevice_lic = relationship("BodyDevice", back_populates="license")
+    headdevice_lic = relationship("HeadDevice", back_populates="license")
+
 
 class DeviceLicense(Base):
     """
@@ -75,23 +78,6 @@ class DeviceLicense(Base):
     licenses = relationship("License", back_populates="devices")
 
 
-class BodyDeviceLicense(Base):
-    """
-    Class defining database table bodydevices_licenses
-    """
-    __tablename__ = "bodydevices_licenses"
-
-    id = Column(Integer, primary_key=True, index=True)
-    bodydevice_id = Column(Integer, ForeignKey("body_devices.id"))
-    license_id = Column(Integer, ForeignKey("licenses.id"))
-    assigned_datetime = Column(String, index=True, nullable=False)
-
-    # relationships for foreign keys, thus connecting table with devices and licenses
-    # tables
-    bodydevice_lic = relationship("BodyDevice", back_populates="debug_licenses")
-    b_licenses = relationship("License", back_populates="body_devices")
-
-
 class PC(Base):
     """
     Class defining database table pc
@@ -118,6 +104,9 @@ class Team(Base):
     name = Column(String, index=True, nullable=False)
 
     devices = relationship("Device", back_populates="team")
+    body_devices = relationship("BodyDevice", back_populates="team")
+    head_devices = relationship("HeadDevice", back_populates="team")
+
 
 class HeadDevice(Base):
     """
@@ -127,9 +116,16 @@ class HeadDevice(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey("teams.id"))
+    license_id = Column(Integer, ForeignKey("licenses.id"))
 
     # relationships for foreign keys, thus connecting table with ld_logs table
     h_logs = relationship("LDLog", back_populates="head_device")
+    license = relationship("License", back_populates="headdevice_lic")
+    team = relationship("Team", back_populates="head_devices")
 
 
 class BodyDevice(Base):
@@ -140,10 +136,16 @@ class BodyDevice(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey("teams.id"))
+    license_id = Column(Integer, ForeignKey("licenses.id"))
 
     # relationships for foreign keys, thus connecting table with ld_logs table
     b_logs = relationship("LDLog", back_populates="body_device")
-    debug_licenses = relationship("BodyDeviceLicense", back_populates="bodydevice_lic")
+    license = relationship("License", back_populates="bodydevice_lic")
+    team = relationship("Team", back_populates="body_devices")
 
 
 class LDLog(Base):
@@ -165,6 +167,7 @@ class LDLog(Base):
     head_device = relationship("HeadDevice", back_populates="h_logs")
     body_device = relationship("BodyDevice", back_populates="b_logs")
 
+
 class User(Base):
     """
     Class defining user in database with its own role
diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py
index 4a7e381..eeab5a6 100644
--- a/server/sql_app/schemas.py
+++ b/server/sql_app/schemas.py
@@ -97,6 +97,8 @@ class LDLog(LDLogCreate):
 
 class BodyDeviceBase(BaseModel):
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class BodyDeviceCreate(BodyDeviceBase):
@@ -114,8 +116,14 @@ class BodyDevice(BodyDeviceCreate):
         orm_mode = True
 
 
+class BodyDeviceTemp(BaseModel):
+    serial_number: str
+
+
 class HeadDeviceBase(BaseModel):
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class HeadDeviceCreate(HeadDeviceBase):
@@ -133,6 +141,10 @@ class HeadDevice(HeadDeviceCreate):
         orm_mode = True
 
 
+class HeadDeviceTemp(BaseModel):
+    serial_number: str
+
+
 class PCBase(BaseModel):
     username: str
     hostname: str
@@ -189,6 +201,8 @@ class License(LicenseCreate):
     """
     id: int
     devices: List[DeviceLicense] = []
+    head_devices: List[HeadDevice] = []
+    body_devices: List[BodyDevice] = []
 
     class Config:
         orm_mode = True
@@ -224,8 +238,8 @@ class LDTempBase(BaseModel):
     username: str
     hostname: str
     timestamp: str
-    head_device: HeadDeviceBase
-    body_device: BodyDeviceBase
+    head_device: HeadDeviceTemp
+    body_device: BodyDeviceTemp
     status: str
 
 
@@ -260,4 +274,3 @@ class User(UserCreate):
 
     class Config:
         orm_mode = True
-
diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html
index 255a851..a929689 100644
--- a/server/templates/body-devices/body_devices.html
+++ b/server/templates/body-devices/body_devices.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Devices Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web" selected>Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web" selected>Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -43,7 +67,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Lauterbach Body ID</TH>
diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html
index 8a3452e..db8159f 100644
--- a/server/templates/body-devices/body_devices_normal.html
+++ b/server/templates/body-devices/body_devices_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Devices Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web" selected>Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web" selected>Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -42,7 +66,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Lauterbach Body ID</TH>
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index 33a1a21..b0e09e2 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -48,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web" selected>Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web" selected>Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -65,7 +65,7 @@
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
-    <label for="lic_name">License Name:</label>
+    <label for="lic_name">License Type:</label>
     <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all">
     <datalist id="licenses_names">
         {% for license in licenses %}
diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html
index ac38f54..abd3400 100644
--- a/server/templates/devices/devices_normal.html
+++ b/server/templates/devices/devices_normal.html
@@ -48,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web" selected>Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web" selected>Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html
index f7afdf1..7723f2a 100644
--- a/server/templates/ld-logs/ldlogs.html
+++ b/server/templates/ld-logs/ldlogs.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title> LD Logs Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web" selected>Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -57,7 +81,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-    <table>
+    <table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>PC Username</TH>
diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html
index 27060e6..303b83f 100644
--- a/server/templates/ld-logs/ldlogs_normal.html
+++ b/server/templates/ld-logs/ldlogs_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title> LD Logs Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web" selected>Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -56,7 +80,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-    <table>
+    <table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>PC Username</TH>
diff --git a/server/templates/licenses/licenses.html b/server/templates/licenses/licenses.html
index 05c0f43..1970c77 100644
--- a/server/templates/licenses/licenses.html
+++ b/server/templates/licenses/licenses.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Licenses Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web" selected>Licenses</option>
@@ -33,7 +57,7 @@
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>License Type</TH>
diff --git a/server/templates/licenses/licenses_normal.html b/server/templates/licenses/licenses_normal.html
index 63414bc..2656650 100644
--- a/server/templates/licenses/licenses_normal.html
+++ b/server/templates/licenses/licenses_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Licenses Details</title>
 </head>
 <body>
@@ -24,15 +48,15 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web" selected>Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html
index 89abe1a..a723452 100644
--- a/server/templates/pcs/pcs.html
+++ b/server/templates/pcs/pcs.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Pcs Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -33,7 +57,7 @@
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Username</TH>
diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html
index b41000e..1ca892d 100644
--- a/server/templates/pcs/pcs_normal.html
+++ b/server/templates/pcs/pcs_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Pcs Details</title>
 </head>
 <body>
@@ -24,15 +48,15 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Username</TH>
diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html
index f16933b..6957999 100644
--- a/server/templates/teams/teams.html
+++ b/server/templates/teams/teams.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Teams Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -33,7 +57,7 @@
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html
index a10f217..c928f52 100644
--- a/server/templates/teams/teams_normal.html
+++ b/server/templates/teams/teams_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Teams Details</title>
 </head>
 <body>
@@ -24,15 +48,15 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Name</TH>
diff --git a/server/templates/usb-logs/crossroad.html b/server/templates/usb-logs/crossroad.html
index f553dc4..01db9b9 100644
--- a/server/templates/usb-logs/crossroad.html
+++ b/server/templates/usb-logs/crossroad.html
@@ -9,10 +9,10 @@
   <label for="view">Choose view:</label>
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value=""></option>
-      <option value="/logs-web">Logs</option>
-      <option value="/ldlogs-web">LD Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index a9d6901..34e14cd 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Logs Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web" selected>Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -57,7 +81,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-    <table>
+    <table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>PC Username</TH>
diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html
index 5132d64..99c3a9c 100644
--- a/server/templates/usb-logs/logs_normal.html
+++ b/server/templates/usb-logs/logs_normal.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Logs Details</title>
 </head>
 <body>
@@ -24,8 +48,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web" selected>Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -56,7 +80,7 @@
     </datalist>
   <input type="submit" value="Filter">
 </form>
-    <table>
+    <table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>PC Username</TH>
diff --git a/server/templates/users/users.html b/server/templates/users/users.html
index 9952d85..6b56b9a 100644
--- a/server/templates/users/users.html
+++ b/server/templates/users/users.html
@@ -1,5 +1,29 @@
 <html>
 <head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
     <title>Users Details</title>
 </head>
 <body>
@@ -21,8 +45,8 @@
   <select id="view" name="view" onchange="this.form.action=this.value;">
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
-      <option value="/devices-web">Devices</option>
-      <option value="/body-devices-web">Body Devices</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -30,7 +54,7 @@
   </select>
   <input type="submit" value="OK">
 </form>
-<table>
+<table id="devices">
     <TR>
         <TH>ID</TH>
         <TH>Username</TH>
-- 
GitLab


From 0fcb708f3eec9a99bb4d6610105394abb368b1c1 Mon Sep 17 00:00:00 2001
From: Matej Zeman <zeman339@gmail.com>
Date: Sun, 15 May 2022 15:53:00 +0200
Subject: [PATCH 64/67] re #9846 Changed keyman devices, body devices views.
 Added Head devices view. Changed filtering of logs, ldlogs, body devices,
 head devices and keyman devices. Changed HTML tables style and few labels.

---
 server/doc/sql_app/api/auth.html              |  633 ++++++
 server/doc/sql_app/api/bodydevices_web.html   |  446 ++++
 server/doc/sql_app/api/devices.html           |    6 +-
 server/doc/sql_app/api/devices_web.html       |  445 +++-
 server/doc/sql_app/api/headdevices_web.html   |  440 ++++
 server/doc/sql_app/api/index.html             |   25 +
 server/doc/sql_app/api/ld_logs_web.html       |  237 ++
 server/doc/sql_app/api/licenses_web.html      |  120 +-
 server/doc/sql_app/api/pcs_web.html           |   93 +-
 server/doc/sql_app/api/teams_web.html         |  174 +-
 server/doc/sql_app/api/usb_logs.html          |    8 +-
 server/doc/sql_app/api/usb_logs_web.html      |   81 +-
 server/doc/sql_app/api/users_web.html         |  194 ++
 server/doc/sql_app/crud.html                  | 1914 +++++++++++++++--
 .../{documentation.html => index.html}        |    0
 server/doc/sql_app/main.html                  |   10 +
 server/doc/sql_app/models.html                | 1150 +++++++---
 server/doc/sql_app/schemas.html               |  430 +++-
 server/sql_app/api/auth.py                    |    9 +
 server/sql_app/api/bodydevices_web.py         |  126 +-
 server/sql_app/api/devices_web.py             |   31 +-
 server/sql_app/api/headdevices_web.py         |  169 ++
 server/sql_app/crud.py                        |  551 ++++-
 server/sql_app/main.py                        |    4 +-
 server/sql_app/schemas.py                     |    9 +
 server/templates/auth/login.html              |    6 +-
 server/templates/auth/signup.html             |    6 +-
 .../body-devices/body_device_license.html     |   37 +-
 .../templates/body-devices/body_devices.html  |   62 +-
 .../body-devices/body_devices_normal.html     |   53 +-
 server/templates/devices/devices.html         |    3 +-
 server/templates/devices/devices_normal.html  |    3 +-
 .../templates/head_devices/head_devices.html  |  114 +
 .../head_devices/head_devices_normal.html     |  113 +
 .../templates/head_devices/headlicense.html   |   49 +
 server/templates/ld-logs/ldlogs.html          |   15 +-
 server/templates/ld-logs/ldlogs_normal.html   |   17 +-
 server/templates/licenses/license_create.html |   10 +-
 server/templates/pcs/pcs.html                 |    3 +-
 server/templates/pcs/pcs_normal.html          |    3 +-
 server/templates/teams/team_change.html       |    4 +-
 server/templates/teams/team_create.html       |    4 +-
 server/templates/teams/teams.html             |    3 +-
 server/templates/teams/teams_normal.html      |    3 +-
 server/templates/usb-logs/crossroad.html      |   31 +-
 server/templates/usb-logs/logs.html           |    3 +-
 server/templates/usb-logs/logs_normal.html    |    3 +-
 server/templates/users/users.html             |    3 +-
 48 files changed, 6887 insertions(+), 966 deletions(-)
 create mode 100644 server/doc/sql_app/api/auth.html
 create mode 100644 server/doc/sql_app/api/bodydevices_web.html
 create mode 100644 server/doc/sql_app/api/headdevices_web.html
 create mode 100644 server/doc/sql_app/api/ld_logs_web.html
 create mode 100644 server/doc/sql_app/api/users_web.html
 rename server/doc/sql_app/{documentation.html => index.html} (100%)
 create mode 100644 server/sql_app/api/headdevices_web.py
 create mode 100644 server/templates/head_devices/head_devices.html
 create mode 100644 server/templates/head_devices/head_devices_normal.html
 create mode 100644 server/templates/head_devices/headlicense.html

diff --git a/server/doc/sql_app/api/auth.html b/server/doc/sql_app/api/auth.html
new file mode 100644
index 0000000..38a4bf7
--- /dev/null
+++ b/server/doc/sql_app/api/auth.html
@@ -0,0 +1,633 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>sql_app.api.auth API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>sql_app.api.auth</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">from fastapi import Depends, APIRouter, Form
+from fastapi import Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi.templating import Jinja2Templates
+from fastapi_jwt_auth import AuthJWT
+from sqlalchemy.orm import Session
+from sql_app import crud
+from passlib.context import CryptContext
+from pydantic import BaseModel
+from ..database import SessionLocal, engine
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory=&#34;../templates/auth&#34;)
+
+pwd_context = CryptContext(schemes=[&#34;bcrypt&#34;], deprecated=&#34;auto&#34;)
+
+# prefix used for all endpoints in this file
+auth = APIRouter(prefix=&#34;&#34;)
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+class Settings(BaseModel):
+    authjwt_secret_key: str = &#34;secret&#34;
+    # Configure application to store and get JWT from cookies
+    authjwt_token_location: set = {&#34;cookies&#34;}
+    # Disable CSRF Protection for this example. default is True
+    authjwt_cookie_csrf_protect: bool = False
+
+
+@AuthJWT.load_config
+def get_config():
+    return Settings()
+
+
+# admin username and password
+fake_users_db = {
+    &#34;admin&#34;: {
+        &#34;username&#34;: &#34;admin&#34;,
+        &#34;password&#34;: &#34;admin&#34;
+    }
+}
+
+
+def verify_password(plain_password, hashed_password):
+    &#34;&#34;&#34;
+    Verifies plain text password with hashed password
+    &#34;&#34;&#34;
+    return pwd_context.verify(plain_password, hashed_password)
+
+
+def get_hash_password(password):
+    &#34;&#34;&#34;
+    Returns hashed password
+    &#34;&#34;&#34;
+    return pwd_context.hash(password)
+
+
+def auth_user(db, username: str, password: str):
+    &#34;&#34;&#34;
+    Determines if given password belongs to user with given username
+    &#34;&#34;&#34;
+    user = crud.find_user(db, username)
+    if not user:
+        return None
+    if not verify_password(password, user.password):
+        return None
+    return user
+
+
+@auth.get(&#34;/signup&#34;, response_class=HTMLResponse)
+async def signup_get(request: Request):
+    &#34;&#34;&#34;
+    return html template for signup
+    &#34;&#34;&#34;
+    return templates.TemplateResponse(&#34;signup.html&#34;, {&#34;request&#34;: request})
+
+
+@auth.post(&#34;/signup&#34;, response_class=HTMLResponse)
+async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
+    &#34;&#34;&#34;
+    Endpoint called form signup template. Creates new user with role guest that can be changed by admin user
+    &#34;&#34;&#34;
+    users = crud.get_users(db, 0, 100)
+    users_names = []
+    for u in users:
+        users_names.append(u.username)
+    if username not in users_names:
+        new_user = crud.create_user(db, username, get_hash_password(password), &#34;guest&#34;)
+        if new_user is None:
+            print(&#34;something went wrong&#34;)
+        return &#34;&#34;&#34;
+            &lt;html&gt;
+                &lt;head&gt;
+                    &lt;title&gt;Signup&lt;/title&gt;
+                &lt;/head&gt;
+                &lt;body&gt;
+                    &lt;h1&gt;New user created. You can go back to previous page.&lt;/h1&gt;
+                    &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                        &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                    &lt;/form&gt;
+                &lt;/body&gt;
+            &lt;/html&gt;
+            &#34;&#34;&#34;
+    else:
+        return &#34;&#34;&#34;
+                    &lt;html&gt;
+                        &lt;head&gt;
+                            &lt;title&gt;Signup&lt;/title&gt;
+                        &lt;/head&gt;
+                        &lt;body&gt;
+                            &lt;h1&gt;Username taken. Try to choose different username.&lt;/h1&gt;
+                            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                            &lt;/form&gt;
+                        &lt;/body&gt;
+                    &lt;/html&gt;
+                    &#34;&#34;&#34;
+
+@auth.get(&#34;/login&#34;, response_class=HTMLResponse)
+async def login_get(request: Request):
+    &#34;&#34;&#34;
+    return html template for login
+    &#34;&#34;&#34;
+    return templates.TemplateResponse(&#34;login.html&#34;, {&#34;request&#34;: request})
+
+
+@auth.post(&#34;/login&#34;, response_class=HTMLResponse)
+async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
+                Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from login template. Checks if given username and password aligns with admin
+    username and password and returns token for browser according to given username and password
+    &#34;&#34;&#34;
+    user = auth_user(db, username, password)
+    if user != None:
+        if user.role == &#34;admin&#34;:
+            access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
+            refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
+        else:
+            access_token = Authorize.create_access_token(subject=&#34;guest&#34;, expires_time=False)
+            refresh_token = Authorize.create_refresh_token(subject=&#34;guest&#34;, expires_time=False)
+    else:
+        usr = fake_users_db.get(username)
+        if usr != None:
+            if usr[&#34;username&#34;] == username and usr[&#34;password&#34;] == password:
+                access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
+                refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
+        else:
+            return &#34;&#34;&#34;
+                &lt;html&gt;
+                    &lt;head&gt;
+                        &lt;title&gt;Login&lt;/title&gt;
+                    &lt;/head&gt;
+                    &lt;body&gt;
+                        &lt;h1&gt;Wrong Username or Password&lt;/h1&gt;
+                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
+                            &lt;input type=&#34;submit&#34; value=&#34;Log again&#34; /&gt;
+                        &lt;/form&gt;
+                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
+                            &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                        &lt;/form&gt;
+                    &lt;/body&gt;
+                &lt;/html&gt;
+                &#34;&#34;&#34;
+
+    # Set the JWT cookies in the response
+    Authorize.set_access_cookies(access_token)
+    Authorize.set_refresh_cookies(refresh_token)
+    return &#34;&#34;&#34;
+    &lt;html&gt;
+        &lt;head&gt;
+            &lt;title&gt;Login&lt;/title&gt;
+        &lt;/head&gt;
+        &lt;body&gt;
+            &lt;h1&gt;Now you are logged in, you can continue to previous page.&lt;/h1&gt;
+            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+            &lt;/form&gt;
+        &lt;/body&gt;
+    &lt;/html&gt;
+    &#34;&#34;&#34;
+
+
+@auth.post(&#39;/refresh&#39;)
+def refresh(Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
+    unlimited.
+    &#34;&#34;&#34;
+    Authorize.jwt_refresh_token_required()
+    current_user = Authorize.get_jwt_subject()
+    new_access_token = Authorize.create_access_token(subject=current_user)
+    # Set the JWT cookies in the response
+    Authorize.set_access_cookies(new_access_token)
+    return {&#34;msg&#34;: &#34;The token has been refresh&#34;}
+
+
+@auth.get(&#39;/logout&#39;, response_class=HTMLResponse)
+def logout(Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint for deleting cookie token with acces role.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+
+    Authorize.unset_jwt_cookies()
+    return &#34;&#34;&#34;
+        &lt;html&gt;
+            &lt;head&gt;
+                &lt;title&gt;Logout&lt;/title&gt;
+            &lt;/head&gt;
+            &lt;body&gt;
+                &lt;h1&gt;Logged Out&lt;/h1&gt;
+                &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                    &lt;input type=&#34;submit&#34; value=&#34;Back&#34; /&gt;
+                &lt;/form&gt;
+            &lt;/body&gt;
+        &lt;/html&gt;
+        &#34;&#34;&#34;</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="sql_app.api.auth.auth_user"><code class="name flex">
+<span>def <span class="ident">auth_user</span></span>(<span>db, username: str, password: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Determines if given password belongs to user with given username</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def auth_user(db, username: str, password: str):
+    &#34;&#34;&#34;
+    Determines if given password belongs to user with given username
+    &#34;&#34;&#34;
+    user = crud.find_user(db, username)
+    if not user:
+        return None
+    if not verify_password(password, user.password):
+        return None
+    return user</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.get_db"><code class="name flex">
+<span>def <span class="ident">get_db</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.get_hash_password"><code class="name flex">
+<span>def <span class="ident">get_hash_password</span></span>(<span>password)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns hashed password</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_hash_password(password):
+    &#34;&#34;&#34;
+    Returns hashed password
+    &#34;&#34;&#34;
+    return pwd_context.hash(password)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.login"><code class="name flex">
+<span>async def <span class="ident">login</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from login template. Checks if given username and password aligns with admin
+username and password and returns token for browser according to given username and password</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.post(&#34;/login&#34;, response_class=HTMLResponse)
+async def login(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db),
+                Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from login template. Checks if given username and password aligns with admin
+    username and password and returns token for browser according to given username and password
+    &#34;&#34;&#34;
+    user = auth_user(db, username, password)
+    if user != None:
+        if user.role == &#34;admin&#34;:
+            access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
+            refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
+        else:
+            access_token = Authorize.create_access_token(subject=&#34;guest&#34;, expires_time=False)
+            refresh_token = Authorize.create_refresh_token(subject=&#34;guest&#34;, expires_time=False)
+    else:
+        usr = fake_users_db.get(username)
+        if usr != None:
+            if usr[&#34;username&#34;] == username and usr[&#34;password&#34;] == password:
+                access_token = Authorize.create_access_token(subject=&#34;admin&#34;, expires_time=False)
+                refresh_token = Authorize.create_refresh_token(subject=&#34;admin&#34;, expires_time=False)
+        else:
+            return &#34;&#34;&#34;
+                &lt;html&gt;
+                    &lt;head&gt;
+                        &lt;title&gt;Login&lt;/title&gt;
+                    &lt;/head&gt;
+                    &lt;body&gt;
+                        &lt;h1&gt;Wrong Username or Password&lt;/h1&gt;
+                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
+                            &lt;input type=&#34;submit&#34; value=&#34;Log again&#34; /&gt;
+                        &lt;/form&gt;
+                        &lt;form action=&#34;/login&#34; method=&#34;get&#34;&gt;
+                            &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                        &lt;/form&gt;
+                    &lt;/body&gt;
+                &lt;/html&gt;
+                &#34;&#34;&#34;
+
+    # Set the JWT cookies in the response
+    Authorize.set_access_cookies(access_token)
+    Authorize.set_refresh_cookies(refresh_token)
+    return &#34;&#34;&#34;
+    &lt;html&gt;
+        &lt;head&gt;
+            &lt;title&gt;Login&lt;/title&gt;
+        &lt;/head&gt;
+        &lt;body&gt;
+            &lt;h1&gt;Now you are logged in, you can continue to previous page.&lt;/h1&gt;
+            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+            &lt;/form&gt;
+        &lt;/body&gt;
+    &lt;/html&gt;
+    &#34;&#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.login_get"><code class="name flex">
+<span>async def <span class="ident">login_get</span></span>(<span>request: starlette.requests.Request)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>return html template for login</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.get(&#34;/login&#34;, response_class=HTMLResponse)
+async def login_get(request: Request):
+    &#34;&#34;&#34;
+    return html template for login
+    &#34;&#34;&#34;
+    return templates.TemplateResponse(&#34;login.html&#34;, {&#34;request&#34;: request})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.logout"><code class="name flex">
+<span>def <span class="ident">logout</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint for deleting cookie token with acces role.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.get(&#39;/logout&#39;, response_class=HTMLResponse)
+def logout(Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint for deleting cookie token with acces role.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+
+    Authorize.unset_jwt_cookies()
+    return &#34;&#34;&#34;
+        &lt;html&gt;
+            &lt;head&gt;
+                &lt;title&gt;Logout&lt;/title&gt;
+            &lt;/head&gt;
+            &lt;body&gt;
+                &lt;h1&gt;Logged Out&lt;/h1&gt;
+                &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                    &lt;input type=&#34;submit&#34; value=&#34;Back&#34; /&gt;
+                &lt;/form&gt;
+            &lt;/body&gt;
+        &lt;/html&gt;
+        &#34;&#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.refresh"><code class="name flex">
+<span>def <span class="ident">refresh</span></span>(<span>Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
+unlimited.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.post(&#39;/refresh&#39;)
+def refresh(Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    endpoint for refreshing browser token. Not used at the moment since lifetime of given tokens are
+    unlimited.
+    &#34;&#34;&#34;
+    Authorize.jwt_refresh_token_required()
+    current_user = Authorize.get_jwt_subject()
+    new_access_token = Authorize.create_access_token(subject=current_user)
+    # Set the JWT cookies in the response
+    Authorize.set_access_cookies(new_access_token)
+    return {&#34;msg&#34;: &#34;The token has been refresh&#34;}</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.signup"><code class="name flex">
+<span>async def <span class="ident">signup</span></span>(<span>username: str = Form(Ellipsis), password: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called form signup template. Creates new user with role guest that can be changed by admin user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.post(&#34;/signup&#34;, response_class=HTMLResponse)
+async def signup(username: str = Form(...), password: str = Form(...), db: Session = Depends(get_db)):
+    &#34;&#34;&#34;
+    Endpoint called form signup template. Creates new user with role guest that can be changed by admin user
+    &#34;&#34;&#34;
+    users = crud.get_users(db, 0, 100)
+    users_names = []
+    for u in users:
+        users_names.append(u.username)
+    if username not in users_names:
+        new_user = crud.create_user(db, username, get_hash_password(password), &#34;guest&#34;)
+        if new_user is None:
+            print(&#34;something went wrong&#34;)
+        return &#34;&#34;&#34;
+            &lt;html&gt;
+                &lt;head&gt;
+                    &lt;title&gt;Signup&lt;/title&gt;
+                &lt;/head&gt;
+                &lt;body&gt;
+                    &lt;h1&gt;New user created. You can go back to previous page.&lt;/h1&gt;
+                    &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                        &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                    &lt;/form&gt;
+                &lt;/body&gt;
+            &lt;/html&gt;
+            &#34;&#34;&#34;
+    else:
+        return &#34;&#34;&#34;
+                    &lt;html&gt;
+                        &lt;head&gt;
+                            &lt;title&gt;Signup&lt;/title&gt;
+                        &lt;/head&gt;
+                        &lt;body&gt;
+                            &lt;h1&gt;Username taken. Try to choose different username.&lt;/h1&gt;
+                            &lt;form action=&#34;/logs-web&#34; method=&#34;get&#34;&gt;
+                                &lt;input type=&#34;submit&#34; value=&#34;Home Page&#34; /&gt;
+                            &lt;/form&gt;
+                        &lt;/body&gt;
+                    &lt;/html&gt;
+                    &#34;&#34;&#34;</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.signup_get"><code class="name flex">
+<span>async def <span class="ident">signup_get</span></span>(<span>request: starlette.requests.Request)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>return html template for signup</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@auth.get(&#34;/signup&#34;, response_class=HTMLResponse)
+async def signup_get(request: Request):
+    &#34;&#34;&#34;
+    return html template for signup
+    &#34;&#34;&#34;
+    return templates.TemplateResponse(&#34;signup.html&#34;, {&#34;request&#34;: request})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.auth.verify_password"><code class="name flex">
+<span>def <span class="ident">verify_password</span></span>(<span>plain_password, hashed_password)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Verifies plain text password with hashed password</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def verify_password(plain_password, hashed_password):
+    &#34;&#34;&#34;
+    Verifies plain text password with hashed password
+    &#34;&#34;&#34;
+    return pwd_context.verify(plain_password, hashed_password)</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+<h2 class="section-title" id="header-classes">Classes</h2>
+<dl>
+<dt id="sql_app.api.auth.Settings"><code class="flex name class">
+<span>class <span class="ident">Settings</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class Settings(BaseModel):
+    authjwt_secret_key: str = &#34;secret&#34;
+    # Configure application to store and get JWT from cookies
+    authjwt_token_location: set = {&#34;cookies&#34;}
+    # Disable CSRF Protection for this example. default is True
+    authjwt_cookie_csrf_protect: bool = False</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect"><code class="name">var <span class="ident">authjwt_cookie_csrf_protect</span> : bool</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.api.auth.Settings.authjwt_secret_key"><code class="name">var <span class="ident">authjwt_secret_key</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.api.auth.Settings.authjwt_token_location"><code class="name">var <span class="ident">authjwt_token_location</span> : set</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
+</dl>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="two-column">
+<li><code><a title="sql_app.api.auth.auth_user" href="#sql_app.api.auth.auth_user">auth_user</a></code></li>
+<li><code><a title="sql_app.api.auth.get_db" href="#sql_app.api.auth.get_db">get_db</a></code></li>
+<li><code><a title="sql_app.api.auth.get_hash_password" href="#sql_app.api.auth.get_hash_password">get_hash_password</a></code></li>
+<li><code><a title="sql_app.api.auth.login" href="#sql_app.api.auth.login">login</a></code></li>
+<li><code><a title="sql_app.api.auth.login_get" href="#sql_app.api.auth.login_get">login_get</a></code></li>
+<li><code><a title="sql_app.api.auth.logout" href="#sql_app.api.auth.logout">logout</a></code></li>
+<li><code><a title="sql_app.api.auth.refresh" href="#sql_app.api.auth.refresh">refresh</a></code></li>
+<li><code><a title="sql_app.api.auth.signup" href="#sql_app.api.auth.signup">signup</a></code></li>
+<li><code><a title="sql_app.api.auth.signup_get" href="#sql_app.api.auth.signup_get">signup_get</a></code></li>
+<li><code><a title="sql_app.api.auth.verify_password" href="#sql_app.api.auth.verify_password">verify_password</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-classes">Classes</a></h3>
+<ul>
+<li>
+<h4><code><a title="sql_app.api.auth.Settings" href="#sql_app.api.auth.Settings">Settings</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.api.auth.Settings.authjwt_cookie_csrf_protect" href="#sql_app.api.auth.Settings.authjwt_cookie_csrf_protect">authjwt_cookie_csrf_protect</a></code></li>
+<li><code><a title="sql_app.api.auth.Settings.authjwt_secret_key" href="#sql_app.api.auth.Settings.authjwt_secret_key">authjwt_secret_key</a></code></li>
+<li><code><a title="sql_app.api.auth.Settings.authjwt_token_location" href="#sql_app.api.auth.Settings.authjwt_token_location">authjwt_token_location</a></code></li>
+</ul>
+</li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/doc/sql_app/api/bodydevices_web.html b/server/doc/sql_app/api/bodydevices_web.html
new file mode 100644
index 0000000..958001a
--- /dev/null
+++ b/server/doc/sql_app/api/bodydevices_web.html
@@ -0,0 +1,446 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>sql_app.api.bodydevices_web API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>sql_app.api.bodydevices_web</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">from datetime import datetime
+
+from fastapi import Depends, APIRouter, Form
+from fastapi import Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi.templating import Jinja2Templates
+from fastapi_jwt_auth import AuthJWT
+from pydantic import BaseModel
+from sqlalchemy.orm import Session
+from sql_app.api.auth import fake_users_db
+from sql_app import crud, models
+from ..database import SessionLocal, engine
+
+models.Base.metadata.create_all(bind=engine)
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory=&#34;../templates/body-devices&#34;)
+
+# prefix used for all endpoints in this file
+body_device_web = APIRouter(prefix=&#34;&#34;)
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@body_device_web.get(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all body devices and necessary attributes
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
+    devices = crud.get_body_devices(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+
+
+@body_device_web.post(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering body devices by user given inputs. returns html template with only
+    body devices that has attributes defined by user input
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_bodydevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
+                                                                       &#34;licenses&#34;: licenses,
+                                                                       &#34;user&#34;: current_user})
+
+
+@body_device_web.get(&#34;/body-device-license/{device_id}&#34;, response_class=HTMLResponse)
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
+    that can be assigned to device, inventory number and comment text input for this device.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    device = crud.get_body_device(db, device_id)
+    licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic != device.license:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
+    return templates.TemplateResponse(&#34;body_device_license.html&#34;,
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})
+
+
+@body_device_web.post(&#34;/body-devices-web-lic/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template. Connects body device with license
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_license(db, device_id, int(lic))
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
+
+
+@body_device_web.post(&#34;/body-devices-web-team/{device_id}&#34;)
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template, connects device with new team
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
+
+
+@body_device_web.post(&#34;/body-devices-inv/{device_id}&#34;)
+async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template, updates devices inventory number
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)
+
+
+@body_device_web.post(&#34;/body-devices-comm/{device_id}&#34;)
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template, updates devices comment
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="sql_app.api.bodydevices_web.connect_dev_lic"><code class="name flex">
+<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
+that can be assigned to device, inventory number and comment text input for this device.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.get(&#34;/body-device-license/{device_id}&#34;, response_class=HTMLResponse)
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
+    that can be assigned to device, inventory number and comment text input for this device.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    device = crud.get_body_device(db, device_id)
+    licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic != device.license:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
+    return templates.TemplateResponse(&#34;body_device_license.html&#34;,
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.connect_post"><code class="name flex">
+<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template from body_device_license.html template. Connects body device with license
+and redirects to body-devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.post(&#34;/body-devices-web-lic/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template. Connects body device with license
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_license(db, device_id, int(lic))
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.delete_post"><code class="name flex">
+<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template from body_device_license.html template, connects device with new team
+and redirects to body-devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.post(&#34;/body-devices-web-team/{device_id}&#34;)
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template, connects device with new team
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.device_inv"><code class="name flex">
+<span>async def <span class="ident">device_inv</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template from body_device_license.html template, updates devices comment
+and redirects to body-devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.post(&#34;/body-devices-comm/{device_id}&#34;)
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template from body_device_license.html template, updates devices comment
+    and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_bodydevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/body-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.filter_devices"><code class="name flex">
+<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, body_id: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint used for filtering body devices by user given inputs. returns html template with only
+body devices that has attributes defined by user input</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.post(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering body devices by user given inputs. returns html template with only
+    body devices that has attributes defined by user input
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_bodydevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
+                                                                       &#34;licenses&#34;: licenses,
+                                                                       &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.get_db"><code class="name flex">
+<span>def <span class="ident">get_db</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.bodydevices_web.read_devices"><code class="name flex">
+<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with all body devices and necessary attributes</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@body_device_web.get(&#34;/body-devices-web&#34;, response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all body devices and necessary attributes
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
+    devices = crud.get_body_devices(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.b_logs[len(dev.b_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;body_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;body_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="two-column">
+<li><code><a title="sql_app.api.bodydevices_web.connect_dev_lic" href="#sql_app.api.bodydevices_web.connect_dev_lic">connect_dev_lic</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.connect_post" href="#sql_app.api.bodydevices_web.connect_post">connect_post</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.delete_post" href="#sql_app.api.bodydevices_web.delete_post">delete_post</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.device_inv" href="#sql_app.api.bodydevices_web.device_inv">device_inv</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.filter_devices" href="#sql_app.api.bodydevices_web.filter_devices">filter_devices</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.get_db" href="#sql_app.api.bodydevices_web.get_db">get_db</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web.read_devices" href="#sql_app.api.bodydevices_web.read_devices">read_devices</a></code></li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/doc/sql_app/api/devices.html b/server/doc/sql_app/api/devices.html
index 44cffd7..0f933d7 100644
--- a/server/doc/sql_app/api/devices.html
+++ b/server/doc/sql_app/api/devices.html
@@ -49,7 +49,7 @@ def get_db():
 
 
 @device.post(&#34;/device&#34;, response_model=schemas.Device)
-def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
+def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)):
     &#34;&#34;&#34;
     Endpoint used for creating new device
     &#34;&#34;&#34;
@@ -84,7 +84,7 @@ def read_device(device_id: int, db: Session = Depends(get_db)):
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
 <dt id="sql_app.api.devices.create_device"><code class="name flex">
-<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceCreate" href="../schemas.html#sql_app.schemas.DeviceCreate">DeviceCreate</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>def <span class="ident">create_device</span></span>(<span>device: <a title="sql_app.schemas.DeviceTemp" href="../schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Endpoint used for creating new device</p></div>
@@ -93,7 +93,7 @@ def read_device(device_id: int, db: Session = Depends(get_db)):
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@device.post(&#34;/device&#34;, response_model=schemas.Device)
-def create_device(device: schemas.DeviceCreate, db: Session = Depends(get_db)):
+def create_device(device: schemas.DeviceTemp, db: Session = Depends(get_db)):
     &#34;&#34;&#34;
     Endpoint used for creating new device
     &#34;&#34;&#34;
diff --git a/server/doc/sql_app/api/devices_web.html b/server/doc/sql_app/api/devices_web.html
index b4028ad..4c54ff9 100644
--- a/server/doc/sql_app/api/devices_web.html
+++ b/server/doc/sql_app/api/devices_web.html
@@ -26,17 +26,18 @@
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">from typing import List
+<pre><code class="python">from datetime import datetime
 
-from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from fastapi import Depends, APIRouter, Form
+from fastapi import Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi.templating import Jinja2Templates
+from fastapi_jwt_auth import AuthJWT
+from pydantic import BaseModel
 from sqlalchemy.orm import Session
+from sql_app.api.auth import fake_users_db
 from sql_app import crud, models, schemas
-from datetime import datetime
 from ..database import SessionLocal, engine
-from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
-from fastapi.staticfiles import StaticFiles
-from fastapi.templating import Jinja2Templates
 
 models.Base.metadata.create_all(bind=engine)
 
@@ -44,7 +45,7 @@ models.Base.metadata.create_all(bind=engine)
 templates = Jinja2Templates(directory=&#34;../templates/devices&#34;)
 
 # prefix used for all endpoints in this file
-device_web = APIRouter(prefix=&#34;/api/v1&#34;)
+device_web = APIRouter(prefix=&#34;&#34;)
 
 
 # Dependency
@@ -57,71 +58,173 @@ def get_db():
 
 
 @device_web.get(&#34;/devices-web&#34;, response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Returns template with all devices and its current states
+    Returns template with all devices and its necessary attributes
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
     devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs)-1].status)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
+    for dev in devices:
+        if len(dev.licenses) &gt; 0:
+            for lic in dev.licenses:
+                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
+                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
 
 
 @device_web.post(&#34;/devices-web&#34;, response_class=HTMLResponse)
-async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form(&#34;all&#34;),
-                         db: Session = Depends(get_db)):
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         keyman_id: str = Form(&#34;all&#34;), lic_name: str = Form(&#34;all&#34;),
+                         lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint used for filtering devices by license. returns html template with only
+    Endpoint used for filtering devices by user given inputs. returns html template with only
     devices that has assigned license defined by user input
     &#34;&#34;&#34;
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    def_devices = []
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_devices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
     for dev in devices:
-        for l in dev.licenses:
-            if dev not in def_devices and l.licenses.name == lic:
-                def_devices.append(dev)
-    # if input was default all
-    if lic == &#34;all&#34;:
-        def_devices = devices
-    statuses = []
-    for i in range(0, len(def_devices)):
-        statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status)
+        if len(dev.licenses) &gt; 0:
+            for lic in dev.licenses:
+                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(def_devices), &#34;devices&#34;: def_devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
+                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
 
 
 @device_web.get(&#34;/device-license/{device_id}&#34;, response_class=HTMLResponse)
-async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Returns template with one device and all available licenses that can be assigned to it.
+    Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
+    be assigned to device, inventory number text input and comment text input
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     device = crud.get_device(db, device_id)
+    dev_licenses = crud.get_device_licenses(db, device_id)
+    lic_ids = []
+    dev_lics = []
+    for dev_lic in dev_licenses:
+        dev_lics.append(dev_lic.licenses)
+    for dev_lic in dev_licenses:
+        lic_ids.append(dev_lic.licenses.license_id)
     licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic.license_id not in lic_ids and lic not in lic_left:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
     return templates.TemplateResponse(&#34;devicelicense.html&#34;,
-                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: licenses})
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;dev_lic&#34;: dev_lics,
+                                       &#34;teams&#34;: teams})
 
 
-@device_web.post(&#34;/devices-web/{device_id}&#34;, response_class=HTMLResponse)
-async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100,
-                       db: Session = Depends(get_db)):
+@device_web.post(&#34;/devices-web/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from template for connecting device with license. Adds entry to devices_licenses
-    table and returns template with all devices in database
+    Endpoint called from devicelicense.html template. Adds entry to devices_licenses
+    table and redirects to devices-web endpoint
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     crud.create_device_license(db, device_id, int(lic), datetime.now())
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
+
+
+@device_web.post(&#34;/devices-web-del/{device_id}&#34;)
+async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
+    bodydevices_licenses table and redirects to devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.delete_device_license(db, device_id, int(lic_del))
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
+
+
+@device_web.post(&#34;/devices-web-team/{device_id}&#34;)
+async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device(db, device_id, team_con)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
+
+
+@device_web.post(&#34;/devices-web-inv/{device_id}&#34;)
+async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web
+    endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)
+
+
+@device_web.post(&#34;/devices-web-comment/{device_id}&#34;)
+async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web
+    endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device_com(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
 </details>
 </section>
 <section>
@@ -132,85 +235,212 @@ async def connect_post(request: Request, device_id: int, lic: str = Form(...), s
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
 <dt id="sql_app.api.devices_web.connect_dev_lic"><code class="name flex">
-<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it.</p></div>
+<div class="desc"><p>Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
+be assigned to device, inventory number text input and comment text input</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@device_web.get(&#34;/device-license/{device_id}&#34;, response_class=HTMLResponse)
-async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db)):
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Returns template with one device and all available licenses that can be assigned to it.
+    Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
+    be assigned to device, inventory number text input and comment text input
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     device = crud.get_device(db, device_id)
+    dev_licenses = crud.get_device_licenses(db, device_id)
+    lic_ids = []
+    dev_lics = []
+    for dev_lic in dev_licenses:
+        dev_lics.append(dev_lic.licenses)
+    for dev_lic in dev_licenses:
+        lic_ids.append(dev_lic.licenses.license_id)
     licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic.license_id not in lic_ids and lic not in lic_left:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
     return templates.TemplateResponse(&#34;devicelicense.html&#34;,
-                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: licenses})</code></pre>
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;dev_lic&#34;: dev_lics,
+                                       &#34;teams&#34;: teams})</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.devices_web.connect_post"><code class="name flex">
-<span>async def <span class="ident">connect_post</span></span>(<span>request: starlette.requests.Request, device_id: int, lic: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Endpoint called from template for connecting device with license. Adds entry to devices_licenses
-table and returns template with all devices in database</p></div>
+<div class="desc"><p>Endpoint called from devicelicense.html template. Adds entry to devices_licenses
+table and redirects to devices-web endpoint</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">@device_web.post(&#34;/devices-web/{device_id}&#34;, response_class=HTMLResponse)
-async def connect_post(request: Request, device_id: int, lic: str = Form(...), skip: int = 0, limit: int = 100,
-                       db: Session = Depends(get_db)):
+<pre><code class="python">@device_web.post(&#34;/devices-web/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from template for connecting device with license. Adds entry to devices_licenses
-    table and returns template with all devices in database
+    Endpoint called from devicelicense.html template. Adds entry to devices_licenses
+    table and redirects to devices-web endpoint
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     crud.create_device_license(db, device_id, int(lic), datetime.now())
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.devices_web.delete_post"><code class="name flex">
+<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, lic_del: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
+bodydevices_licenses table and redirects to devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@device_web.post(&#34;/devices-web-del/{device_id}&#34;)
+async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
+    bodydevices_licenses table and redirects to devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.delete_device_license(db, device_id, int(lic_del))
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.devices_web.dev_comm_new"><code class="name flex">
+<span>async def <span class="ident">dev_comm_new</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web
+endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@device_web.post(&#34;/devices-web-comment/{device_id}&#34;)
+async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web
+    endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device_com(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.devices_web.dev_inv_new"><code class="name flex">
+<span>async def <span class="ident">dev_inv_new</span></span>(<span>device_id: int, dev_inv: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web
+endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@device_web.post(&#34;/devices-web-inv/{device_id}&#34;)
+async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web
+    endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.devices_web.dev_team_con"><code class="name flex">
+<span>async def <span class="ident">dev_team_con</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@device_web.post(&#34;/devices-web-team/{device_id}&#34;)
+async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_device(db, device_id, team_con)
+    return RedirectResponse(url=f&#34;/devices-web&#34;, status_code=303)</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.devices_web.filter_devices"><code class="name flex">
-<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, lic: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, keyman_id: str = Form(all), lic_name: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Endpoint used for filtering devices by license. returns html template with only
+<div class="desc"><p>Endpoint used for filtering devices by user given inputs. returns html template with only
 devices that has assigned license defined by user input</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@device_web.post(&#34;/devices-web&#34;, response_class=HTMLResponse)
-async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form(&#34;all&#34;),
-                         db: Session = Depends(get_db)):
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         keyman_id: str = Form(&#34;all&#34;), lic_name: str = Form(&#34;all&#34;),
+                         lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint used for filtering devices by license. returns html template with only
+    Endpoint used for filtering devices by user given inputs. returns html template with only
     devices that has assigned license defined by user input
     &#34;&#34;&#34;
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    def_devices = []
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_devices(db, keyman_id, lic_name, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_devices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
     for dev in devices:
-        for l in dev.licenses:
-            if dev not in def_devices and l.licenses.name == lic:
-                def_devices.append(dev)
-    # if input was default all
-    if lic == &#34;all&#34;:
-        def_devices = devices
-    statuses = []
-    for i in range(0, len(def_devices)):
-        statuses.append(def_devices[i].logs[len(def_devices[i].logs) - 1].status)
+        if len(dev.licenses) &gt; 0:
+            for lic in dev.licenses:
+                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(def_devices), &#34;devices&#34;: def_devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
+                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.devices_web.get_db"><code class="name flex">
@@ -231,27 +461,42 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic:
 </details>
 </dd>
 <dt id="sql_app.api.devices_web.read_devices"><code class="name flex">
-<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Returns template with all devices and its current states</p></div>
+<div class="desc"><p>Returns template with all devices and its necessary attributes</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@device_web.get(&#34;/devices-web&#34;, response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Returns template with all devices and its current states
+    Returns template with all devices and its necessary attributes
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
     devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs)-1].status)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    # adding dictionary entry with all inforamtions needed in template
+    for dev in devices:
+        if len(dev.licenses) &gt; 0:
+            for lic in dev.licenses:
+                device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
+        else:
+            device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: dev.licenses, &#34;log&#34;: dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                           &#34;licenses&#34;: licenses, &#34;devs&#34;: devices,
+                                                           &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                  &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 </dl>
@@ -271,9 +516,13 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
 </ul>
 </li>
 <li><h3><a href="#header-functions">Functions</a></h3>
-<ul class="">
+<ul class="two-column">
 <li><code><a title="sql_app.api.devices_web.connect_dev_lic" href="#sql_app.api.devices_web.connect_dev_lic">connect_dev_lic</a></code></li>
 <li><code><a title="sql_app.api.devices_web.connect_post" href="#sql_app.api.devices_web.connect_post">connect_post</a></code></li>
+<li><code><a title="sql_app.api.devices_web.delete_post" href="#sql_app.api.devices_web.delete_post">delete_post</a></code></li>
+<li><code><a title="sql_app.api.devices_web.dev_comm_new" href="#sql_app.api.devices_web.dev_comm_new">dev_comm_new</a></code></li>
+<li><code><a title="sql_app.api.devices_web.dev_inv_new" href="#sql_app.api.devices_web.dev_inv_new">dev_inv_new</a></code></li>
+<li><code><a title="sql_app.api.devices_web.dev_team_con" href="#sql_app.api.devices_web.dev_team_con">dev_team_con</a></code></li>
 <li><code><a title="sql_app.api.devices_web.filter_devices" href="#sql_app.api.devices_web.filter_devices">filter_devices</a></code></li>
 <li><code><a title="sql_app.api.devices_web.get_db" href="#sql_app.api.devices_web.get_db">get_db</a></code></li>
 <li><code><a title="sql_app.api.devices_web.read_devices" href="#sql_app.api.devices_web.read_devices">read_devices</a></code></li>
diff --git a/server/doc/sql_app/api/headdevices_web.html b/server/doc/sql_app/api/headdevices_web.html
new file mode 100644
index 0000000..9d1ba03
--- /dev/null
+++ b/server/doc/sql_app/api/headdevices_web.html
@@ -0,0 +1,440 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>sql_app.api.headdevices_web API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>sql_app.api.headdevices_web</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">from datetime import datetime
+
+from fastapi import Depends, APIRouter, Form
+from fastapi import Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi.templating import Jinja2Templates
+from fastapi_jwt_auth import AuthJWT
+from pydantic import BaseModel
+from sqlalchemy.orm import Session
+from sql_app.api.auth import fake_users_db
+from sql_app import crud, models
+from ..database import SessionLocal, engine
+
+models.Base.metadata.create_all(bind=engine)
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory=&#34;../templates/head_devices&#34;)
+
+# prefix used for all endpoints in this file
+head_device_web = APIRouter(prefix=&#34;&#34;)
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@head_device_web.get(&#34;/head-devices-web&#34;, response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all head devices and necessary attributes
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
+    devices = crud.get_head_devices(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;head_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;head_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+
+
+@head_device_web.post(&#34;/head-devices-web&#34;, response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering head devices by user given inputs. returns html template with only
+    head devices that has attributes defined by user input
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_headdevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;head_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;head_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
+                                                                       &#34;licenses&#34;: licenses,
+                                                                       &#34;user&#34;: current_user})
+
+
+@head_device_web.get(&#34;/head-device-license/{device_id}&#34;, response_class=HTMLResponse)
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with one head device and all available licenses that can be assigned to it, plus team and comment
+    and inventory number inputs.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    device = crud.get_head_device(db, device_id)
+    licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic != device.license:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
+    return templates.TemplateResponse(&#34;headlicense.html&#34;,
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})
+
+
+@head_device_web.post(&#34;/head-devices-web-lic/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_license(db, device_id, int(lic))
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)
+
+
+@head_device_web.post(&#34;/head-devices-web-team/{device_id}&#34;)
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)
+
+
+@head_device_web.post(&#34;/head-devices-inv/{device_id}&#34;)
+async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from within from headlicense.html template. Changes head devices inventory number with new one
+    given from user
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)
+
+
+@head_device_web.post(&#34;/head-devices-comm/{device_id}&#34;)
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from within from headlicense.html template. Changes head devices comment with new one
+    given from user
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="sql_app.api.headdevices_web.connect_dev_lic"><code class="name flex">
+<span>async def <span class="ident">connect_dev_lic</span></span>(<span>request: starlette.requests.Request, device_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with one head device and all available licenses that can be assigned to it, plus team and comment
+and inventory number inputs.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.get(&#34;/head-device-license/{device_id}&#34;, response_class=HTMLResponse)
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with one head device and all available licenses that can be assigned to it, plus team and comment
+    and inventory number inputs.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    device = crud.get_head_device(db, device_id)
+    licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic != device.license:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
+    return templates.TemplateResponse(&#34;headlicense.html&#34;,
+                                      {&#34;request&#34;: request, &#34;device&#34;: device, &#34;licenses&#34;: lic_left, &#34;teams&#34;: teams})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.connect_post"><code class="name flex">
+<span>async def <span class="ident">connect_post</span></span>(<span>device_id: int, lic: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.post(&#34;/head-devices-web-lic/{device_id}&#34;)
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_license(db, device_id, int(lic))
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.delete_post"><code class="name flex">
+<span>async def <span class="ident">delete_post</span></span>(<span>device_id: int, team_con: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.post(&#34;/head-devices-web-team/{device_id}&#34;)
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.device_inv"><code class="name flex">
+<span>async def <span class="ident">device_inv</span></span>(<span>device_id: int, dev_com: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint called from within from headlicense.html template. Changes head devices comment with new one
+given from user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.post(&#34;/head-devices-comm/{device_id}&#34;)
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint called from within from headlicense.html template. Changes head devices comment with new one
+    given from user
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    crud.update_headdevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f&#34;/head-devices-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.filter_devices"><code class="name flex">
+<span>async def <span class="ident">filter_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, body_id: str = Form(all), lic_id: str = Form(all), team: str = Form(all), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint used for filtering head devices by user given inputs. returns html template with only
+head devices that has attributes defined by user input</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.post(&#34;/head-devices-web&#34;, response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form(&#34;all&#34;), lic_id: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering head devices by user given inputs. returns html template with only
+    head devices that has attributes defined by user input
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_headdevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;head_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;head_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                       &#34;devs&#34;: devices, &#34;teams&#34;: teams,
+                                                                       &#34;licenses&#34;: licenses,
+                                                                       &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.get_db"><code class="name flex">
+<span>def <span class="ident">get_db</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.headdevices_web.read_devices"><code class="name flex">
+<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with all head devices and necessary attributes</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@head_device_web.get(&#34;/head-devices-web&#34;, response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all head devices and necessary attributes
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
+    devices = crud.get_head_devices(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({&#34;device&#34;: dev, &#34;license&#34;: lic, &#34;log&#34;: dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;head_devices.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;head_devices_normal.html&#34;, {&#34;request&#34;: request, &#34;devices&#34;: device_dict,
+                                                                &#34;devs&#34;: devices, &#34;teams&#34;: teams, &#34;licenses&#34;: licenses,
+                                                                &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="two-column">
+<li><code><a title="sql_app.api.headdevices_web.connect_dev_lic" href="#sql_app.api.headdevices_web.connect_dev_lic">connect_dev_lic</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.connect_post" href="#sql_app.api.headdevices_web.connect_post">connect_post</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.delete_post" href="#sql_app.api.headdevices_web.delete_post">delete_post</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.device_inv" href="#sql_app.api.headdevices_web.device_inv">device_inv</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.filter_devices" href="#sql_app.api.headdevices_web.filter_devices">filter_devices</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.get_db" href="#sql_app.api.headdevices_web.get_db">get_db</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web.read_devices" href="#sql_app.api.headdevices_web.read_devices">read_devices</a></code></li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/doc/sql_app/api/index.html b/server/doc/sql_app/api/index.html
index edd8582..6459f2e 100644
--- a/server/doc/sql_app/api/index.html
+++ b/server/doc/sql_app/api/index.html
@@ -26,6 +26,14 @@
 <section>
 <h2 class="section-title" id="header-submodules">Sub-modules</h2>
 <dl>
+<dt><code class="name"><a title="sql_app.api.auth" href="auth.html">sql_app.api.auth</a></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt><code class="name"><a title="sql_app.api.bodydevices_web" href="bodydevices_web.html">sql_app.api.bodydevices_web</a></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt><code class="name"><a title="sql_app.api.devices" href="devices.html">sql_app.api.devices</a></code></dt>
 <dd>
 <div class="desc"></div>
@@ -34,6 +42,14 @@
 <dd>
 <div class="desc"></div>
 </dd>
+<dt><code class="name"><a title="sql_app.api.headdevices_web" href="headdevices_web.html">sql_app.api.headdevices_web</a></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt><code class="name"><a title="sql_app.api.ld_logs_web" href="ld_logs_web.html">sql_app.api.ld_logs_web</a></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt><code class="name"><a title="sql_app.api.licenses" href="licenses.html">sql_app.api.licenses</a></code></dt>
 <dd>
 <div class="desc"></div>
@@ -66,6 +82,10 @@
 <dd>
 <div class="desc"></div>
 </dd>
+<dt><code class="name"><a title="sql_app.api.users_web" href="users_web.html">sql_app.api.users_web</a></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 </dl>
 </section>
 <section>
@@ -88,8 +108,12 @@
 </li>
 <li><h3><a href="#header-submodules">Sub-modules</a></h3>
 <ul>
+<li><code><a title="sql_app.api.auth" href="auth.html">sql_app.api.auth</a></code></li>
+<li><code><a title="sql_app.api.bodydevices_web" href="bodydevices_web.html">sql_app.api.bodydevices_web</a></code></li>
 <li><code><a title="sql_app.api.devices" href="devices.html">sql_app.api.devices</a></code></li>
 <li><code><a title="sql_app.api.devices_web" href="devices_web.html">sql_app.api.devices_web</a></code></li>
+<li><code><a title="sql_app.api.headdevices_web" href="headdevices_web.html">sql_app.api.headdevices_web</a></code></li>
+<li><code><a title="sql_app.api.ld_logs_web" href="ld_logs_web.html">sql_app.api.ld_logs_web</a></code></li>
 <li><code><a title="sql_app.api.licenses" href="licenses.html">sql_app.api.licenses</a></code></li>
 <li><code><a title="sql_app.api.licenses_web" href="licenses_web.html">sql_app.api.licenses_web</a></code></li>
 <li><code><a title="sql_app.api.pcs" href="pcs.html">sql_app.api.pcs</a></code></li>
@@ -98,6 +122,7 @@
 <li><code><a title="sql_app.api.teams_web" href="teams_web.html">sql_app.api.teams_web</a></code></li>
 <li><code><a title="sql_app.api.usb_logs" href="usb_logs.html">sql_app.api.usb_logs</a></code></li>
 <li><code><a title="sql_app.api.usb_logs_web" href="usb_logs_web.html">sql_app.api.usb_logs_web</a></code></li>
+<li><code><a title="sql_app.api.users_web" href="users_web.html">sql_app.api.users_web</a></code></li>
 </ul>
 </li>
 </ul>
diff --git a/server/doc/sql_app/api/ld_logs_web.html b/server/doc/sql_app/api/ld_logs_web.html
new file mode 100644
index 0000000..5336ec6
--- /dev/null
+++ b/server/doc/sql_app/api/ld_logs_web.html
@@ -0,0 +1,237 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>sql_app.api.ld_logs_web API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>sql_app.api.ld_logs_web</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">from typing import List
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from datetime import datetime
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi_jwt_auth import AuthJWT
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory=&#34;../templates/ld-logs&#34;)
+
+# prefix used for all endpoints in this file
+ldlogs_web = APIRouter(prefix=&#34;&#34;)
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@ldlogs_web.get(&#34;/ldlogs-web&#34;, response_class=HTMLResponse)
+async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                    Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all usb logs currently saved in database with its pcs, teams and licenses.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    logs = crud.get_ld_logs(db, skip=skip, limit=limit)
+    pcs = []
+    for log in logs:
+        if log.pc_id not in pcs:
+            pcs.append(log.pc_id)
+    pc_obj = crud.find_pcs(db, pcs)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;ldlogs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                          &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;ldlogs_normal.html&#34;,
+                                          {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                           &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+
+
+@ldlogs_web.post(&#34;/ldlogs-web&#34;, response_class=HTMLResponse)
+async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;), lic: str = Form(&#34;all&#34;),
+                      skip: int = 0, limit: int = 100,
+                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering ld logs by user given form inputs.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    log = crud.get_filtered_ldlogs(db, pc, team, lic)
+    logs_ids = []
+    for l in log:
+        logs_ids.append(l[0])
+    logs = crud.find_filtered_ldlogs(db, logs_ids)
+    pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;ldlogs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                          &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;ldlogs_normal.html&#34;,
+                                          {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                           &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="sql_app.api.ld_logs_web.filter_logs"><code class="name flex">
+<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Endpoint used for filtering ld logs by user given form inputs.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@ldlogs_web.post(&#34;/ldlogs-web&#34;, response_class=HTMLResponse)
+async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;), lic: str = Form(&#34;all&#34;),
+                      skip: int = 0, limit: int = 100,
+                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Endpoint used for filtering ld logs by user given form inputs.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    log = crud.get_filtered_ldlogs(db, pc, team, lic)
+    logs_ids = []
+    for l in log:
+        logs_ids.append(l[0])
+    logs = crud.find_filtered_ldlogs(db, logs_ids)
+    pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;ldlogs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                          &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;ldlogs_normal.html&#34;,
+                                          {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                           &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.ld_logs_web.get_db"><code class="name flex">
+<span>def <span class="ident">get_db</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.ld_logs_web.read_logs"><code class="name flex">
+<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with all usb logs currently saved in database with its pcs, teams and licenses.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@ldlogs_web.get(&#34;/ldlogs-web&#34;, response_class=HTMLResponse)
+async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                    Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all usb logs currently saved in database with its pcs, teams and licenses.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    logs = crud.get_ld_logs(db, skip=skip, limit=limit)
+    pcs = []
+    for log in logs:
+        if log.pc_id not in pcs:
+            pcs.append(log.pc_id)
+    pc_obj = crud.find_pcs(db, pcs)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;ldlogs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                          &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;ldlogs_normal.html&#34;,
+                                          {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                           &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="">
+<li><code><a title="sql_app.api.ld_logs_web.filter_logs" href="#sql_app.api.ld_logs_web.filter_logs">filter_logs</a></code></li>
+<li><code><a title="sql_app.api.ld_logs_web.get_db" href="#sql_app.api.ld_logs_web.get_db">get_db</a></code></li>
+<li><code><a title="sql_app.api.ld_logs_web.read_logs" href="#sql_app.api.ld_logs_web.read_logs">read_logs</a></code></li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/doc/sql_app/api/licenses_web.html b/server/doc/sql_app/api/licenses_web.html
index fb9ff21..0ac98d8 100644
--- a/server/doc/sql_app/api/licenses_web.html
+++ b/server/doc/sql_app/api/licenses_web.html
@@ -27,14 +27,15 @@
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">from typing import List
-
+from typing import Optional
 from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
 from sqlalchemy.orm import Session
 from datetime import date
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi_jwt_auth import AuthJWT
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
@@ -45,7 +46,7 @@ templates = Jinja2Templates(directory=&#34;../templates/licenses&#34;)
 device_templates = Jinja2Templates(directory=&#34;../templates/devices&#34;)
 
 # prefix used for all endpoints in this file
-licenses_web = APIRouter(prefix=&#34;/api/v1&#34;)
+licenses_web = APIRouter(prefix=&#34;&#34;)
 
 
 # Dependency
@@ -58,38 +59,53 @@ def get_db():
 
 
 @licenses_web.get(&#34;/license-create&#34;, response_class=HTMLResponse)
-async def licenses_create_web(request: Request):
+async def licenses_create_web(request: Request, Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with Form for creating new license.
     &#34;&#34;&#34;
-    return templates.TemplateResponse(&#34;license_create.html&#34;, {&#34;request&#34;: request})
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    return templates.TemplateResponse(&#34;license_create.html&#34;, {&#34;request&#34;: request, &#34;minimum_date&#34;: date.today()})
 
 
 @licenses_web.get(&#34;/licenses-web&#34;, response_class=HTMLResponse)
-async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                            Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all licenses currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;licenses.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses})
-
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;licenses.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses,
+                                                            &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;licenses_normal.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses,
+                                                            &#34;user&#34;: current_user})
 
-@licenses_web.post(&#34;/licenses-web&#34;, response_class=HTMLResponse)
-def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100,
-                   db: Session = Depends(get_db)):
+@licenses_web.post(&#34;/licenses-web&#34;)
+def create_license(name: Optional[str] = Form(&#34;&#34;), lic_id: str = Form(...), expdate: Optional[date] = Form(None),
+                   db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from create license form. Creates new license and returns template with all licenses in database
+    Endpoint called from create license form. Creates new license and redirects to devices-web endpoint
     &#34;&#34;&#34;
-    db_license = crud.create_license(db, name, expdate)
-    if db_license is None:
-        print(&#34;something went wrong&#34;)
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return device_templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    licenses = crud.get_licenses(db, 0, 100)
+    licenses_ids = []
+    for l in licenses:
+        licenses_ids.append(l.license_id)
+    if lic_id not in licenses_ids:
+        db_license = crud.create_license(db, name, lic_id, expdate)
+        if db_license is None:
+            print(&#34;something went wrong&#34;)
+    return RedirectResponse(url=f&#34;/licenses-web&#34;, status_code=303)</code></pre>
 </details>
 </section>
 <section>
@@ -100,30 +116,33 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
 <dt id="sql_app.api.licenses_web.create_license"><code class="name flex">
-<span>def <span class="ident">create_license</span></span>(<span>request: starlette.requests.Request, name: str = Form(Ellipsis), expdate: datetime.date = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>def <span class="ident">create_license</span></span>(<span>name: Optional[str] = Form(), lic_id: str = Form(Ellipsis), expdate: Optional[datetime.date] = Form(None), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Endpoint called from create license form. Creates new license and returns template with all licenses in database</p></div>
+<div class="desc"><p>Endpoint called from create license form. Creates new license and redirects to devices-web endpoint</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">@licenses_web.post(&#34;/licenses-web&#34;, response_class=HTMLResponse)
-def create_license(request: Request, name: str = Form(...), expdate: date = Form(...), skip: int = 0, limit: int = 100,
-                   db: Session = Depends(get_db)):
+<pre><code class="python">@licenses_web.post(&#34;/licenses-web&#34;)
+def create_license(name: Optional[str] = Form(&#34;&#34;), lic_id: str = Form(...), expdate: Optional[date] = Form(None),
+                   db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from create license form. Creates new license and returns template with all licenses in database
+    Endpoint called from create license form. Creates new license and redirects to devices-web endpoint
     &#34;&#34;&#34;
-    db_license = crud.create_license(db, name, expdate)
-    if db_license is None:
-        print(&#34;something went wrong&#34;)
-    devices = crud.get_devices(db, skip=skip, limit=limit)
-    statuses = []
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].logs[len(devices[i].logs) - 1].status)
-    licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return device_templates.TemplateResponse(&#34;devices.html&#34;, {&#34;request&#34;: request, &#34;devs&#34;: len(devices), &#34;devices&#34;: devices,
-                                                       &#34;statuses&#34;: statuses, &#34;licenses&#34;: licenses})</code></pre>
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    licenses = crud.get_licenses(db, 0, 100)
+    licenses_ids = []
+    for l in licenses:
+        licenses_ids.append(l.license_id)
+    if lic_id not in licenses_ids:
+        db_license = crud.create_license(db, name, lic_id, expdate)
+        if db_license is None:
+            print(&#34;something went wrong&#34;)
+    return RedirectResponse(url=f&#34;/licenses-web&#34;, status_code=303)</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.licenses_web.get_db"><code class="name flex">
@@ -144,7 +163,7 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form
 </details>
 </dd>
 <dt id="sql_app.api.licenses_web.licenses_create_web"><code class="name flex">
-<span>async def <span class="ident">licenses_create_web</span></span>(<span>request: starlette.requests.Request)</span>
+<span>async def <span class="ident">licenses_create_web</span></span>(<span>request: starlette.requests.Request, Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with Form for creating new license.</p></div>
@@ -153,15 +172,19 @@ def create_license(request: Request, name: str = Form(...), expdate: date = Form
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@licenses_web.get(&#34;/license-create&#34;, response_class=HTMLResponse)
-async def licenses_create_web(request: Request):
+async def licenses_create_web(request: Request, Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with Form for creating new license.
     &#34;&#34;&#34;
-    return templates.TemplateResponse(&#34;license_create.html&#34;, {&#34;request&#34;: request})</code></pre>
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    return templates.TemplateResponse(&#34;license_create.html&#34;, {&#34;request&#34;: request, &#34;minimum_date&#34;: date.today()})</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.licenses_web.read_licenses_web"><code class="name flex">
-<span>async def <span class="ident">read_licenses_web</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">read_licenses_web</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with all licenses currently saved in database</p></div>
@@ -170,12 +193,21 @@ async def licenses_create_web(request: Request):
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@licenses_web.get(&#34;/licenses-web&#34;, response_class=HTMLResponse)
-async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_licenses_web(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                            Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all licenses currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;licenses.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;licenses.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses,
+                                                            &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;licenses_normal.html&#34;, {&#34;request&#34;: request, &#34;licenses&#34;: licenses,
+                                                            &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 </dl>
diff --git a/server/doc/sql_app/api/pcs_web.html b/server/doc/sql_app/api/pcs_web.html
index 5f11982..3b208a9 100644
--- a/server/doc/sql_app/api/pcs_web.html
+++ b/server/doc/sql_app/api/pcs_web.html
@@ -32,7 +32,8 @@ from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi_jwt_auth import AuthJWT
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
@@ -42,7 +43,7 @@ models.Base.metadata.create_all(bind=engine)
 templates = Jinja2Templates(directory=&#34;../templates/pcs&#34;)
 
 # prefix used for all endpoints in this file
-pcs_web = APIRouter(prefix=&#34;/api/v1&#34;)
+pcs_web = APIRouter(prefix=&#34;&#34;)
 
 
 # Dependency
@@ -55,34 +56,19 @@ def get_db():
 
 
 @pcs_web.get(&#34;/pcs-web&#34;, response_class=HTMLResponse)
-async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                   Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all pcs currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     pcs = crud.get_pcs(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs})
-
-
-@pcs_web.get(&#34;/pc-team/{pc_id}&#34;, response_class=HTMLResponse)
-async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db)):
-    &#34;&#34;&#34;
-    Returns template with Form for connecting pc with team
-    &#34;&#34;&#34;
-    pc = crud.get_pc(db, pc_id)
-    teams = crud.get_teams(db, 0, 100)
-    return templates.TemplateResponse(&#34;pcteam.html&#34;,
-                                      {&#34;request&#34;: request, &#34;pc&#34;: pc, &#34;teams&#34;: teams})
-
-
-@pcs_web.post(&#34;/pcs-web/{pc_id}&#34;, response_class=HTMLResponse)
-async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip: int = 0, limit: int = 100,
-                       db: Session = Depends(get_db)):
-    &#34;&#34;&#34;
-    Endpoint called from within form for connecting pc with team. Updates certain pc with new team.
-    &#34;&#34;&#34;
-    old_pc = crud.update_pc(db, pc_id, team)
-    pcs = crud.get_pcs(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;pcs_normal.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs, &#34;user&#34;: current_user})</code></pre>
 </details>
 </section>
 <section>
@@ -92,46 +78,6 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip
 <section>
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
-<dt id="sql_app.api.pcs_web.connect_pc_team"><code class="name flex">
-<span>async def <span class="ident">connect_pc_team</span></span>(<span>request: starlette.requests.Request, pc_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
-</code></dt>
-<dd>
-<div class="desc"><p>Returns template with Form for connecting pc with team</p></div>
-<details class="source">
-<summary>
-<span>Expand source code</span>
-</summary>
-<pre><code class="python">@pcs_web.get(&#34;/pc-team/{pc_id}&#34;, response_class=HTMLResponse)
-async def connect_pc_team(request: Request, pc_id: int, db: Session = Depends(get_db)):
-    &#34;&#34;&#34;
-    Returns template with Form for connecting pc with team
-    &#34;&#34;&#34;
-    pc = crud.get_pc(db, pc_id)
-    teams = crud.get_teams(db, 0, 100)
-    return templates.TemplateResponse(&#34;pcteam.html&#34;,
-                                      {&#34;request&#34;: request, &#34;pc&#34;: pc, &#34;teams&#34;: teams})</code></pre>
-</details>
-</dd>
-<dt id="sql_app.api.pcs_web.connect_post"><code class="name flex">
-<span>async def <span class="ident">connect_post</span></span>(<span>request: starlette.requests.Request, pc_id: int, team: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
-</code></dt>
-<dd>
-<div class="desc"><p>Endpoint called from within form for connecting pc with team. Updates certain pc with new team.</p></div>
-<details class="source">
-<summary>
-<span>Expand source code</span>
-</summary>
-<pre><code class="python">@pcs_web.post(&#34;/pcs-web/{pc_id}&#34;, response_class=HTMLResponse)
-async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip: int = 0, limit: int = 100,
-                       db: Session = Depends(get_db)):
-    &#34;&#34;&#34;
-    Endpoint called from within form for connecting pc with team. Updates certain pc with new team.
-    &#34;&#34;&#34;
-    old_pc = crud.update_pc(db, pc_id, team)
-    pcs = crud.get_pcs(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs})</code></pre>
-</details>
-</dd>
 <dt id="sql_app.api.pcs_web.get_db"><code class="name flex">
 <span>def <span class="ident">get_db</span></span>(<span>)</span>
 </code></dt>
@@ -150,7 +96,7 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip
 </details>
 </dd>
 <dt id="sql_app.api.pcs_web.read_pcs"><code class="name flex">
-<span>async def <span class="ident">read_pcs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">read_pcs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with all pcs currently saved in database</p></div>
@@ -159,12 +105,19 @@ async def connect_post(request: Request, pc_id: int, team: str = Form(...), skip
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@pcs_web.get(&#34;/pcs-web&#34;, response_class=HTMLResponse)
-async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                   Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all pcs currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     pcs = crud.get_pcs(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;pcs.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;pcs_normal.html&#34;, {&#34;request&#34;: request, &#34;pcs&#34;: pcs, &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 </dl>
@@ -185,8 +138,6 @@ async def read_pcs(request: Request, skip: int = 0, limit: int = 100, db: Sessio
 </li>
 <li><h3><a href="#header-functions">Functions</a></h3>
 <ul class="">
-<li><code><a title="sql_app.api.pcs_web.connect_pc_team" href="#sql_app.api.pcs_web.connect_pc_team">connect_pc_team</a></code></li>
-<li><code><a title="sql_app.api.pcs_web.connect_post" href="#sql_app.api.pcs_web.connect_post">connect_post</a></code></li>
 <li><code><a title="sql_app.api.pcs_web.get_db" href="#sql_app.api.pcs_web.get_db">get_db</a></code></li>
 <li><code><a title="sql_app.api.pcs_web.read_pcs" href="#sql_app.api.pcs_web.read_pcs">read_pcs</a></code></li>
 </ul>
diff --git a/server/doc/sql_app/api/teams_web.html b/server/doc/sql_app/api/teams_web.html
index bee1c5d..d80c794 100644
--- a/server/doc/sql_app/api/teams_web.html
+++ b/server/doc/sql_app/api/teams_web.html
@@ -33,7 +33,8 @@ from sqlalchemy.orm import Session
 from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 from fastapi import FastAPI, Request
-from fastapi.responses import HTMLResponse
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi_jwt_auth import AuthJWT
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
@@ -43,7 +44,7 @@ models.Base.metadata.create_all(bind=engine)
 templates = Jinja2Templates(directory=&#34;../templates/teams&#34;)
 
 # prefix used for all endpoints in this file
-teams_web = APIRouter(prefix=&#34;/api/v1&#34;)
+teams_web = APIRouter(prefix=&#34;&#34;)
 
 
 # Dependency
@@ -56,33 +57,78 @@ def get_db():
 
 
 @teams_web.get(&#34;/teams-web&#34;, response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all teams currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     teams = crud.get_teams(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams})
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;teams_normal.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams, &#34;user&#34;: current_user})
 
 
 @teams_web.get(&#34;/team-create&#34;, response_class=HTMLResponse)
-async def team_create_web(request: Request):
+async def team_create_web(request: Request, Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with form for creating new team
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     return templates.TemplateResponse(&#34;team_create.html&#34;, {&#34;request&#34;: request})
 
 
-@teams_web.post(&#34;/teams-web&#34;, response_class=HTMLResponse)
-def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: int = 100,
-                   db: Session = Depends(get_db)):
+@teams_web.post(&#34;/teams-web-con&#34;)
+def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from within form for creating new team. Creates new team and returns all teams in database
+    Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams
     &#34;&#34;&#34;
-    team = crud.create_team(db, name)
-    if team is None:
-        print(&#34;something went wrong&#34;)
-    teams = crud.get_teams(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams})</code></pre>
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    teams = crud.get_teams(db, 0, 100)
+    teams_names = []
+    for t in teams:
+        teams_names.append(t.name)
+    if name not in teams_names:
+        team = crud.create_team(db, name)
+        if team is None:
+            print(&#34;something went wrong&#34;)
+    return RedirectResponse(url=f&#34;/teams-web&#34;, status_code=303)
+
+
+@teams_web.get(&#34;/team-change/{team_id}&#34;, response_class=HTMLResponse)
+async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with form for changing teams name
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    team = crud.get_team(db, team_id)
+    return templates.TemplateResponse(&#34;team_change.html&#34;, {&#34;request&#34;: request, &#34;team&#34;: team})
+
+@teams_web.post(&#34;/teams-change-process/{team_id}&#34;)
+async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...),
+                              Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Changes teams name to a new one given by user
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    team = crud.change_team(db, team_id, name)
+    return RedirectResponse(url=f&#34;/teams-web&#34;, status_code=303)</code></pre>
 </details>
 </section>
 <section>
@@ -93,25 +139,32 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
 <dt id="sql_app.api.teams_web.create_team"><code class="name flex">
-<span>def <span class="ident">create_team</span></span>(<span>request: starlette.requests.Request, name: str = Form(Ellipsis), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>def <span class="ident">create_team</span></span>(<span>name: str = Form(Ellipsis), db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Endpoint called from within form for creating new team. Creates new team and returns all teams in database</p></div>
+<div class="desc"><p>Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">@teams_web.post(&#34;/teams-web&#34;, response_class=HTMLResponse)
-def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: int = 100,
-                   db: Session = Depends(get_db)):
+<pre><code class="python">@teams_web.post(&#34;/teams-web-con&#34;)
+def create_team(name: str = Form(...), db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
-    Endpoint called from within form for creating new team. Creates new team and returns all teams in database
+    Endpoint called from within form for creating new team. Creates new team and redirects to view with all teams
     &#34;&#34;&#34;
-    team = crud.create_team(db, name)
-    if team is None:
-        print(&#34;something went wrong&#34;)
-    teams = crud.get_teams(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams})</code></pre>
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    teams = crud.get_teams(db, 0, 100)
+    teams_names = []
+    for t in teams:
+        teams_names.append(t.name)
+    if name not in teams_names:
+        team = crud.create_team(db, name)
+        if team is None:
+            print(&#34;something went wrong&#34;)
+    return RedirectResponse(url=f&#34;/teams-web&#34;, status_code=303)</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.teams_web.get_db"><code class="name flex">
@@ -132,7 +185,7 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i
 </details>
 </dd>
 <dt id="sql_app.api.teams_web.read_devices"><code class="name flex">
-<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">read_devices</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with all teams currently saved in database</p></div>
@@ -141,16 +194,69 @@ def create_team(request: Request, name: str = Form(...), skip: int = 0, limit: i
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@teams_web.get(&#34;/teams-web&#34;, response_class=HTMLResponse)
-async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all teams currently saved in database
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     teams = crud.get_teams(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;teams.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;teams_normal.html&#34;, {&#34;request&#34;: request, &#34;teams&#34;: teams, &#34;user&#34;: current_user})</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.teams_web.team_change_process"><code class="name flex">
+<span>async def <span class="ident">team_change_process</span></span>(<span>team_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), name: str = Form(Ellipsis), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Changes teams name to a new one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@teams_web.post(&#34;/teams-change-process/{team_id}&#34;)
+async def team_change_process(team_id: int, db:Session = Depends(get_db), name: str = Form(...),
+                              Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Changes teams name to a new one given by user
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    team = crud.change_team(db, team_id, name)
+    return RedirectResponse(url=f&#34;/teams-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.teams_web.team_change_web"><code class="name flex">
+<span>async def <span class="ident">team_change_web</span></span>(<span>request: starlette.requests.Request, team_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with form for changing teams name</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@teams_web.get(&#34;/team-change/{team_id}&#34;, response_class=HTMLResponse)
+async def team_change_web(request: Request, team_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with form for changing teams name
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    team = crud.get_team(db, team_id)
+    return templates.TemplateResponse(&#34;team_change.html&#34;, {&#34;request&#34;: request, &#34;team&#34;: team})</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.teams_web.team_create_web"><code class="name flex">
-<span>async def <span class="ident">team_create_web</span></span>(<span>request: starlette.requests.Request)</span>
+<span>async def <span class="ident">team_create_web</span></span>(<span>request: starlette.requests.Request, Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with form for creating new team</p></div>
@@ -159,10 +265,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@teams_web.get(&#34;/team-create&#34;, response_class=HTMLResponse)
-async def team_create_web(request: Request):
+async def team_create_web(request: Request, Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with form for creating new team
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
     return templates.TemplateResponse(&#34;team_create.html&#34;, {&#34;request&#34;: request})</code></pre>
 </details>
 </dd>
@@ -183,10 +293,12 @@ async def team_create_web(request: Request):
 </ul>
 </li>
 <li><h3><a href="#header-functions">Functions</a></h3>
-<ul class="">
+<ul class="two-column">
 <li><code><a title="sql_app.api.teams_web.create_team" href="#sql_app.api.teams_web.create_team">create_team</a></code></li>
 <li><code><a title="sql_app.api.teams_web.get_db" href="#sql_app.api.teams_web.get_db">get_db</a></code></li>
 <li><code><a title="sql_app.api.teams_web.read_devices" href="#sql_app.api.teams_web.read_devices">read_devices</a></code></li>
+<li><code><a title="sql_app.api.teams_web.team_change_process" href="#sql_app.api.teams_web.team_change_process">team_change_process</a></code></li>
+<li><code><a title="sql_app.api.teams_web.team_change_web" href="#sql_app.api.teams_web.team_change_web">team_change_web</a></code></li>
 <li><code><a title="sql_app.api.teams_web.team_create_web" href="#sql_app.api.teams_web.team_create_web">team_create_web</a></code></li>
 </ul>
 </li>
diff --git a/server/doc/sql_app/api/usb_logs.html b/server/doc/sql_app/api/usb_logs.html
index 499c94e..68e28ae 100644
--- a/server/doc/sql_app/api/usb_logs.html
+++ b/server/doc/sql_app/api/usb_logs.html
@@ -76,9 +76,9 @@ def create_ld_logs(log: schemas.LDTempBase, db: Session = Depends(get_db)):
     head_dev = crud.find_head_device(db, log.head_device)
     body_dev = crud.find_body_device(db, log.body_device)
     if head_dev is None:
-        crud.create_head_device(db, log.head_device)
+        head_dev = crud.create_head_device(db, log.head_device)
     if body_dev is None:
-        crud.create_body_device(db, log.body_device)
+        body_dev = crud.create_body_device(db, log.body_device)
 
     pc = crud.find_pc(db, log.username, log.hostname)
     if pc is None:
@@ -164,9 +164,9 @@ def create_ld_logs(log: schemas.LDTempBase, db: Session = Depends(get_db)):
     head_dev = crud.find_head_device(db, log.head_device)
     body_dev = crud.find_body_device(db, log.body_device)
     if head_dev is None:
-        crud.create_head_device(db, log.head_device)
+        head_dev = crud.create_head_device(db, log.head_device)
     if body_dev is None:
-        crud.create_body_device(db, log.body_device)
+        body_dev = crud.create_body_device(db, log.body_device)
 
     pc = crud.find_pc(db, log.username, log.hostname)
     if pc is None:
diff --git a/server/doc/sql_app/api/usb_logs_web.html b/server/doc/sql_app/api/usb_logs_web.html
index fb54ab6..5c2b0ca 100644
--- a/server/doc/sql_app/api/usb_logs_web.html
+++ b/server/doc/sql_app/api/usb_logs_web.html
@@ -34,6 +34,7 @@ from sql_app import crud, models, schemas
 from ..database import SessionLocal, engine
 from fastapi import FastAPI, Request
 from fastapi.responses import HTMLResponse
+from fastapi_jwt_auth import AuthJWT
 from fastapi.staticfiles import StaticFiles
 from fastapi.templating import Jinja2Templates
 
@@ -43,7 +44,7 @@ models.Base.metadata.create_all(bind=engine)
 templates = Jinja2Templates(directory=&#34;../templates/usb-logs&#34;)
 
 # prefix used for all endpoints in this file
-usblogs_web = APIRouter(prefix=&#34;/api/v1&#34;)
+usblogs_web = APIRouter(prefix=&#34;&#34;)
 
 
 # Dependency
@@ -56,10 +57,13 @@ def get_db():
 
 
 @usblogs_web.get(&#34;/logs-web&#34;, response_class=HTMLResponse)
-async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                    Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all usb logs currently saved in database with its pcs, teams and licenses.
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     logs = crud.get_logs(db, skip=skip, limit=limit)
     pcs = []
     for log in logs:
@@ -68,17 +72,24 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
     pc_obj = crud.find_pcs(db, pcs)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
-                                                    &#34;licenses&#34;: licenses})
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;logs_normal.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
 
 
 @usblogs_web.post(&#34;/logs-web&#34;, response_class=HTMLResponse)
 async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;), lic: str = Form(&#34;all&#34;),
                       skip: int = 0, limit: int = 100,
-                      db: Session = Depends(get_db)):
+                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Endpoint used for filtering usb logs by user given form inputs.
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     log = crud.get_filtered_logs(db, pc, team, lic)
     logs_ids = []
     for l in log:
@@ -87,8 +98,18 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
     pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
-                                                    &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;logs_normal.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+
+
+@usblogs_web.get(&#34;/&#34;, response_class=HTMLResponse)
+async def crossroad(request: Request):
+    return templates.TemplateResponse(&#34;crossroad.html&#34;, {&#34;request&#34;: request})</code></pre>
 </details>
 </section>
 <section>
@@ -98,8 +119,22 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
 <section>
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
+<dt id="sql_app.api.usb_logs_web.crossroad"><code class="name flex">
+<span>async def <span class="ident">crossroad</span></span>(<span>request: starlette.requests.Request)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@usblogs_web.get(&#34;/&#34;, response_class=HTMLResponse)
+async def crossroad(request: Request):
+    return templates.TemplateResponse(&#34;crossroad.html&#34;, {&#34;request&#34;: request})</code></pre>
+</details>
+</dd>
 <dt id="sql_app.api.usb_logs_web.filter_logs"><code class="name flex">
-<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">filter_logs</span></span>(<span>request: starlette.requests.Request, pc: str = Form(all), team: str = Form(all), lic: str = Form(all), skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Endpoint used for filtering usb logs by user given form inputs.</p></div>
@@ -110,10 +145,12 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
 <pre><code class="python">@usblogs_web.post(&#34;/logs-web&#34;, response_class=HTMLResponse)
 async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str = Form(&#34;all&#34;), lic: str = Form(&#34;all&#34;),
                       skip: int = 0, limit: int = 100,
-                      db: Session = Depends(get_db)):
+                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Endpoint used for filtering usb logs by user given form inputs.
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     log = crud.get_filtered_logs(db, pc, team, lic)
     logs_ids = []
     for l in log:
@@ -122,8 +159,13 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
     pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
-                                                    &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;logs_normal.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 <dt id="sql_app.api.usb_logs_web.get_db"><code class="name flex">
@@ -144,7 +186,7 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
 </details>
 </dd>
 <dt id="sql_app.api.usb_logs_web.read_logs"><code class="name flex">
-<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db))</span>
+<span>async def <span class="ident">read_logs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Returns template with all usb logs currently saved in database with its pcs, teams and licenses.</p></div>
@@ -153,10 +195,13 @@ async def filter_logs(request: Request, pc: str = Form(&#34;all&#34;), team: str
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">@usblogs_web.get(&#34;/logs-web&#34;, response_class=HTMLResponse)
-async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
+async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                    Authorize: AuthJWT = Depends()):
     &#34;&#34;&#34;
     Returns template with all usb logs currently saved in database with its pcs, teams and licenses.
     &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
     logs = crud.get_logs(db, skip=skip, limit=limit)
     pcs = []
     for log in logs:
@@ -165,8 +210,13 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
     pc_obj = crud.find_pcs(db, pcs)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
-    return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
-                                                    &#34;licenses&#34;: licenses})</code></pre>
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;logs.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})
+    else:
+        current_user = &#34;guest&#34;
+        return templates.TemplateResponse(&#34;logs_normal.html&#34;, {&#34;request&#34;: request, &#34;logs&#34;: logs, &#34;pcs&#34;: pc_obj, &#34;teams&#34;: teams,
+                                                        &#34;licenses&#34;: licenses, &#34;user&#34;: current_user})</code></pre>
 </details>
 </dd>
 </dl>
@@ -187,6 +237,7 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
 </li>
 <li><h3><a href="#header-functions">Functions</a></h3>
 <ul class="">
+<li><code><a title="sql_app.api.usb_logs_web.crossroad" href="#sql_app.api.usb_logs_web.crossroad">crossroad</a></code></li>
 <li><code><a title="sql_app.api.usb_logs_web.filter_logs" href="#sql_app.api.usb_logs_web.filter_logs">filter_logs</a></code></li>
 <li><code><a title="sql_app.api.usb_logs_web.get_db" href="#sql_app.api.usb_logs_web.get_db">get_db</a></code></li>
 <li><code><a title="sql_app.api.usb_logs_web.read_logs" href="#sql_app.api.usb_logs_web.read_logs">read_logs</a></code></li>
diff --git a/server/doc/sql_app/api/users_web.html b/server/doc/sql_app/api/users_web.html
new file mode 100644
index 0000000..ac9a9d6
--- /dev/null
+++ b/server/doc/sql_app/api/users_web.html
@@ -0,0 +1,194 @@
+<!doctype html>
+<html lang="en">
+<head>
+<meta charset="utf-8">
+<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" />
+<meta name="generator" content="pdoc 0.10.0" />
+<title>sql_app.api.users_web API documentation</title>
+<meta name="description" content="" />
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin>
+<link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin>
+<link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin>
+<style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:20px}#sidebar{padding:30px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style>
+<style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:30%;height:100vh;overflow:auto;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style>
+<style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style>
+<script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script>
+<script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script>
+</head>
+<body>
+<main>
+<article id="content">
+<header>
+<h1 class="title">Module <code>sql_app.api.users_web</code></h1>
+</header>
+<section id="section-intro">
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">from typing import List
+from fastapi import Depends, FastAPI, HTTPException, APIRouter, Form
+from sqlalchemy.orm import Session
+from sql_app import crud, models, schemas
+from ..database import SessionLocal, engine
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi_jwt_auth import AuthJWT
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+models.Base.metadata.create_all(bind=engine)
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory=&#34;../templates/users&#34;)
+
+# prefix used for all endpoints in this file
+users = APIRouter(prefix=&#34;&#34;)
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@users.get(&#34;/users-web&#34;, response_class=HTMLResponse)
+async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                   Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all users currently saved in database
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    users = crud.get_users(db, skip, limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;users.html&#34;, {&#34;request&#34;: request, &#34;users&#34;: users})
+    else:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+
+
+@users.get(&#34;/user-role/{usr_id}&#34;, response_class=HTMLResponse)
+async def connect_pc_team(usr_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Changes role of user to either guest or admin depending on old role.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    user = crud.find_user_byid(db, usr_id)
+    if user.role == &#34;admin&#34;:
+        crud.change_role(db, usr_id, &#34;guest&#34;)
+    else:
+        crud.change_role(db, usr_id, &#34;admin&#34;)
+    return RedirectResponse(url=f&#34;/users-web&#34;, status_code=303)</code></pre>
+</details>
+</section>
+<section>
+</section>
+<section>
+</section>
+<section>
+<h2 class="section-title" id="header-functions">Functions</h2>
+<dl>
+<dt id="sql_app.api.users_web.connect_pc_team"><code class="name flex">
+<span>async def <span class="ident">connect_pc_team</span></span>(<span>usr_id: int, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Changes role of user to either guest or admin depending on old role.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@users.get(&#34;/user-role/{usr_id}&#34;, response_class=HTMLResponse)
+async def connect_pc_team(usr_id: int, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Changes role of user to either guest or admin depending on old role.
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != &#34;admin&#34;:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)
+    user = crud.find_user_byid(db, usr_id)
+    if user.role == &#34;admin&#34;:
+        crud.change_role(db, usr_id, &#34;guest&#34;)
+    else:
+        crud.change_role(db, usr_id, &#34;admin&#34;)
+    return RedirectResponse(url=f&#34;/users-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.users_web.get_db"><code class="name flex">
+<span>def <span class="ident">get_db</span></span>(<span>)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.api.users_web.read_usrs"><code class="name flex">
+<span>async def <span class="ident">read_usrs</span></span>(<span>request: starlette.requests.Request, skip: int = 0, limit: int = 100, db: sqlalchemy.orm.session.Session = Depends(get_db), Authorize: fastapi_jwt_auth.auth_jwt.AuthJWT = Depends(NoneType))</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns template with all users currently saved in database</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">@users.get(&#34;/users-web&#34;, response_class=HTMLResponse)
+async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                   Authorize: AuthJWT = Depends()):
+    &#34;&#34;&#34;
+    Returns template with all users currently saved in database
+    &#34;&#34;&#34;
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    users = crud.get_users(db, skip, limit)
+    if current_user == &#34;admin&#34;:
+        return templates.TemplateResponse(&#34;users.html&#34;, {&#34;request&#34;: request, &#34;users&#34;: users})
+    else:
+        return RedirectResponse(url=f&#34;/logs-web&#34;, status_code=303)</code></pre>
+</details>
+</dd>
+</dl>
+</section>
+<section>
+</section>
+</article>
+<nav id="sidebar">
+<h1>Index</h1>
+<div class="toc">
+<ul></ul>
+</div>
+<ul id="index">
+<li><h3>Super-module</h3>
+<ul>
+<li><code><a title="sql_app.api" href="index.html">sql_app.api</a></code></li>
+</ul>
+</li>
+<li><h3><a href="#header-functions">Functions</a></h3>
+<ul class="">
+<li><code><a title="sql_app.api.users_web.connect_pc_team" href="#sql_app.api.users_web.connect_pc_team">connect_pc_team</a></code></li>
+<li><code><a title="sql_app.api.users_web.get_db" href="#sql_app.api.users_web.get_db">get_db</a></code></li>
+<li><code><a title="sql_app.api.users_web.read_usrs" href="#sql_app.api.users_web.read_usrs">read_usrs</a></code></li>
+</ul>
+</li>
+</ul>
+</nav>
+</main>
+<footer id="footer">
+<p>Generated by <a href="https://pdoc3.github.io/pdoc" title="pdoc: Python API documentation generator"><cite>pdoc</cite> 0.10.0</a>.</p>
+</footer>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/doc/sql_app/crud.html b/server/doc/sql_app/crud.html
index b6620d0..3130d1d 100644
--- a/server/doc/sql_app/crud.html
+++ b/server/doc/sql_app/crud.html
@@ -47,21 +47,82 @@ def get_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.Device).offset(skip).limit(limit).all()
 
 
-def find_device(db: Session, device: schemas.DeviceBase):
+def find_device(db: Session, device: schemas.DeviceTemp):
     &#34;&#34;&#34;
-    finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object
+    finds one device with  serial_number same as in given DeviceBase object
     &#34;&#34;&#34;
-    return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id,
-                                               models.Device.vendor_id == device.vendor_id,
-                                               models.Device.serial_number == device.serial_number)).first()
+    return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first()
 
 
-def create_device(db: Session, device: schemas.DeviceBase):
+def find_device_by_serial(db: Session, ser: str):
+    &#34;&#34;&#34;
+    finds one device with serial_number same as in given DeviceBase object
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first()
+
+
+def get_devices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all devices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(models.Device.id.in_(ids)).all()
+
+
+def get_bodydevices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all bodydevices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all()
+
+
+def get_headdevices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all headdevices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all()
+
+
+def find_headdevices_by_team(db: Session, team_id: int):
+    &#34;&#34;&#34;
+    Returns all head devices in specific team
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all()
+
+
+def find_bodydevices_by_team(db: Session, team_id: int):
+    &#34;&#34;&#34;
+    Returns all body devices in specific team
+    &#34;&#34;&#34;
+    return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all()
+
+
+def find_headdevices_by_license(db: Session, lic_id: int):
+    &#34;&#34;&#34;
+    Returns all head devices with specific license
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all()
+
+
+def find_bodydevices_by_license(db: Session, lic_id: int):
+    &#34;&#34;&#34;
+    Returns all body devices with specific license
+    &#34;&#34;&#34;
+    return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all()
+
+
+def get_devices_by_team(db: Session, team: int):
+    &#34;&#34;&#34;
+    returns all devices with same team
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(models.Device.team_id == team).all()
+
+
+def create_device(db: Session, device: schemas.DeviceTemp):
     &#34;&#34;&#34;
     creates new device with data from given DeviceBase object
     &#34;&#34;&#34;
     db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id,
-                              serial_number=device.serial_number, assigned=False)
+                              serial_number=device.serial_number, inventory_number=&#34;&#34;, comment=&#34;&#34;)
     db.add(db_device)
     db.commit()
     db.refresh(db_device)
@@ -86,14 +147,18 @@ def find_license(db: Session, name: str):
     &#34;&#34;&#34;
     finds one license by given string name
     &#34;&#34;&#34;
-    return db.query(models.License).filter(models.License.name == name).first()
+    return db.query(models.License).filter(models.License.license_id == name).first()
 
 
-def create_license(db: Session, name: str, expdate: date):
+def get_licenses_by_name(db: Session, name: str):
+    return db.query(models.License).filter(models.License.name == name).all()
+
+
+def create_license(db: Session, name: str, lic_id: str, expdate: date):
     &#34;&#34;&#34;
     creates new license with given name and expiration date
     &#34;&#34;&#34;
-    db_license = models.License(name=name, expiration_date=expdate)
+    db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate)
     db.add(db_license)
     db.commit()
     db.refresh(db_license)
@@ -102,11 +167,33 @@ def create_license(db: Session, name: str, expdate: date):
 
 def get_license_devices(db: Session, license_id: int):
     &#34;&#34;&#34;
-    returns all entries in devices_licenses table
+    returns all entries in devices_licenses table with given license_id
     &#34;&#34;&#34;
     return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all()
 
 
+def find_devicelicenses_by_licid_array(db: Session, lcs: []):
+    &#34;&#34;&#34;
+    Finds all device_licenses with license_id in given id array
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all()
+
+
+def get_device_licenses(db: Session, device_id: int):
+    &#34;&#34;&#34;
+    returns all entries in devices_licenses table with given device_id
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all()
+
+
+def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id: int):
+    &#34;&#34;&#34;
+    returns entry in devices_licenses table with given device id and license id
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(and_(models.DeviceLicense.device_id == device_id,
+                                                      models.DeviceLicense.license_id == license_id)).first()
+
+
 def create_device_license(db: Session, device: int, license: int, time: datetime):
     &#34;&#34;&#34;
     creates new entry in devices_licenses table with device id, license id and time.
@@ -119,6 +206,16 @@ def create_device_license(db: Session, device: int, license: int, time: datetime
     return db_device_license
 
 
+def delete_device_license(db: Session, device: int, license: int):
+    &#34;&#34;&#34;
+    deletes entry in devices_licenses table with device id, license id and time.
+    &#34;&#34;&#34;
+    db_device_license = get_devicelicense_by_devicelicense(db, device, license)
+    db_lic = db.delete(db_device_license)
+    db.commit()
+    return db_lic
+
+
 def find_pc_by_username(db: Session, name: str):
     &#34;&#34;&#34;
     Finds one pc by given username
@@ -133,19 +230,73 @@ def get_pc(db: Session, pc_id: int):
     return db.query(models.PC).filter(models.PC.id == pc_id).first()
 
 
-def update_pc(db: Session, pc_id: int, team: str):
+def update_device(db: Session, device_id: int, team: str):
     &#34;&#34;&#34;
-    Function updates team of one specific pc
+    Updates team of one specific pc
     &#34;&#34;&#34;
-    old_pc = get_pc(db, pc_id)
+    old_dev = get_device(db, device_id)
     team = get_team(db, int(team))
-    new = {&#39;id&#39;: old_pc.id, &#39;username&#39;: old_pc.username, &#39;hostname&#39;: old_pc.hostname, &#39;assigned&#39;: True,
-           &#39;team_id&#39;: team.id}
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_device_inv(db: Session, device_id: int, inv: str):
+    &#34;&#34;&#34;
+    Updates inventory number of one specific pc
+    &#34;&#34;&#34;
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: teamid}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_device_com(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates team of one specific pc
+    &#34;&#34;&#34;
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: teamid}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def change_role(db: Session, usr_id: int, role: str):
+    &#34;&#34;&#34;
+    Updates team of one specific pc
+    &#34;&#34;&#34;
+    old_usr = find_user_byid(db, usr_id)
+    new = {&#39;id&#39;: old_usr.id, &#39;username&#39;: old_usr.username, &#39;password&#39;: old_usr.password, &#39;role&#39;: role}
     for key, value in new.items():
-        setattr(old_pc, key, value)
+        setattr(old_usr, key, value)
     db.commit()
-    db.refresh(old_pc)
-    return old_pc
+    db.refresh(old_usr)
+    return old_usr
 
 
 def get_pcs(db: Session, skip: int = 0, limit: int = 100):
@@ -184,18 +335,11 @@ def find_pcs(db: Session, pcs: []):
     return db.query(models.PC).filter(models.PC.id.in_(pcs)).all()
 
 
-def get_pcs_by_team(db: Session, team_id: int):
-    &#34;&#34;&#34;
-    returns all pcs in given team by team id
-    &#34;&#34;&#34;
-    return db.query(models.PC).filter(models.PC.team_id == team_id).all()
-
-
 def create_pc(db: Session, user: str, host: str):
     &#34;&#34;&#34;
     creates new pc with given username and hostname
     &#34;&#34;&#34;
-    db_pc = models.PC(username=user, hostname=host, assigned=False)
+    db_pc = models.PC(username=user, hostname=host)
     db.add(db_pc)
     db.commit()
     db.refresh(db_pc)
@@ -234,6 +378,19 @@ def create_team(db: Session, name: str):
     return db_team
 
 
+def change_team(db: Session, team_id: int, name: str):
+    &#34;&#34;&#34;
+    Updates name of one specific team
+    &#34;&#34;&#34;
+    old_team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_team.id, &#39;name&#39;: name}
+    for key, value in new.items():
+        setattr(old_team, key, value)
+    db.commit()
+    db.refresh(old_team)
+    return old_team
+
+
 def get_head_device(db: Session, head_id: int):
     &#34;&#34;&#34;
     Returns one specific head device by given id
@@ -248,14 +405,14 @@ def get_head_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.HeadDevice).offset(skip).limit(limit).all()
 
 
-def find_head_device(db: Session, serial: schemas.HeadDeviceBase):
+def find_head_device(db: Session, serial: schemas.HeadDeviceTemp):
     &#34;&#34;&#34;
     Finds one head device by its serial number
     &#34;&#34;&#34;
     return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()
 
 
-def create_head_device(db: Session, log: schemas.HeadDeviceBase):
+def create_head_device(db: Session, log: schemas.HeadDeviceTemp):
     &#34;&#34;&#34;
     Creates new head device
     &#34;&#34;&#34;
@@ -280,29 +437,159 @@ def get_body_devices(db: Session, skip: int = 0, limit: int = 100):
     return db.query(models.BodyDevice).offset(skip).limit(limit).all()
 
 
-def find_body_device(db: Session, serial: schemas.BodyDeviceBase):
+def find_body_device(db: Session, serial: schemas.BodyDeviceTemp):
     &#34;&#34;&#34;
     Finds one body device by its serial number
     &#34;&#34;&#34;
     return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()
 
 
-def create_body_device(db: Session, log: schemas.BodyDeviceBase):
+def find_bodydevice_by_serial(db: Session, serial: str):
+    &#34;&#34;&#34;
+    Finds one specific body device by given serial number
+    &#34;&#34;&#34;
+    return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first()
+
+
+def find_headdevice_by_serial(db: Session, serial: str):
+    &#34;&#34;&#34;
+    Finds one specific head device by given serial number
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first()
+
+
+def create_body_device(db: Session, log: schemas.BodyDeviceTemp):
     &#34;&#34;&#34;
     Creates new Body device
     &#34;&#34;&#34;
-    db_body = models.BodyDevice(serial_number=log.serial_number)
+    db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number=&#34;&#34;, comment=&#34;&#34;)
     db.add(db_body)
     db.commit()
     db.refresh(db_body)
     return db_body
 
 
+def update_bodydevice_license(db: Session, device_id: int, lic_id: int):
+    &#34;&#34;&#34;
+    Updates body devices license with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_team(db: Session, device_id: int, team_id: int):
+    &#34;&#34;&#34;
+    Updates body devices team with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str):
+    &#34;&#34;&#34;
+    Updates body devices inventory number with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: dev_inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_comm(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates body devices comment with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_license(db: Session, device_id: int, lic_id: int):
+    &#34;&#34;&#34;
+    Updates head devices license with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_team(db: Session, device_id: int, team_id: int):
+    &#34;&#34;&#34;
+    Updates head devices team with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_inv(db: Session, device_id: int, dev_inv: str):
+    &#34;&#34;&#34;
+    Updates head devices inventory number with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: dev_inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_comm(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates head devices comment with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
 def get_ld_logs(db: Session, skip: int = 0, limit: int = 100):
     &#34;&#34;&#34;
     Returns all ld debugger logs in database
     &#34;&#34;&#34;
-    return db.query(models.LDLog).offset(skip).limit(limit).all()
+    return db.query(models.LDLog).order_by(desc(models.LDLog.timestamp)).offset(skip).limit(limit).all()
 
 
 def create_ld_logs(db: Session, item: schemas.LDTempBase, head_id: int, body_id: int, pc_id: int, date: datetime):
@@ -337,43 +624,330 @@ def find_filtered_logs(db: Session, logs: []):
     return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()
 
 
+def find_filtered_ldlogs(db: Session, logs: []):
+    &#34;&#34;&#34;
+    Returns all ld logs with ids in given id array.
+    &#34;&#34;&#34;
+    return db.query(models.LDLog).filter(models.LDLog.id.in_(logs)).order_by(desc(models.LDLog.timestamp)).all()
+
+
+def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str):
+    &#34;&#34;&#34;
+    Function creates query string used for filtering by pc username, team name and license name.
+    Depending on selected filters assembles query string for database
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM ld_logs AS logs WHERE&#34;
+    before_me = False
+    all_all = True
+    if pc != &#34;all&#34;:
+        all_all = False
+        pc = find_pc_by_username(db, pc)
+        if pc != None:
+            if before_me:
+                execute_string += &#34; AND logs.pc_id = &#34; + str(pc.id)
+            else:
+                before_me = True
+                execute_string += &#34; logs.pc_id = &#34; + str(pc.id)
+    if tema != &#34;all&#34;:
+        all_all = False
+        team = find_team(db, tema)
+        if team != None:
+            head_devices = find_headdevices_by_team(db, team.id)
+            body_devices = find_bodydevices_by_team(db, team.id)
+            if len(head_devices) &gt; 0 and len(body_devices) &gt; 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+            elif len(head_devices) == 0 and len(body_devices) &gt; 0:
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.body_id IN &#34; + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.body_id IN &#34; + def_b_ids
+            elif len(head_devices) &gt; 0 and len(body_devices) == 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.head_id IN &#34; + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.head_id IN &#34; + def_h_ids
+            else:
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id = -1 OR logs.body_id = -1)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id = -1 OR logs.body_id = -1)&#34;
+    if lic != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, lic)
+        if license != None:
+            head_devices = find_headdevices_by_license(db, license.id)
+            body_devices = find_bodydevices_by_license(db, license.id)
+            if len(head_devices) &gt; 0 and len(body_devices) &gt; 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+            elif len(head_devices) == 0 and len(body_devices) &gt; 0:
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.body_id IN &#34; + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.body_id IN &#34; + def_b_ids
+            elif len(head_devices) &gt; 0 and len(body_devices) == 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.head_id IN &#34; + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.head_id IN &#34; + def_h_ids
+            else:
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id = -1 OR logs.body_id = -1)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id = -1 OR logs.body_id = -1)&#34;
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM ld_logs AS logs&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM ld_logs AS logs WHERE logs.id = -1&#34;
+    result = db.execute(execute_string)
+    return result
+
+
 def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
     &#34;&#34;&#34;
     Function creates query string used for filtering by pc username, team name and license name.
     Depending on selected filters assembles query string for database
     &#34;&#34;&#34;
     execute_string = &#34;SELECT * FROM usb_logs AS logs&#34;
+    pcs = find_pc_by_username(db, pc)
     if pc != &#34;all&#34;:
-        pcs = find_pc_by_username(db, pc)
-        execute_string += &#34;  WHERE logs.pc_id = &#34; + str(pcs.id)
+        if pcs is not None:
+            execute_string += &#34;  WHERE logs.pc_id = &#34; + str(pcs.id)
     if tema != &#34;all&#34;:
         team = find_team(db, tema)
-        pcs = get_pcs_by_team(db, team.id)
-        pc_ids = &#34;(&#34;
-        for p in pcs:
-            pc_ids += str(p.id) + &#34;, &#34;
-        def_pc_ids = pc_ids[:-2] + &#34;)&#34;
-        if pc != &#34;all&#34;:
-            execute_string += &#34; AND logs.pc_id IN &#34; + def_pc_ids
-        else:
-            execute_string += &#34; WHERE logs.pc_id IN &#34; + def_pc_ids
+        if team is not None:
+            devs = get_devices_by_team(db, team.id)
+            d_ids = &#34;(&#34;
+            for p in devs:
+                d_ids += str(p.id) + &#34;, &#34;
+            def_d_ids = d_ids[:-2] + &#34;)&#34;
+            if pc != &#34;all&#34; and pcs is not None:
+                if len(def_d_ids) &gt; 1:
+                    execute_string += &#34; AND logs.device_id IN &#34; + def_d_ids
+            else:
+                if len(def_d_ids) &gt; 1:
+                    execute_string += &#34; WHERE logs.device_id IN &#34; + def_d_ids
     if lic != &#34;all&#34;:
-        license = find_license(db, lic)
-        device_licenses = get_license_devices(db, license.id)
-        dev_ids = &#34;(&#34;
-        for dev in device_licenses:
-            dev_ids += str(dev.device_id) + &#34;, &#34;
-        defin_ids = dev_ids[:-2] + &#34;)&#34;
-        if pc != &#34;all&#34; or tema != &#34;all&#34;:
-            execute_string += &#34; AND logs.device_id IN &#34; + defin_ids
-        else:
-            execute_string += &#34; WHERE logs.device_id IN &#34; + defin_ids
+        license = get_licenses_by_name(db, lic)
+        if license is not None:
+            device_licenses = get_license_devices(db, license.id)
+            dev_ids = &#34;(&#34;
+            for dev in device_licenses:
+                dev_ids += str(dev.device_id) + &#34;, &#34;
+            defin_ids = dev_ids[:-2] + &#34;)&#34;
+            if pc != &#34;all&#34; or tema != &#34;all&#34;:
+                if len(defin_ids) &gt; 1:
+                    execute_string += &#34; AND logs.device_id IN &#34; + defin_ids
+            else:
+                if len(defin_ids) &gt; 1:
+                    execute_string += &#34; WHERE logs.device_id IN &#34; + defin_ids
 
     # executing assembled query string
     result = db.execute(execute_string)
     return result
 
 
+def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered body devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM body_devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if body_id != &#34;all&#34;:
+        all_all = False
+        body_dev = find_bodydevice_by_serial(db, body_id)
+        if body_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(body_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(body_dev.id)
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.license_id = &#34; + str(license.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.license_id = &#34; + str(license.id)
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM body_devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM body_devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result
+
+
+def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered head devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM head_devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if body_id != &#34;all&#34;:
+        all_all = False
+        head_dev = find_headdevice_by_serial(db, body_id)
+        if head_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(head_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(head_dev.id)
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.license_id = &#34; + str(license.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.license_id = &#34; + str(license.id)
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM body_devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM body_devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result
+
+
+def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered keyman devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if keyman_id != &#34;all&#34;:
+        all_all = False
+        keyman_dev = find_device_by_serial(db, keyman_id)
+        if keyman_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(keyman_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(keyman_dev.id)
+    if license_name != &#34;all&#34;:
+        all_all = False
+        license = get_licenses_by_name(db, license_name)
+        if len(license) &gt; 0:
+            lic_ids = []
+            for l in license:
+                lic_ids.append(l.id)
+            dev_lics = find_devicelicenses_by_licid_array(db, lic_ids)
+            lic_ids = &#34;(&#34;
+            for l in dev_lics:
+                lic_ids += str(l.device_id) + &#34;, &#34;
+            def_lic_ids = lic_ids[:-2] + &#34;)&#34;
+            if before_me:
+                execute_string += &#34; AND device.id IN &#34; + def_lic_ids
+            else:
+                before_me = True
+                execute_string += &#34; device.id IN &#34; + def_lic_ids
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        licen_devs = get_license_devices(db, license.id)
+        ids = &#34;(&#34;
+        for lic in licen_devs:
+            ids += str(lic.device_id) + &#34;, &#34;
+        def_ids = ids[:-2] + &#34;)&#34;
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.id IN &#34; + def_ids
+            else:
+                before_me = True
+                execute_string += &#34; device.id IN &#34; + def_ids
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result
+
+
 def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_id: int, date: datetime):
     &#34;&#34;&#34;
     Creates new USB log for usb_logs database table
@@ -382,7 +956,39 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     db.add(db_log)
     db.commit()
     db.refresh(db_log)
-    return db_log</code></pre>
+    return db_log
+
+
+def get_users(db: Session, skip: int = 0, limit: int = 100):
+    &#34;&#34;&#34;
+    Returns all users saved in database
+    &#34;&#34;&#34;
+    return db.query(models.User).offset(skip).limit(limit).all()
+
+
+def find_user(db: Session, name: str):
+    &#34;&#34;&#34;
+    Finds one user by given username
+    &#34;&#34;&#34;
+    return db.query(models.User).filter(models.User.username == name).first()
+
+
+def find_user_byid(db: Session, id: int):
+    &#34;&#34;&#34;
+    Finds one user by given id
+    &#34;&#34;&#34;
+    return db.query(models.User).filter(models.User.id == id).first()
+
+
+def create_user(db: Session, name: str, passw: str, rol: str):
+    &#34;&#34;&#34;
+    Creates new user
+    &#34;&#34;&#34;
+    db_user = models.User(username=name, password=passw, role=rol)
+    db.add(db_user)
+    db.commit()
+    db.refresh(db_user)
+    return db_user</code></pre>
 </details>
 </section>
 <section>
@@ -392,8 +998,52 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 <section>
 <h2 class="section-title" id="header-functions">Functions</h2>
 <dl>
+<dt id="sql_app.crud.change_role"><code class="name flex">
+<span>def <span class="ident">change_role</span></span>(<span>db: sqlalchemy.orm.session.Session, usr_id: int, role: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates team of one specific pc</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def change_role(db: Session, usr_id: int, role: str):
+    &#34;&#34;&#34;
+    Updates team of one specific pc
+    &#34;&#34;&#34;
+    old_usr = find_user_byid(db, usr_id)
+    new = {&#39;id&#39;: old_usr.id, &#39;username&#39;: old_usr.username, &#39;password&#39;: old_usr.password, &#39;role&#39;: role}
+    for key, value in new.items():
+        setattr(old_usr, key, value)
+    db.commit()
+    db.refresh(old_usr)
+    return old_usr</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.change_team"><code class="name flex">
+<span>def <span class="ident">change_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int, name: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates name of one specific team</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def change_team(db: Session, team_id: int, name: str):
+    &#34;&#34;&#34;
+    Updates name of one specific team
+    &#34;&#34;&#34;
+    old_team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_team.id, &#39;name&#39;: name}
+    for key, value in new.items():
+        setattr(old_team, key, value)
+    db.commit()
+    db.refresh(old_team)
+    return old_team</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.create_body_device"><code class="name flex">
-<span>def <span class="ident">create_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.BodyDeviceBase" href="schemas.html#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a>)</span>
+<span>def <span class="ident">create_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.BodyDeviceTemp" href="schemas.html#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a>)</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Creates new Body device</p></div>
@@ -401,11 +1051,11 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def create_body_device(db: Session, log: schemas.BodyDeviceBase):
+<pre><code class="python">def create_body_device(db: Session, log: schemas.BodyDeviceTemp):
     &#34;&#34;&#34;
     Creates new Body device
     &#34;&#34;&#34;
-    db_body = models.BodyDevice(serial_number=log.serial_number)
+    db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number=&#34;&#34;, comment=&#34;&#34;)
     db.add(db_body)
     db.commit()
     db.refresh(db_body)
@@ -413,7 +1063,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 </details>
 </dd>
 <dt id="sql_app.crud.create_device"><code class="name flex">
-<span>def <span class="ident">create_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceBase" href="schemas.html#sql_app.schemas.DeviceBase">DeviceBase</a>)</span>
+<span>def <span class="ident">create_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceTemp" href="schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>)</span>
 </code></dt>
 <dd>
 <div class="desc"><p>creates new device with data from given DeviceBase object</p></div>
@@ -421,12 +1071,12 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def create_device(db: Session, device: schemas.DeviceBase):
+<pre><code class="python">def create_device(db: Session, device: schemas.DeviceTemp):
     &#34;&#34;&#34;
     creates new device with data from given DeviceBase object
     &#34;&#34;&#34;
     db_device = models.Device(vendor_id=device.vendor_id, product_id=device.product_id,
-                              serial_number=device.serial_number, assigned=False)
+                              serial_number=device.serial_number, inventory_number=&#34;&#34;, comment=&#34;&#34;)
     db.add(db_device)
     db.commit()
     db.refresh(db_device)
@@ -475,7 +1125,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 </details>
 </dd>
 <dt id="sql_app.crud.create_head_device"><code class="name flex">
-<span>def <span class="ident">create_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.HeadDeviceBase" href="schemas.html#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a>)</span>
+<span>def <span class="ident">create_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, log: <a title="sql_app.schemas.HeadDeviceTemp" href="schemas.html#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a>)</span>
 </code></dt>
 <dd>
 <div class="desc"><p>Creates new head device</p></div>
@@ -483,7 +1133,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def create_head_device(db: Session, log: schemas.HeadDeviceBase):
+<pre><code class="python">def create_head_device(db: Session, log: schemas.HeadDeviceTemp):
     &#34;&#34;&#34;
     Creates new head device
     &#34;&#34;&#34;
@@ -515,7 +1165,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 </details>
 </dd>
 <dt id="sql_app.crud.create_license"><code class="name flex">
-<span>def <span class="ident">create_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, expdate: datetime.date)</span>
+<span>def <span class="ident">create_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, lic_id: str, expdate: datetime.date)</span>
 </code></dt>
 <dd>
 <div class="desc"><p>creates new license with given name and expiration date</p></div>
@@ -523,11 +1173,11 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def create_license(db: Session, name: str, expdate: date):
+<pre><code class="python">def create_license(db: Session, name: str, lic_id: str, expdate: date):
     &#34;&#34;&#34;
     creates new license with given name and expiration date
     &#34;&#34;&#34;
-    db_license = models.License(name=name, expiration_date=expdate)
+    db_license = models.License(name=name, license_id=lic_id, expiration_date=expdate)
     db.add(db_license)
     db.commit()
     db.refresh(db_license)
@@ -547,7 +1197,7 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     &#34;&#34;&#34;
     creates new pc with given username and hostname
     &#34;&#34;&#34;
-    db_pc = models.PC(username=user, hostname=host, assigned=False)
+    db_pc = models.PC(username=user, hostname=host)
     db.add(db_pc)
     db.commit()
     db.refresh(db_pc)
@@ -574,133 +1224,315 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     return db_team</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_body_device"><code class="name flex">
-<span>def <span class="ident">find_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.BodyDeviceBase" href="schemas.html#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a>)</span>
+<dt id="sql_app.crud.create_user"><code class="name flex">
+<span>def <span class="ident">create_user</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str, passw: str, rol: str)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Finds one body device by its serial number</p></div>
+<div class="desc"><p>Creates new user</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_body_device(db: Session, serial: schemas.BodyDeviceBase):
+<pre><code class="python">def create_user(db: Session, name: str, passw: str, rol: str):
     &#34;&#34;&#34;
-    Finds one body device by its serial number
+    Creates new user
     &#34;&#34;&#34;
-    return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()</code></pre>
+    db_user = models.User(username=name, password=passw, role=rol)
+    db.add(db_user)
+    db.commit()
+    db.refresh(db_user)
+    return db_user</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_device"><code class="name flex">
-<span>def <span class="ident">find_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceBase" href="schemas.html#sql_app.schemas.DeviceBase">DeviceBase</a>)</span>
+<dt id="sql_app.crud.delete_device_license"><code class="name flex">
+<span>def <span class="ident">delete_device_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device: int, license: int)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object</p></div>
+<div class="desc"><p>deletes entry in devices_licenses table with device id, license id and time.</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_device(db: Session, device: schemas.DeviceBase):
+<pre><code class="python">def delete_device_license(db: Session, device: int, license: int):
     &#34;&#34;&#34;
-    finds one device with product_id, vendor_id and serial_number same as in given DeviceBase object
+    deletes entry in devices_licenses table with device id, license id and time.
     &#34;&#34;&#34;
-    return db.query(models.Device).filter(and_(models.Device.product_id == device.product_id,
-                                               models.Device.vendor_id == device.vendor_id,
-                                               models.Device.serial_number == device.serial_number)).first()</code></pre>
+    db_device_license = get_devicelicense_by_devicelicense(db, device, license)
+    db_lic = db.delete(db_device_license)
+    db.commit()
+    return db_lic</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_filtered_logs"><code class="name flex">
-<span>def <span class="ident">find_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span>
+<dt id="sql_app.crud.find_body_device"><code class="name flex">
+<span>def <span class="ident">find_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.BodyDeviceTemp" href="schemas.html#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a>)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Returns all usb logs with ids in given id array.</p></div>
+<div class="desc"><p>Finds one body device by its serial number</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_filtered_logs(db: Session, logs: []):
+<pre><code class="python">def find_body_device(db: Session, serial: schemas.BodyDeviceTemp):
     &#34;&#34;&#34;
-    Returns all usb logs with ids in given id array.
+    Finds one body device by its serial number
     &#34;&#34;&#34;
-    return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()</code></pre>
+    return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_head_device"><code class="name flex">
-<span>def <span class="ident">find_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.HeadDeviceBase" href="schemas.html#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a>)</span>
+<dt id="sql_app.crud.find_bodydevice_by_serial"><code class="name flex">
+<span>def <span class="ident">find_bodydevice_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: str)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Finds one head device by its serial number</p></div>
+<div class="desc"><p>Finds one specific body device by given serial number</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_head_device(db: Session, serial: schemas.HeadDeviceBase):
+<pre><code class="python">def find_bodydevice_by_serial(db: Session, serial: str):
     &#34;&#34;&#34;
-    Finds one head device by its serial number
+    Finds one specific body device by given serial number
     &#34;&#34;&#34;
-    return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()</code></pre>
+    return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_license"><code class="name flex">
-<span>def <span class="ident">find_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span>
+<dt id="sql_app.crud.find_bodydevices_by_license"><code class="name flex">
+<span>def <span class="ident">find_bodydevices_by_license</span></span>(<span>db: sqlalchemy.orm.session.Session, lic_id: int)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>finds one license by given string name</p></div>
+<div class="desc"><p>Returns all body devices with specific license</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_license(db: Session, name: str):
+<pre><code class="python">def find_bodydevices_by_license(db: Session, lic_id: int):
     &#34;&#34;&#34;
-    finds one license by given string name
+    Returns all body devices with specific license
     &#34;&#34;&#34;
-    return db.query(models.License).filter(models.License.name == name).first()</code></pre>
+    return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_pc"><code class="name flex">
-<span>def <span class="ident">find_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str, hostname: str)</span>
+<dt id="sql_app.crud.find_bodydevices_by_team"><code class="name flex">
+<span>def <span class="ident">find_bodydevices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Finds one pc with given username and hostname</p></div>
+<div class="desc"><p>Returns all body devices in specific team</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_pc(db: Session, username: str, hostname: str):
+<pre><code class="python">def find_bodydevices_by_team(db: Session, team_id: int):
     &#34;&#34;&#34;
-    Finds one pc with given username and hostname
+    Returns all body devices in specific team
     &#34;&#34;&#34;
-    return db.query(models.PC).filter(and_(models.PC.username == username,
-                                           models.PC.hostname == hostname)).first()</code></pre>
+    return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_pc_by_name"><code class="name flex">
-<span>def <span class="ident">find_pc_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span>
+<dt id="sql_app.crud.find_device"><code class="name flex">
+<span>def <span class="ident">find_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device: <a title="sql_app.schemas.DeviceTemp" href="schemas.html#sql_app.schemas.DeviceTemp">DeviceTemp</a>)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Finds one pc by its username</p></div>
+<div class="desc"><p>finds one device with
+serial_number same as in given DeviceBase object</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_pc_by_name(db: Session, username: str):
+<pre><code class="python">def find_device(db: Session, device: schemas.DeviceTemp):
     &#34;&#34;&#34;
-    Finds one pc by its username
+    finds one device with  serial_number same as in given DeviceBase object
     &#34;&#34;&#34;
-    return db.query(models.PC).filter(models.PC.username == username).first()</code></pre>
+    return db.query(models.Device).filter(and_(models.Device.serial_number == device.serial_number)).first()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.find_pc_by_name_all"><code class="name flex">
-<span>def <span class="ident">find_pc_by_name_all</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span>
+<dt id="sql_app.crud.find_device_by_serial"><code class="name flex">
+<span>def <span class="ident">find_device_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, ser: str)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Finds all pcs with same username</p></div>
+<div class="desc"><p>finds one device with serial_number same as in given DeviceBase object</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def find_pc_by_name_all(db: Session, username: str):
+<pre><code class="python">def find_device_by_serial(db: Session, ser: str):
     &#34;&#34;&#34;
-    Finds all pcs with same username
+    finds one device with serial_number same as in given DeviceBase object
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_devicelicenses_by_licid_array"><code class="name flex">
+<span>def <span class="ident">find_devicelicenses_by_licid_array</span></span>(<span>db: sqlalchemy.orm.session.Session, lcs: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds all device_licenses with license_id in given id array</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_devicelicenses_by_licid_array(db: Session, lcs: []):
+    &#34;&#34;&#34;
+    Finds all device_licenses with license_id in given id array
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id.in_(lcs)).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_filtered_ldlogs"><code class="name flex">
+<span>def <span class="ident">find_filtered_ldlogs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns all ld logs with ids in given id array.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_filtered_ldlogs(db: Session, logs: []):
+    &#34;&#34;&#34;
+    Returns all ld logs with ids in given id array.
+    &#34;&#34;&#34;
+    return db.query(models.LDLog).filter(models.LDLog.id.in_(logs)).order_by(desc(models.LDLog.timestamp)).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_filtered_logs"><code class="name flex">
+<span>def <span class="ident">find_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, logs: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns all usb logs with ids in given id array.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_filtered_logs(db: Session, logs: []):
+    &#34;&#34;&#34;
+    Returns all usb logs with ids in given id array.
+    &#34;&#34;&#34;
+    return db.query(models.USBLog).filter(models.USBLog.id.in_(logs)).order_by(desc(models.USBLog.timestamp)).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_head_device"><code class="name flex">
+<span>def <span class="ident">find_head_device</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: <a title="sql_app.schemas.HeadDeviceTemp" href="schemas.html#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a>)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one head device by its serial number</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_head_device(db: Session, serial: schemas.HeadDeviceTemp):
+    &#34;&#34;&#34;
+    Finds one head device by its serial number
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial.serial_number).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_headdevice_by_serial"><code class="name flex">
+<span>def <span class="ident">find_headdevice_by_serial</span></span>(<span>db: sqlalchemy.orm.session.Session, serial: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one specific head device by given serial number</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_headdevice_by_serial(db: Session, serial: str):
+    &#34;&#34;&#34;
+    Finds one specific head device by given serial number
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_headdevices_by_license"><code class="name flex">
+<span>def <span class="ident">find_headdevices_by_license</span></span>(<span>db: sqlalchemy.orm.session.Session, lic_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns all head devices with specific license</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_headdevices_by_license(db: Session, lic_id: int):
+    &#34;&#34;&#34;
+    Returns all head devices with specific license
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_headdevices_by_team"><code class="name flex">
+<span>def <span class="ident">find_headdevices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns all head devices in specific team</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_headdevices_by_team(db: Session, team_id: int):
+    &#34;&#34;&#34;
+    Returns all head devices in specific team
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_license"><code class="name flex">
+<span>def <span class="ident">find_license</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>finds one license by given string name</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_license(db: Session, name: str):
+    &#34;&#34;&#34;
+    finds one license by given string name
+    &#34;&#34;&#34;
+    return db.query(models.License).filter(models.License.license_id == name).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_pc"><code class="name flex">
+<span>def <span class="ident">find_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str, hostname: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one pc with given username and hostname</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_pc(db: Session, username: str, hostname: str):
+    &#34;&#34;&#34;
+    Finds one pc with given username and hostname
+    &#34;&#34;&#34;
+    return db.query(models.PC).filter(and_(models.PC.username == username,
+                                           models.PC.hostname == hostname)).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_pc_by_name"><code class="name flex">
+<span>def <span class="ident">find_pc_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one pc by its username</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_pc_by_name(db: Session, username: str):
+    &#34;&#34;&#34;
+    Finds one pc by its username
+    &#34;&#34;&#34;
+    return db.query(models.PC).filter(models.PC.username == username).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_pc_by_name_all"><code class="name flex">
+<span>def <span class="ident">find_pc_by_name_all</span></span>(<span>db: sqlalchemy.orm.session.Session, username: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds all pcs with same username</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_pc_by_name_all(db: Session, username: str):
+    &#34;&#34;&#34;
+    Finds all pcs with same username
     &#34;&#34;&#34;
     return db.query(models.PC).filter(models.PC.username == username).offset(0).limit(100).all()</code></pre>
 </details>
@@ -753,6 +1585,38 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     return db.query(models.Team).filter(models.Team.name == name).first()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.find_user"><code class="name flex">
+<span>def <span class="ident">find_user</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one user by given username</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_user(db: Session, name: str):
+    &#34;&#34;&#34;
+    Finds one user by given username
+    &#34;&#34;&#34;
+    return db.query(models.User).filter(models.User.username == name).first()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.find_user_byid"><code class="name flex">
+<span>def <span class="ident">find_user_byid</span></span>(<span>db: sqlalchemy.orm.session.Session, id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Finds one user by given id</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def find_user_byid(db: Session, id: int):
+    &#34;&#34;&#34;
+    Finds one user by given id
+    &#34;&#34;&#34;
+    return db.query(models.User).filter(models.User.id == id).first()</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_body_device"><code class="name flex">
 <span>def <span class="ident">get_body_device</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: int)</span>
 </code></dt>
@@ -785,6 +1649,22 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     return db.query(models.BodyDevice).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.get_bodydevices_with_ids"><code class="name flex">
+<span>def <span class="ident">get_bodydevices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns all bodydevices with given ids</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_bodydevices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all bodydevices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all()</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_device"><code class="name flex">
 <span>def <span class="ident">get_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int)</span>
 </code></dt>
@@ -801,6 +1681,39 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     return db.query(models.Device).filter(models.Device.id == device_id).first()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.get_device_licenses"><code class="name flex">
+<span>def <span class="ident">get_device_licenses</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns all entries in devices_licenses table with given device_id</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_device_licenses(db: Session, device_id: int):
+    &#34;&#34;&#34;
+    returns all entries in devices_licenses table with given device_id
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(models.DeviceLicense.device_id == device_id).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_devicelicense_by_devicelicense"><code class="name flex">
+<span>def <span class="ident">get_devicelicense_by_devicelicense</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, license_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns entry in devices_licenses table with given device id and license id</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id: int):
+    &#34;&#34;&#34;
+    returns entry in devices_licenses table with given device id and license id
+    &#34;&#34;&#34;
+    return db.query(models.DeviceLicense).filter(and_(models.DeviceLicense.device_id == device_id,
+                                                      models.DeviceLicense.license_id == license_id)).first()</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_devices"><code class="name flex">
 <span>def <span class="ident">get_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span>
 </code></dt>
@@ -817,6 +1730,348 @@ def create_device_logs(db: Session, item: schemas.USBTempBase, dev_id: int, pc_i
     return db.query(models.Device).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.get_devices_by_team"><code class="name flex">
+<span>def <span class="ident">get_devices_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns all devices with same team</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_devices_by_team(db: Session, team: int):
+    &#34;&#34;&#34;
+    returns all devices with same team
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(models.Device.team_id == team).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_devices_with_ids"><code class="name flex">
+<span>def <span class="ident">get_devices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns all devices with given ids</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_devices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all devices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.Device).filter(models.Device.id.in_(ids)).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_filtered_bodydevices"><code class="name flex">
+<span>def <span class="ident">get_filtered_bodydevices</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: str, license_id: str, team: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns filtered body devices based on given attributes</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered body devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM body_devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if body_id != &#34;all&#34;:
+        all_all = False
+        body_dev = find_bodydevice_by_serial(db, body_id)
+        if body_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(body_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(body_dev.id)
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.license_id = &#34; + str(license.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.license_id = &#34; + str(license.id)
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM body_devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM body_devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_filtered_devices"><code class="name flex">
+<span>def <span class="ident">get_filtered_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, keyman_id: str, license_name: str, license_id: str, team: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns filtered keyman devices based on given attributes</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered keyman devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if keyman_id != &#34;all&#34;:
+        all_all = False
+        keyman_dev = find_device_by_serial(db, keyman_id)
+        if keyman_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(keyman_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(keyman_dev.id)
+    if license_name != &#34;all&#34;:
+        all_all = False
+        license = get_licenses_by_name(db, license_name)
+        if len(license) &gt; 0:
+            lic_ids = []
+            for l in license:
+                lic_ids.append(l.id)
+            dev_lics = find_devicelicenses_by_licid_array(db, lic_ids)
+            lic_ids = &#34;(&#34;
+            for l in dev_lics:
+                lic_ids += str(l.device_id) + &#34;, &#34;
+            def_lic_ids = lic_ids[:-2] + &#34;)&#34;
+            if before_me:
+                execute_string += &#34; AND device.id IN &#34; + def_lic_ids
+            else:
+                before_me = True
+                execute_string += &#34; device.id IN &#34; + def_lic_ids
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        licen_devs = get_license_devices(db, license.id)
+        ids = &#34;(&#34;
+        for lic in licen_devs:
+            ids += str(lic.device_id) + &#34;, &#34;
+        def_ids = ids[:-2] + &#34;)&#34;
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.id IN &#34; + def_ids
+            else:
+                before_me = True
+                execute_string += &#34; device.id IN &#34; + def_ids
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_filtered_headdevices"><code class="name flex">
+<span>def <span class="ident">get_filtered_headdevices</span></span>(<span>db: sqlalchemy.orm.session.Session, body_id: str, license_id: str, team: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns filtered head devices based on given attributes</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str):
+    &#34;&#34;&#34;
+    returns filtered head devices based on given attributes
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM head_devices AS device WHERE&#34;
+    before_me = False
+    all_all = True
+    if body_id != &#34;all&#34;:
+        all_all = False
+        head_dev = find_headdevice_by_serial(db, body_id)
+        if head_dev != None:
+            if before_me:
+                execute_string += &#34; AND device.id = &#34; + str(head_dev.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.id = &#34; + str(head_dev.id)
+    if license_id != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += &#34; AND device.license_id = &#34; + str(license.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.license_id = &#34; + str(license.id)
+    if team != &#34;all&#34;:
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += &#34; AND device.team_id = &#34; + str(tem.id)
+            else:
+                before_me = True
+                execute_string += &#34; device.team_id = &#34; + str(tem.id)
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM body_devices AS devices&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM body_devices AS devices WHERE devices.id = -1&#34;
+    result = db.execute(execute_string)
+    return result</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.get_filtered_ldlogs"><code class="name flex">
+<span>def <span class="ident">get_filtered_ldlogs</span></span>(<span>db: sqlalchemy.orm.session.Session, pc: str, tema: str, lic: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Function creates query string used for filtering by pc username, team name and license name.
+Depending on selected filters assembles query string for database</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str):
+    &#34;&#34;&#34;
+    Function creates query string used for filtering by pc username, team name and license name.
+    Depending on selected filters assembles query string for database
+    &#34;&#34;&#34;
+    execute_string = &#34;SELECT * FROM ld_logs AS logs WHERE&#34;
+    before_me = False
+    all_all = True
+    if pc != &#34;all&#34;:
+        all_all = False
+        pc = find_pc_by_username(db, pc)
+        if pc != None:
+            if before_me:
+                execute_string += &#34; AND logs.pc_id = &#34; + str(pc.id)
+            else:
+                before_me = True
+                execute_string += &#34; logs.pc_id = &#34; + str(pc.id)
+    if tema != &#34;all&#34;:
+        all_all = False
+        team = find_team(db, tema)
+        if team != None:
+            head_devices = find_headdevices_by_team(db, team.id)
+            body_devices = find_bodydevices_by_team(db, team.id)
+            if len(head_devices) &gt; 0 and len(body_devices) &gt; 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+            elif len(head_devices) == 0 and len(body_devices) &gt; 0:
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.body_id IN &#34; + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.body_id IN &#34; + def_b_ids
+            elif len(head_devices) &gt; 0 and len(body_devices) == 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.head_id IN &#34; + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.head_id IN &#34; + def_h_ids
+            else:
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id = -1 OR logs.body_id = -1)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id = -1 OR logs.body_id = -1)&#34;
+    if lic != &#34;all&#34;:
+        all_all = False
+        license = find_license(db, lic)
+        if license != None:
+            head_devices = find_headdevices_by_license(db, license.id)
+            body_devices = find_bodydevices_by_license(db, license.id)
+            if len(head_devices) &gt; 0 and len(body_devices) &gt; 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id IN &#34; + def_h_ids + &#34; OR logs.body_id IN &#34; + def_b_ids + &#34;)&#34;
+            elif len(head_devices) == 0 and len(body_devices) &gt; 0:
+                b_ids = &#34;(&#34;
+                for b in body_devices:
+                    b_ids += str(b.id) + &#34;, &#34;
+                def_b_ids = b_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.body_id IN &#34; + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.body_id IN &#34; + def_b_ids
+            elif len(head_devices) &gt; 0 and len(body_devices) == 0:
+                h_ids = &#34;(&#34;
+                for h in head_devices:
+                    h_ids += str(h.id) + &#34;, &#34;
+                def_h_ids = h_ids[:-2] + &#34;)&#34;
+                if before_me:
+                    execute_string += &#34; AND logs.head_id IN &#34; + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += &#34; logs.head_id IN &#34; + def_h_ids
+            else:
+                if before_me:
+                    execute_string += &#34; AND (logs.head_id = -1 OR logs.body_id = -1)&#34;
+                else:
+                    before_me = True
+                    execute_string += &#34; (logs.head_id = -1 OR logs.body_id = -1)&#34;
+    if all_all:
+        before_me = True
+        execute_string = &#34;SELECT * FROM ld_logs AS logs&#34;
+
+    if not before_me:
+        execute_string = &#34;SELECT * FROM ld_logs AS logs WHERE logs.id = -1&#34;
+    result = db.execute(execute_string)
+    return result</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_filtered_logs"><code class="name flex">
 <span>def <span class="ident">get_filtered_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, pc: str, tema: str, lic: str)</span>
 </code></dt>
@@ -833,31 +2088,38 @@ Depending on selected filters assembles query string for database</p></div>
     Depending on selected filters assembles query string for database
     &#34;&#34;&#34;
     execute_string = &#34;SELECT * FROM usb_logs AS logs&#34;
+    pcs = find_pc_by_username(db, pc)
     if pc != &#34;all&#34;:
-        pcs = find_pc_by_username(db, pc)
-        execute_string += &#34;  WHERE logs.pc_id = &#34; + str(pcs.id)
+        if pcs is not None:
+            execute_string += &#34;  WHERE logs.pc_id = &#34; + str(pcs.id)
     if tema != &#34;all&#34;:
         team = find_team(db, tema)
-        pcs = get_pcs_by_team(db, team.id)
-        pc_ids = &#34;(&#34;
-        for p in pcs:
-            pc_ids += str(p.id) + &#34;, &#34;
-        def_pc_ids = pc_ids[:-2] + &#34;)&#34;
-        if pc != &#34;all&#34;:
-            execute_string += &#34; AND logs.pc_id IN &#34; + def_pc_ids
-        else:
-            execute_string += &#34; WHERE logs.pc_id IN &#34; + def_pc_ids
+        if team is not None:
+            devs = get_devices_by_team(db, team.id)
+            d_ids = &#34;(&#34;
+            for p in devs:
+                d_ids += str(p.id) + &#34;, &#34;
+            def_d_ids = d_ids[:-2] + &#34;)&#34;
+            if pc != &#34;all&#34; and pcs is not None:
+                if len(def_d_ids) &gt; 1:
+                    execute_string += &#34; AND logs.device_id IN &#34; + def_d_ids
+            else:
+                if len(def_d_ids) &gt; 1:
+                    execute_string += &#34; WHERE logs.device_id IN &#34; + def_d_ids
     if lic != &#34;all&#34;:
-        license = find_license(db, lic)
-        device_licenses = get_license_devices(db, license.id)
-        dev_ids = &#34;(&#34;
-        for dev in device_licenses:
-            dev_ids += str(dev.device_id) + &#34;, &#34;
-        defin_ids = dev_ids[:-2] + &#34;)&#34;
-        if pc != &#34;all&#34; or tema != &#34;all&#34;:
-            execute_string += &#34; AND logs.device_id IN &#34; + defin_ids
-        else:
-            execute_string += &#34; WHERE logs.device_id IN &#34; + defin_ids
+        license = get_licenses_by_name(db, lic)
+        if license is not None:
+            device_licenses = get_license_devices(db, license.id)
+            dev_ids = &#34;(&#34;
+            for dev in device_licenses:
+                dev_ids += str(dev.device_id) + &#34;, &#34;
+            defin_ids = dev_ids[:-2] + &#34;)&#34;
+            if pc != &#34;all&#34; or tema != &#34;all&#34;:
+                if len(defin_ids) &gt; 1:
+                    execute_string += &#34; AND logs.device_id IN &#34; + defin_ids
+            else:
+                if len(defin_ids) &gt; 1:
+                    execute_string += &#34; WHERE logs.device_id IN &#34; + defin_ids
 
     # executing assembled query string
     result = db.execute(execute_string)
@@ -896,6 +2158,22 @@ Depending on selected filters assembles query string for database</p></div>
     return db.query(models.HeadDevice).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.get_headdevices_with_ids"><code class="name flex">
+<span>def <span class="ident">get_headdevices_with_ids</span></span>(<span>db: sqlalchemy.orm.session.Session, ids: [])</span>
+</code></dt>
+<dd>
+<div class="desc"><p>returns all headdevices with given ids</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_headdevices_with_ids(db: Session, ids: []):
+    &#34;&#34;&#34;
+    returns all headdevices with given ids
+    &#34;&#34;&#34;
+    return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all()</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_ld_logs"><code class="name flex">
 <span>def <span class="ident">get_ld_logs</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span>
 </code></dt>
@@ -909,7 +2187,7 @@ Depending on selected filters assembles query string for database</p></div>
     &#34;&#34;&#34;
     Returns all ld debugger logs in database
     &#34;&#34;&#34;
-    return db.query(models.LDLog).offset(skip).limit(limit).all()</code></pre>
+    return db.query(models.LDLog).order_by(desc(models.LDLog.timestamp)).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
 <dt id="sql_app.crud.get_license"><code class="name flex">
@@ -932,14 +2210,14 @@ Depending on selected filters assembles query string for database</p></div>
 <span>def <span class="ident">get_license_devices</span></span>(<span>db: sqlalchemy.orm.session.Session, license_id: int)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>returns all entries in devices_licenses table</p></div>
+<div class="desc"><p>returns all entries in devices_licenses table with given license_id</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">def get_license_devices(db: Session, license_id: int):
     &#34;&#34;&#34;
-    returns all entries in devices_licenses table
+    returns all entries in devices_licenses table with given license_id
     &#34;&#34;&#34;
     return db.query(models.DeviceLicense).filter(models.DeviceLicense.license_id == license_id).all()</code></pre>
 </details>
@@ -960,6 +2238,19 @@ Depending on selected filters assembles query string for database</p></div>
     return db.query(models.License).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
+<dt id="sql_app.crud.get_licenses_by_name"><code class="name flex">
+<span>def <span class="ident">get_licenses_by_name</span></span>(<span>db: sqlalchemy.orm.session.Session, name: str)</span>
+</code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_licenses_by_name(db: Session, name: str):
+    return db.query(models.License).filter(models.License.name == name).all()</code></pre>
+</details>
+</dd>
 <dt id="sql_app.crud.get_log"><code class="name flex">
 <span>def <span class="ident">get_log</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, skip: int = 0, limit: int = 100)</span>
 </code></dt>
@@ -1024,22 +2315,6 @@ Depending on selected filters assembles query string for database</p></div>
     return db.query(models.PC).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.get_pcs_by_team"><code class="name flex">
-<span>def <span class="ident">get_pcs_by_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span>
-</code></dt>
-<dd>
-<div class="desc"><p>returns all pcs in given team by team id</p></div>
-<details class="source">
-<summary>
-<span>Expand source code</span>
-</summary>
-<pre><code class="python">def get_pcs_by_team(db: Session, team_id: int):
-    &#34;&#34;&#34;
-    returns all pcs in given team by team id
-    &#34;&#34;&#34;
-    return db.query(models.PC).filter(models.PC.team_id == team_id).all()</code></pre>
-</details>
-</dd>
 <dt id="sql_app.crud.get_team"><code class="name flex">
 <span>def <span class="ident">get_team</span></span>(<span>db: sqlalchemy.orm.session.Session, team_id: int)</span>
 </code></dt>
@@ -1072,28 +2347,291 @@ Depending on selected filters assembles query string for database</p></div>
     return db.query(models.Team).offset(skip).limit(limit).all()</code></pre>
 </details>
 </dd>
-<dt id="sql_app.crud.update_pc"><code class="name flex">
-<span>def <span class="ident">update_pc</span></span>(<span>db: sqlalchemy.orm.session.Session, pc_id: int, team: str)</span>
+<dt id="sql_app.crud.get_users"><code class="name flex">
+<span>def <span class="ident">get_users</span></span>(<span>db: sqlalchemy.orm.session.Session, skip: int = 0, limit: int = 100)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Returns all users saved in database</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def get_users(db: Session, skip: int = 0, limit: int = 100):
+    &#34;&#34;&#34;
+    Returns all users saved in database
+    &#34;&#34;&#34;
+    return db.query(models.User).offset(skip).limit(limit).all()</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_bodydevice_comm"><code class="name flex">
+<span>def <span class="ident">update_bodydevice_comm</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates body devices comment with new one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_bodydevice_comm(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates body devices comment with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_bodydevice_inv"><code class="name flex">
+<span>def <span class="ident">update_bodydevice_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, dev_inv: str)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Function updates team of one specific pc</p></div>
+<div class="desc"><p>Updates body devices inventory number with new one given by user</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def update_pc(db: Session, pc_id: int, team: str):
+<pre><code class="python">def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str):
     &#34;&#34;&#34;
-    Function updates team of one specific pc
+    Updates body devices inventory number with new one given by user
     &#34;&#34;&#34;
-    old_pc = get_pc(db, pc_id)
+    old_dev = get_body_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: dev_inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_bodydevice_license"><code class="name flex">
+<span>def <span class="ident">update_bodydevice_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, lic_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates body devices license with one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_bodydevice_license(db: Session, device_id: int, lic_id: int):
+    &#34;&#34;&#34;
+    Updates body devices license with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_bodydevice_team"><code class="name flex">
+<span>def <span class="ident">update_bodydevice_team</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates body devices team with one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_bodydevice_team(db: Session, device_id: int, team_id: int):
+    &#34;&#34;&#34;
+    Updates body devices team with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_body_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_device"><code class="name flex">
+<span>def <span class="ident">update_device</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates team of one specific pc</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_device(db: Session, device_id: int, team: str):
+    &#34;&#34;&#34;
+    Updates team of one specific pc
+    &#34;&#34;&#34;
+    old_dev = get_device(db, device_id)
     team = get_team(db, int(team))
-    new = {&#39;id&#39;: old_pc.id, &#39;username&#39;: old_pc.username, &#39;hostname&#39;: old_pc.hostname, &#39;assigned&#39;: True,
-           &#39;team_id&#39;: team.id}
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_device_com"><code class="name flex">
+<span>def <span class="ident">update_device_com</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates team of one specific pc</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_device_com(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates team of one specific pc
+    &#34;&#34;&#34;
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: teamid}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_device_inv"><code class="name flex">
+<span>def <span class="ident">update_device_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, inv: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates inventory number of one specific pc</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_device_inv(db: Session, device_id: int, inv: str):
+    &#34;&#34;&#34;
+    Updates inventory number of one specific pc
+    &#34;&#34;&#34;
+    old_dev = get_device(db, device_id)
+    if old_dev.team_id != None:
+        team = get_team(db, int(old_dev.team_id))
+        teamid = team.id
+    else:
+        teamid = None
+    new = {&#39;id&#39;: old_dev.id, &#39;vendor_id&#39;: old_dev.vendor_id, &#39;product_id&#39;: old_dev.product_id,
+           &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: teamid}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_headdevice_comm"><code class="name flex">
+<span>def <span class="ident">update_headdevice_comm</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, comm: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates head devices comment with new one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_headdevice_comm(db: Session, device_id: int, comm: str):
+    &#34;&#34;&#34;
+    Updates head devices comment with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: comm, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_headdevice_inv"><code class="name flex">
+<span>def <span class="ident">update_headdevice_inv</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, dev_inv: str)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates head devices inventory number with new one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_headdevice_inv(db: Session, device_id: int, dev_inv: str):
+    &#34;&#34;&#34;
+    Updates head devices inventory number with new one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: dev_inv,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_headdevice_license"><code class="name flex">
+<span>def <span class="ident">update_headdevice_license</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, lic_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates head devices license with one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_headdevice_license(db: Session, device_id: int, lic_id: int):
+    &#34;&#34;&#34;
+    Updates head devices license with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: old_dev.team_id, &#39;license_id&#39;: lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev</code></pre>
+</details>
+</dd>
+<dt id="sql_app.crud.update_headdevice_team"><code class="name flex">
+<span>def <span class="ident">update_headdevice_team</span></span>(<span>db: sqlalchemy.orm.session.Session, device_id: int, team_id: int)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Updates head devices team with one given by user</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def update_headdevice_team(db: Session, device_id: int, team_id: int):
+    &#34;&#34;&#34;
+    Updates head devices team with one given by user
+    &#34;&#34;&#34;
+    old_dev = get_head_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {&#39;id&#39;: old_dev.id, &#39;serial_number&#39;: old_dev.serial_number, &#39;inventory_number&#39;: old_dev.inventory_number,
+           &#39;comment&#39;: old_dev.comment, &#39;team_id&#39;: team.id, &#39;license_id&#39;: old_dev.license_id}
     for key, value in new.items():
-        setattr(old_pc, key, value)
+        setattr(old_dev, key, value)
     db.commit()
-    db.refresh(old_pc)
-    return old_pc</code></pre>
+    db.refresh(old_dev)
+    return old_dev</code></pre>
 </details>
 </dd>
 </dl>
@@ -1114,6 +2652,8 @@ Depending on selected filters assembles query string for database</p></div>
 </li>
 <li><h3><a href="#header-functions">Functions</a></h3>
 <ul class="">
+<li><code><a title="sql_app.crud.change_role" href="#sql_app.crud.change_role">change_role</a></code></li>
+<li><code><a title="sql_app.crud.change_team" href="#sql_app.crud.change_team">change_team</a></code></li>
 <li><code><a title="sql_app.crud.create_body_device" href="#sql_app.crud.create_body_device">create_body_device</a></code></li>
 <li><code><a title="sql_app.crud.create_device" href="#sql_app.crud.create_device">create_device</a></code></li>
 <li><code><a title="sql_app.crud.create_device_license" href="#sql_app.crud.create_device_license">create_device_license</a></code></li>
@@ -1123,10 +2663,21 @@ Depending on selected filters assembles query string for database</p></div>
 <li><code><a title="sql_app.crud.create_license" href="#sql_app.crud.create_license">create_license</a></code></li>
 <li><code><a title="sql_app.crud.create_pc" href="#sql_app.crud.create_pc">create_pc</a></code></li>
 <li><code><a title="sql_app.crud.create_team" href="#sql_app.crud.create_team">create_team</a></code></li>
+<li><code><a title="sql_app.crud.create_user" href="#sql_app.crud.create_user">create_user</a></code></li>
+<li><code><a title="sql_app.crud.delete_device_license" href="#sql_app.crud.delete_device_license">delete_device_license</a></code></li>
 <li><code><a title="sql_app.crud.find_body_device" href="#sql_app.crud.find_body_device">find_body_device</a></code></li>
+<li><code><a title="sql_app.crud.find_bodydevice_by_serial" href="#sql_app.crud.find_bodydevice_by_serial">find_bodydevice_by_serial</a></code></li>
+<li><code><a title="sql_app.crud.find_bodydevices_by_license" href="#sql_app.crud.find_bodydevices_by_license">find_bodydevices_by_license</a></code></li>
+<li><code><a title="sql_app.crud.find_bodydevices_by_team" href="#sql_app.crud.find_bodydevices_by_team">find_bodydevices_by_team</a></code></li>
 <li><code><a title="sql_app.crud.find_device" href="#sql_app.crud.find_device">find_device</a></code></li>
+<li><code><a title="sql_app.crud.find_device_by_serial" href="#sql_app.crud.find_device_by_serial">find_device_by_serial</a></code></li>
+<li><code><a title="sql_app.crud.find_devicelicenses_by_licid_array" href="#sql_app.crud.find_devicelicenses_by_licid_array">find_devicelicenses_by_licid_array</a></code></li>
+<li><code><a title="sql_app.crud.find_filtered_ldlogs" href="#sql_app.crud.find_filtered_ldlogs">find_filtered_ldlogs</a></code></li>
 <li><code><a title="sql_app.crud.find_filtered_logs" href="#sql_app.crud.find_filtered_logs">find_filtered_logs</a></code></li>
 <li><code><a title="sql_app.crud.find_head_device" href="#sql_app.crud.find_head_device">find_head_device</a></code></li>
+<li><code><a title="sql_app.crud.find_headdevice_by_serial" href="#sql_app.crud.find_headdevice_by_serial">find_headdevice_by_serial</a></code></li>
+<li><code><a title="sql_app.crud.find_headdevices_by_license" href="#sql_app.crud.find_headdevices_by_license">find_headdevices_by_license</a></code></li>
+<li><code><a title="sql_app.crud.find_headdevices_by_team" href="#sql_app.crud.find_headdevices_by_team">find_headdevices_by_team</a></code></li>
 <li><code><a title="sql_app.crud.find_license" href="#sql_app.crud.find_license">find_license</a></code></li>
 <li><code><a title="sql_app.crud.find_pc" href="#sql_app.crud.find_pc">find_pc</a></code></li>
 <li><code><a title="sql_app.crud.find_pc_by_name" href="#sql_app.crud.find_pc_by_name">find_pc_by_name</a></code></li>
@@ -1134,25 +2685,48 @@ Depending on selected filters assembles query string for database</p></div>
 <li><code><a title="sql_app.crud.find_pc_by_username" href="#sql_app.crud.find_pc_by_username">find_pc_by_username</a></code></li>
 <li><code><a title="sql_app.crud.find_pcs" href="#sql_app.crud.find_pcs">find_pcs</a></code></li>
 <li><code><a title="sql_app.crud.find_team" href="#sql_app.crud.find_team">find_team</a></code></li>
+<li><code><a title="sql_app.crud.find_user" href="#sql_app.crud.find_user">find_user</a></code></li>
+<li><code><a title="sql_app.crud.find_user_byid" href="#sql_app.crud.find_user_byid">find_user_byid</a></code></li>
 <li><code><a title="sql_app.crud.get_body_device" href="#sql_app.crud.get_body_device">get_body_device</a></code></li>
 <li><code><a title="sql_app.crud.get_body_devices" href="#sql_app.crud.get_body_devices">get_body_devices</a></code></li>
+<li><code><a title="sql_app.crud.get_bodydevices_with_ids" href="#sql_app.crud.get_bodydevices_with_ids">get_bodydevices_with_ids</a></code></li>
 <li><code><a title="sql_app.crud.get_device" href="#sql_app.crud.get_device">get_device</a></code></li>
+<li><code><a title="sql_app.crud.get_device_licenses" href="#sql_app.crud.get_device_licenses">get_device_licenses</a></code></li>
+<li><code><a title="sql_app.crud.get_devicelicense_by_devicelicense" href="#sql_app.crud.get_devicelicense_by_devicelicense">get_devicelicense_by_devicelicense</a></code></li>
 <li><code><a title="sql_app.crud.get_devices" href="#sql_app.crud.get_devices">get_devices</a></code></li>
+<li><code><a title="sql_app.crud.get_devices_by_team" href="#sql_app.crud.get_devices_by_team">get_devices_by_team</a></code></li>
+<li><code><a title="sql_app.crud.get_devices_with_ids" href="#sql_app.crud.get_devices_with_ids">get_devices_with_ids</a></code></li>
+<li><code><a title="sql_app.crud.get_filtered_bodydevices" href="#sql_app.crud.get_filtered_bodydevices">get_filtered_bodydevices</a></code></li>
+<li><code><a title="sql_app.crud.get_filtered_devices" href="#sql_app.crud.get_filtered_devices">get_filtered_devices</a></code></li>
+<li><code><a title="sql_app.crud.get_filtered_headdevices" href="#sql_app.crud.get_filtered_headdevices">get_filtered_headdevices</a></code></li>
+<li><code><a title="sql_app.crud.get_filtered_ldlogs" href="#sql_app.crud.get_filtered_ldlogs">get_filtered_ldlogs</a></code></li>
 <li><code><a title="sql_app.crud.get_filtered_logs" href="#sql_app.crud.get_filtered_logs">get_filtered_logs</a></code></li>
 <li><code><a title="sql_app.crud.get_head_device" href="#sql_app.crud.get_head_device">get_head_device</a></code></li>
 <li><code><a title="sql_app.crud.get_head_devices" href="#sql_app.crud.get_head_devices">get_head_devices</a></code></li>
+<li><code><a title="sql_app.crud.get_headdevices_with_ids" href="#sql_app.crud.get_headdevices_with_ids">get_headdevices_with_ids</a></code></li>
 <li><code><a title="sql_app.crud.get_ld_logs" href="#sql_app.crud.get_ld_logs">get_ld_logs</a></code></li>
 <li><code><a title="sql_app.crud.get_license" href="#sql_app.crud.get_license">get_license</a></code></li>
 <li><code><a title="sql_app.crud.get_license_devices" href="#sql_app.crud.get_license_devices">get_license_devices</a></code></li>
 <li><code><a title="sql_app.crud.get_licenses" href="#sql_app.crud.get_licenses">get_licenses</a></code></li>
+<li><code><a title="sql_app.crud.get_licenses_by_name" href="#sql_app.crud.get_licenses_by_name">get_licenses_by_name</a></code></li>
 <li><code><a title="sql_app.crud.get_log" href="#sql_app.crud.get_log">get_log</a></code></li>
 <li><code><a title="sql_app.crud.get_logs" href="#sql_app.crud.get_logs">get_logs</a></code></li>
 <li><code><a title="sql_app.crud.get_pc" href="#sql_app.crud.get_pc">get_pc</a></code></li>
 <li><code><a title="sql_app.crud.get_pcs" href="#sql_app.crud.get_pcs">get_pcs</a></code></li>
-<li><code><a title="sql_app.crud.get_pcs_by_team" href="#sql_app.crud.get_pcs_by_team">get_pcs_by_team</a></code></li>
 <li><code><a title="sql_app.crud.get_team" href="#sql_app.crud.get_team">get_team</a></code></li>
 <li><code><a title="sql_app.crud.get_teams" href="#sql_app.crud.get_teams">get_teams</a></code></li>
-<li><code><a title="sql_app.crud.update_pc" href="#sql_app.crud.update_pc">update_pc</a></code></li>
+<li><code><a title="sql_app.crud.get_users" href="#sql_app.crud.get_users">get_users</a></code></li>
+<li><code><a title="sql_app.crud.update_bodydevice_comm" href="#sql_app.crud.update_bodydevice_comm">update_bodydevice_comm</a></code></li>
+<li><code><a title="sql_app.crud.update_bodydevice_inv" href="#sql_app.crud.update_bodydevice_inv">update_bodydevice_inv</a></code></li>
+<li><code><a title="sql_app.crud.update_bodydevice_license" href="#sql_app.crud.update_bodydevice_license">update_bodydevice_license</a></code></li>
+<li><code><a title="sql_app.crud.update_bodydevice_team" href="#sql_app.crud.update_bodydevice_team">update_bodydevice_team</a></code></li>
+<li><code><a title="sql_app.crud.update_device" href="#sql_app.crud.update_device">update_device</a></code></li>
+<li><code><a title="sql_app.crud.update_device_com" href="#sql_app.crud.update_device_com">update_device_com</a></code></li>
+<li><code><a title="sql_app.crud.update_device_inv" href="#sql_app.crud.update_device_inv">update_device_inv</a></code></li>
+<li><code><a title="sql_app.crud.update_headdevice_comm" href="#sql_app.crud.update_headdevice_comm">update_headdevice_comm</a></code></li>
+<li><code><a title="sql_app.crud.update_headdevice_inv" href="#sql_app.crud.update_headdevice_inv">update_headdevice_inv</a></code></li>
+<li><code><a title="sql_app.crud.update_headdevice_license" href="#sql_app.crud.update_headdevice_license">update_headdevice_license</a></code></li>
+<li><code><a title="sql_app.crud.update_headdevice_team" href="#sql_app.crud.update_headdevice_team">update_headdevice_team</a></code></li>
 </ul>
 </li>
 </ul>
diff --git a/server/doc/sql_app/documentation.html b/server/doc/sql_app/index.html
similarity index 100%
rename from server/doc/sql_app/documentation.html
rename to server/doc/sql_app/index.html
diff --git a/server/doc/sql_app/main.html b/server/doc/sql_app/main.html
index fabf34b..2e35621 100644
--- a/server/doc/sql_app/main.html
+++ b/server/doc/sql_app/main.html
@@ -37,6 +37,11 @@ from sql_app.api.usb_logs import usblogs
 from sql_app.api.usb_logs_web import usblogs_web
 from sql_app.api.teams import teams
 from sql_app.api.teams_web import teams_web
+from sql_app.api.auth import auth
+from sql_app.api.ld_logs_web import ldlogs_web
+from sql_app.api.bodydevices_web import body_device_web
+from sql_app.api.headdevices_web import head_device_web
+from sql_app.api.users_web import users
 from fastapi import FastAPI
 
 
@@ -55,6 +60,11 @@ app.include_router(licenses_web)
 app.include_router(pcs_web)
 app.include_router(teams_web)
 app.include_router(usblogs_web)
+app.include_router(ldlogs_web)
+app.include_router(body_device_web)
+app.include_router(users)
+app.include_router(head_device_web)
+app.include_router(auth)
 
 
 if __name__ == &#34;__main__&#34;:
diff --git a/server/doc/sql_app/models.html b/server/doc/sql_app/models.html
index 6cc705a..c554ff0 100644
--- a/server/doc/sql_app/models.html
+++ b/server/doc/sql_app/models.html
@@ -42,12 +42,16 @@ class Device(Base):
     vendor_id = Column(String, index=True, nullable=False)
     product_id = Column(String, index=True, nullable=False)
     serial_number = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
 
     # relationships for foreign keys, thus connecting table with usb_logs and licenses
     # tables
     logs = relationship(&#34;USBLog&#34;, back_populates=&#34;device&#34;)
     licenses = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;device_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;devices&#34;)
 
 
 class USBLog(Base):
@@ -75,11 +79,14 @@ class License(Base):
     __tablename__ = &#34;licenses&#34;
 
     id = Column(Integer, primary_key=True, index=True)
-    name = Column(String, index=True, nullable=False)
-    expiration_date = Column(DateTime(timezone=True), server_default=func.now())
+    name = Column(String, index=True, nullable=True)
+    license_id = Column(String, index=True, nullable=False)
+    expiration_date = Column(DateTime(timezone=True), nullable=True)
 
     # relationships for foreign keys, thus connecting table with devices table
     devices = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;licenses&#34;)
+    bodydevice_lic = relationship(&#34;BodyDevice&#34;, back_populates=&#34;license&#34;)
+    headdevice_lic = relationship(&#34;HeadDevice&#34;, back_populates=&#34;license&#34;)
 
 
 class DeviceLicense(Base):
@@ -108,12 +115,9 @@ class PC(Base):
     id = Column(Integer, primary_key=True, index=True)
     username = Column(String, index=True, nullable=False)
     hostname = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
-    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
 
     # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs
     # tables
-    team = relationship(&#34;Team&#34;, back_populates=&#34;pcs&#34;)
     logs_pc = relationship(&#34;USBLog&#34;, back_populates=&#34;pc&#34;)
     ld_pc = relationship(&#34;LDLog&#34;, back_populates=&#34;ldpc&#34;)
 
@@ -127,8 +131,9 @@ class Team(Base):
     id = Column(Integer, primary_key=True, index=True)
     name = Column(String, index=True, nullable=False)
 
-    # relationships for foreign keys, thus connecting table with pc table
-    pcs = relationship(&#34;PC&#34;, back_populates=&#34;team&#34;)
+    devices = relationship(&#34;Device&#34;, back_populates=&#34;team&#34;)
+    body_devices = relationship(&#34;BodyDevice&#34;, back_populates=&#34;team&#34;)
+    head_devices = relationship(&#34;HeadDevice&#34;, back_populates=&#34;team&#34;)
 
 
 class HeadDevice(Base):
@@ -139,9 +144,16 @@ class HeadDevice(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
+    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
 
     # relationships for foreign keys, thus connecting table with ld_logs table
     h_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;head_device&#34;)
+    license = relationship(&#34;License&#34;, back_populates=&#34;headdevice_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;head_devices&#34;)
 
 
 class BodyDevice(Base):
@@ -152,9 +164,16 @@ class BodyDevice(Base):
 
     id = Column(Integer, primary_key=True, index=True)
     serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
+    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
 
     # relationships for foreign keys, thus connecting table with ld_logs table
     b_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;body_device&#34;)
+    license = relationship(&#34;License&#34;, back_populates=&#34;bodydevice_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;body_devices&#34;)
 
 
 class LDLog(Base):
@@ -174,7 +193,19 @@ class LDLog(Base):
     # tables
     ldpc = relationship(&#34;PC&#34;, back_populates=&#34;ld_pc&#34;)
     head_device = relationship(&#34;HeadDevice&#34;, back_populates=&#34;h_logs&#34;)
-    body_device = relationship(&#34;BodyDevice&#34;, back_populates=&#34;b_logs&#34;)</code></pre>
+    body_device = relationship(&#34;BodyDevice&#34;, back_populates=&#34;b_logs&#34;)
+
+
+class User(Base):
+    &#34;&#34;&#34;
+    Class defining user in database with its own role
+    &#34;&#34;&#34;
+    __tablename__ = &#34;users&#34;
+
+    id = Column(Integer, primary_key=True, index=True)
+    username = Column(String, index=True, nullable=False)
+    password = Column(String, index=True, nullable=False)
+    role = Column(String, index=True, nullable=False)</code></pre>
 </details>
 </section>
 <section>
@@ -210,9 +241,16 @@ for example, any mapped columns or relationships.</p></div>
 
     id = Column(Integer, primary_key=True, index=True)
     serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
+    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
 
     # relationships for foreign keys, thus connecting table with ld_logs table
-    b_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;body_device&#34;)</code></pre>
+    b_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;body_device&#34;)
+    license = relationship(&#34;License&#34;, back_populates=&#34;bodydevice_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;body_devices&#34;)</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -245,32 +283,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.BodyDevice.id"><code class="name">var <span class="ident">id</span></code></dt>
-<dd>
-<div class="desc"></div>
-<details class="source">
-<summary>
-<span>Expand source code</span>
-</summary>
-<pre><code class="python">def __get__(self, instance, owner):
-    if instance is None:
-        return self
-
-    dict_ = instance_dict(instance)
-    if self._supports_population and self.key in dict_:
-        return dict_[self.key]
-    else:
-        try:
-            state = instance_state(instance)
-        except AttributeError as err:
-            util.raise_(
-                orm_exc.UnmappedInstanceError(instance),
-                replace_context=err,
-            )
-        return self.impl.get(state, dict_)</code></pre>
-</details>
-</dd>
-<dt id="sql_app.models.BodyDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
+<dt id="sql_app.models.BodyDevice.comment"><code class="name">var <span class="ident">comment</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -295,48 +308,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-</dl>
-</dd>
-<dt id="sql_app.models.Device"><code class="flex name class">
-<span>class <span class="ident">Device</span></span>
-<span>(</span><span>**kwargs)</span>
-</code></dt>
-<dd>
-<div class="desc"><p>Class defining database table devices</p>
-<p>A simple constructor that allows initialization from kwargs.</p>
-<p>Sets attributes on the constructed instance using the names and
-values in <code>kwargs</code>.</p>
-<p>Only keys that are present as
-attributes of the instance's class are allowed. These could be,
-for example, any mapped columns or relationships.</p></div>
-<details class="source">
-<summary>
-<span>Expand source code</span>
-</summary>
-<pre><code class="python">class Device(Base):
-    &#34;&#34;&#34;
-    Class defining database table devices
-    &#34;&#34;&#34;
-    __tablename__ = &#34;devices&#34;
-
-    id = Column(Integer, primary_key=True, index=True)
-    vendor_id = Column(String, index=True, nullable=False)
-    product_id = Column(String, index=True, nullable=False)
-    serial_number = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
-
-    # relationships for foreign keys, thus connecting table with usb_logs and licenses
-    # tables
-    logs = relationship(&#34;USBLog&#34;, back_populates=&#34;device&#34;)
-    licenses = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;device_lic&#34;)</code></pre>
-</details>
-<h3>Ancestors</h3>
-<ul class="hlist">
-<li>sqlalchemy.orm.decl_api.Base</li>
-</ul>
-<h3>Instance variables</h3>
-<dl>
-<dt id="sql_app.models.Device.assigned"><code class="name">var <span class="ident">assigned</span></code></dt>
+<dt id="sql_app.models.BodyDevice.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -361,7 +333,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.BodyDevice.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -386,7 +358,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.licenses"><code class="name">var <span class="ident">licenses</span></code></dt>
+<dt id="sql_app.models.BodyDevice.license"><code class="name">var <span class="ident">license</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -411,7 +383,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.logs"><code class="name">var <span class="ident">logs</span></code></dt>
+<dt id="sql_app.models.BodyDevice.license_id"><code class="name">var <span class="ident">license_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -436,7 +408,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.product_id"><code class="name">var <span class="ident">product_id</span></code></dt>
+<dt id="sql_app.models.BodyDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -461,7 +433,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
+<dt id="sql_app.models.BodyDevice.team"><code class="name">var <span class="ident">team</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -486,7 +458,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Device.vendor_id"><code class="name">var <span class="ident">vendor_id</span></code></dt>
+<dt id="sql_app.models.BodyDevice.team_id"><code class="name">var <span class="ident">team_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -513,12 +485,12 @@ for example, any mapped columns or relationships.</p></div>
 </dd>
 </dl>
 </dd>
-<dt id="sql_app.models.DeviceLicense"><code class="flex name class">
-<span>class <span class="ident">DeviceLicense</span></span>
+<dt id="sql_app.models.Device"><code class="flex name class">
+<span>class <span class="ident">Device</span></span>
 <span>(</span><span>**kwargs)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Class defining database table devices_licenses</p>
+<div class="desc"><p>Class defining database table devices</p>
 <p>A simple constructor that allows initialization from kwargs.</p>
 <p>Sets attributes on the constructed instance using the names and
 values in <code>kwargs</code>.</p>
@@ -529,21 +501,26 @@ for example, any mapped columns or relationships.</p></div>
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">class DeviceLicense(Base):
+<pre><code class="python">class Device(Base):
     &#34;&#34;&#34;
-    Class defining database table devices_licenses
+    Class defining database table devices
     &#34;&#34;&#34;
-    __tablename__ = &#34;devices_licenses&#34;
+    __tablename__ = &#34;devices&#34;
 
     id = Column(Integer, primary_key=True, index=True)
-    device_id = Column(Integer, ForeignKey(&#34;devices.id&#34;))
-    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
-    assigned_datetime = Column(String, index=True, nullable=False)
+    vendor_id = Column(String, index=True, nullable=False)
+    product_id = Column(String, index=True, nullable=False)
+    serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
 
-    # relationships for foreign keys, thus connecting table with devices and licenses
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
+
+    # relationships for foreign keys, thus connecting table with usb_logs and licenses
     # tables
-    device_lic = relationship(&#34;Device&#34;, back_populates=&#34;licenses&#34;)
-    licenses = relationship(&#34;License&#34;, back_populates=&#34;devices&#34;)</code></pre>
+    logs = relationship(&#34;USBLog&#34;, back_populates=&#34;device&#34;)
+    licenses = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;device_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;devices&#34;)</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -551,7 +528,7 @@ for example, any mapped columns or relationships.</p></div>
 </ul>
 <h3>Instance variables</h3>
 <dl>
-<dt id="sql_app.models.DeviceLicense.assigned_datetime"><code class="name">var <span class="ident">assigned_datetime</span></code></dt>
+<dt id="sql_app.models.Device.comment"><code class="name">var <span class="ident">comment</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -576,7 +553,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.DeviceLicense.device_id"><code class="name">var <span class="ident">device_id</span></code></dt>
+<dt id="sql_app.models.Device.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -601,7 +578,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.DeviceLicense.device_lic"><code class="name">var <span class="ident">device_lic</span></code></dt>
+<dt id="sql_app.models.Device.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -626,7 +603,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.DeviceLicense.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.Device.licenses"><code class="name">var <span class="ident">licenses</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -651,7 +628,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.DeviceLicense.license_id"><code class="name">var <span class="ident">license_id</span></code></dt>
+<dt id="sql_app.models.Device.logs"><code class="name">var <span class="ident">logs</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -676,7 +653,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.DeviceLicense.licenses"><code class="name">var <span class="ident">licenses</span></code></dt>
+<dt id="sql_app.models.Device.product_id"><code class="name">var <span class="ident">product_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -701,43 +678,32 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-</dl>
-</dd>
-<dt id="sql_app.models.HeadDevice"><code class="flex name class">
-<span>class <span class="ident">HeadDevice</span></span>
-<span>(</span><span>**kwargs)</span>
-</code></dt>
+<dt id="sql_app.models.Device.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
 <dd>
-<div class="desc"><p>Class defining database table head_devices</p>
-<p>A simple constructor that allows initialization from kwargs.</p>
-<p>Sets attributes on the constructed instance using the names and
-values in <code>kwargs</code>.</p>
-<p>Only keys that are present as
-attributes of the instance's class are allowed. These could be,
-for example, any mapped columns or relationships.</p></div>
+<div class="desc"></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">class HeadDevice(Base):
-    &#34;&#34;&#34;
-    Class defining database table head_devices
-    &#34;&#34;&#34;
-    __tablename__ = &#34;head_devices&#34;
-
-    id = Column(Integer, primary_key=True, index=True)
-    serial_number = Column(String, index=True, nullable=False)
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
 
-    # relationships for foreign keys, thus connecting table with ld_logs table
-    h_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;head_device&#34;)</code></pre>
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
 </details>
-<h3>Ancestors</h3>
-<ul class="hlist">
-<li>sqlalchemy.orm.decl_api.Base</li>
-</ul>
-<h3>Instance variables</h3>
-<dl>
-<dt id="sql_app.models.HeadDevice.h_logs"><code class="name">var <span class="ident">h_logs</span></code></dt>
+</dd>
+<dt id="sql_app.models.Device.team"><code class="name">var <span class="ident">team</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -762,7 +728,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.HeadDevice.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.Device.team_id"><code class="name">var <span class="ident">team_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -787,7 +753,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.HeadDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
+<dt id="sql_app.models.Device.vendor_id"><code class="name">var <span class="ident">vendor_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -814,12 +780,12 @@ for example, any mapped columns or relationships.</p></div>
 </dd>
 </dl>
 </dd>
-<dt id="sql_app.models.LDLog"><code class="flex name class">
-<span>class <span class="ident">LDLog</span></span>
+<dt id="sql_app.models.DeviceLicense"><code class="flex name class">
+<span>class <span class="ident">DeviceLicense</span></span>
 <span>(</span><span>**kwargs)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Class defining database table ld_logs</p>
+<div class="desc"><p>Class defining database table devices_licenses</p>
 <p>A simple constructor that allows initialization from kwargs.</p>
 <p>Sets attributes on the constructed instance using the names and
 values in <code>kwargs</code>.</p>
@@ -830,24 +796,21 @@ for example, any mapped columns or relationships.</p></div>
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">class LDLog(Base):
+<pre><code class="python">class DeviceLicense(Base):
     &#34;&#34;&#34;
-    Class defining database table ld_logs
+    Class defining database table devices_licenses
     &#34;&#34;&#34;
-    __tablename__ = &#34;ld_logs&#34;
+    __tablename__ = &#34;devices_licenses&#34;
 
     id = Column(Integer, primary_key=True, index=True)
-    pc_id = Column(Integer, ForeignKey(&#34;pc.id&#34;))
-    timestamp = Column(DateTime(timezone=True), server_default=func.now())
-    status = Column(String, index=True, nullable=False)
-    head_id = Column(Integer, ForeignKey(&#34;head_devices.id&#34;))
-    body_id = Column(Integer, ForeignKey(&#34;body_devices.id&#34;))
+    device_id = Column(Integer, ForeignKey(&#34;devices.id&#34;))
+    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
+    assigned_datetime = Column(String, index=True, nullable=False)
 
-    # relationships for foreign keys, thus connecting table with pc, head_devices and body_devices
+    # relationships for foreign keys, thus connecting table with devices and licenses
     # tables
-    ldpc = relationship(&#34;PC&#34;, back_populates=&#34;ld_pc&#34;)
-    head_device = relationship(&#34;HeadDevice&#34;, back_populates=&#34;h_logs&#34;)
-    body_device = relationship(&#34;BodyDevice&#34;, back_populates=&#34;b_logs&#34;)</code></pre>
+    device_lic = relationship(&#34;Device&#34;, back_populates=&#34;licenses&#34;)
+    licenses = relationship(&#34;License&#34;, back_populates=&#34;devices&#34;)</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -855,7 +818,7 @@ for example, any mapped columns or relationships.</p></div>
 </ul>
 <h3>Instance variables</h3>
 <dl>
-<dt id="sql_app.models.LDLog.body_device"><code class="name">var <span class="ident">body_device</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.assigned_datetime"><code class="name">var <span class="ident">assigned_datetime</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -880,7 +843,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.body_id"><code class="name">var <span class="ident">body_id</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.device_id"><code class="name">var <span class="ident">device_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -905,7 +868,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.head_device"><code class="name">var <span class="ident">head_device</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.device_lic"><code class="name">var <span class="ident">device_lic</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -930,7 +893,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.head_id"><code class="name">var <span class="ident">head_id</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -955,7 +918,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.license_id"><code class="name">var <span class="ident">license_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -980,7 +943,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.ldpc"><code class="name">var <span class="ident">ldpc</span></code></dt>
+<dt id="sql_app.models.DeviceLicense.licenses"><code class="name">var <span class="ident">licenses</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1005,30 +968,491 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.LDLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt>
+</dl>
+</dd>
+<dt id="sql_app.models.HeadDevice"><code class="flex name class">
+<span>class <span class="ident">HeadDevice</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
 <dd>
-<div class="desc"></div>
+<div class="desc"><p>Class defining database table head_devices</p>
+<p>A simple constructor that allows initialization from kwargs.</p>
+<p>Sets attributes on the constructed instance using the names and
+values in <code>kwargs</code>.</p>
+<p>Only keys that are present as
+attributes of the instance's class are allowed. These could be,
+for example, any mapped columns or relationships.</p></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">def __get__(self, instance, owner):
-    if instance is None:
-        return self
+<pre><code class="python">class HeadDevice(Base):
+    &#34;&#34;&#34;
+    Class defining database table head_devices
+    &#34;&#34;&#34;
+    __tablename__ = &#34;head_devices&#34;
 
-    dict_ = instance_dict(instance)
-    if self._supports_population and self.key in dict_:
-        return dict_[self.key]
-    else:
-        try:
-            state = instance_state(instance)
-        except AttributeError as err:
-            util.raise_(
-                orm_exc.UnmappedInstanceError(instance),
-                replace_context=err,
-            )
-        return self.impl.get(state, dict_)</code></pre>
-</details>
+    id = Column(Integer, primary_key=True, index=True)
+    serial_number = Column(String, index=True, nullable=False)
+    inventory_number = Column(String, index=True, nullable=True)
+    comment = Column(String, index=True, nullable=True)
+
+    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
+    license_id = Column(Integer, ForeignKey(&#34;licenses.id&#34;))
+
+    # relationships for foreign keys, thus connecting table with ld_logs table
+    h_logs = relationship(&#34;LDLog&#34;, back_populates=&#34;head_device&#34;)
+    license = relationship(&#34;License&#34;, back_populates=&#34;headdevice_lic&#34;)
+    team = relationship(&#34;Team&#34;, back_populates=&#34;head_devices&#34;)</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>sqlalchemy.orm.decl_api.Base</li>
+</ul>
+<h3>Instance variables</h3>
+<dl>
+<dt id="sql_app.models.HeadDevice.comment"><code class="name">var <span class="ident">comment</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.h_logs"><code class="name">var <span class="ident">h_logs</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.inventory_number"><code class="name">var <span class="ident">inventory_number</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.license"><code class="name">var <span class="ident">license</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.license_id"><code class="name">var <span class="ident">license_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.serial_number"><code class="name">var <span class="ident">serial_number</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.team"><code class="name">var <span class="ident">team</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.HeadDevice.team_id"><code class="name">var <span class="ident">team_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+</dl>
+</dd>
+<dt id="sql_app.models.LDLog"><code class="flex name class">
+<span>class <span class="ident">LDLog</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class defining database table ld_logs</p>
+<p>A simple constructor that allows initialization from kwargs.</p>
+<p>Sets attributes on the constructed instance using the names and
+values in <code>kwargs</code>.</p>
+<p>Only keys that are present as
+attributes of the instance's class are allowed. These could be,
+for example, any mapped columns or relationships.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class LDLog(Base):
+    &#34;&#34;&#34;
+    Class defining database table ld_logs
+    &#34;&#34;&#34;
+    __tablename__ = &#34;ld_logs&#34;
+
+    id = Column(Integer, primary_key=True, index=True)
+    pc_id = Column(Integer, ForeignKey(&#34;pc.id&#34;))
+    timestamp = Column(DateTime(timezone=True), server_default=func.now())
+    status = Column(String, index=True, nullable=False)
+    head_id = Column(Integer, ForeignKey(&#34;head_devices.id&#34;))
+    body_id = Column(Integer, ForeignKey(&#34;body_devices.id&#34;))
+
+    # relationships for foreign keys, thus connecting table with pc, head_devices and body_devices
+    # tables
+    ldpc = relationship(&#34;PC&#34;, back_populates=&#34;ld_pc&#34;)
+    head_device = relationship(&#34;HeadDevice&#34;, back_populates=&#34;h_logs&#34;)
+    body_device = relationship(&#34;BodyDevice&#34;, back_populates=&#34;b_logs&#34;)</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>sqlalchemy.orm.decl_api.Base</li>
+</ul>
+<h3>Instance variables</h3>
+<dl>
+<dt id="sql_app.models.LDLog.body_device"><code class="name">var <span class="ident">body_device</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.body_id"><code class="name">var <span class="ident">body_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.head_device"><code class="name">var <span class="ident">head_device</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.head_id"><code class="name">var <span class="ident">head_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.ldpc"><code class="name">var <span class="ident">ldpc</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.LDLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
 </dd>
 <dt id="sql_app.models.LDLog.status"><code class="name">var <span class="ident">status</span></code></dt>
 <dd>
@@ -1105,19 +1529,72 @@ for example, any mapped columns or relationships.</p></div>
     __tablename__ = &#34;licenses&#34;
 
     id = Column(Integer, primary_key=True, index=True)
-    name = Column(String, index=True, nullable=False)
-    expiration_date = Column(DateTime(timezone=True), server_default=func.now())
+    name = Column(String, index=True, nullable=True)
+    license_id = Column(String, index=True, nullable=False)
+    expiration_date = Column(DateTime(timezone=True), nullable=True)
 
     # relationships for foreign keys, thus connecting table with devices table
-    devices = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;licenses&#34;)</code></pre>
+    devices = relationship(&#34;DeviceLicense&#34;, back_populates=&#34;licenses&#34;)
+    bodydevice_lic = relationship(&#34;BodyDevice&#34;, back_populates=&#34;license&#34;)
+    headdevice_lic = relationship(&#34;HeadDevice&#34;, back_populates=&#34;license&#34;)</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>sqlalchemy.orm.decl_api.Base</li>
+</ul>
+<h3>Instance variables</h3>
+<dl>
+<dt id="sql_app.models.License.bodydevice_lic"><code class="name">var <span class="ident">bodydevice_lic</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.License.devices"><code class="name">var <span class="ident">devices</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
 </details>
-<h3>Ancestors</h3>
-<ul class="hlist">
-<li>sqlalchemy.orm.decl_api.Base</li>
-</ul>
-<h3>Instance variables</h3>
-<dl>
-<dt id="sql_app.models.License.devices"><code class="name">var <span class="ident">devices</span></code></dt>
+</dd>
+<dt id="sql_app.models.License.expiration_date"><code class="name">var <span class="ident">expiration_date</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1142,7 +1619,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.License.expiration_date"><code class="name">var <span class="ident">expiration_date</span></code></dt>
+<dt id="sql_app.models.License.headdevice_lic"><code class="name">var <span class="ident">headdevice_lic</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1192,6 +1669,31 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
+<dt id="sql_app.models.License.license_id"><code class="name">var <span class="ident">license_id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
 <dt id="sql_app.models.License.name"><code class="name">var <span class="ident">name</span></code></dt>
 <dd>
 <div class="desc"></div>
@@ -1244,12 +1746,9 @@ for example, any mapped columns or relationships.</p></div>
     id = Column(Integer, primary_key=True, index=True)
     username = Column(String, index=True, nullable=False)
     hostname = Column(String, index=True, nullable=False)
-    assigned = Column(Boolean, index=True, nullable=False)
-    team_id = Column(Integer, ForeignKey(&#34;teams.id&#34;))
 
     # relationships for foreign keys, thus connecting table with teams, usb_logs and ld_logs
     # tables
-    team = relationship(&#34;Team&#34;, back_populates=&#34;pcs&#34;)
     logs_pc = relationship(&#34;USBLog&#34;, back_populates=&#34;pc&#34;)
     ld_pc = relationship(&#34;LDLog&#34;, back_populates=&#34;ldpc&#34;)</code></pre>
 </details>
@@ -1259,7 +1758,7 @@ for example, any mapped columns or relationships.</p></div>
 </ul>
 <h3>Instance variables</h3>
 <dl>
-<dt id="sql_app.models.PC.assigned"><code class="name">var <span class="ident">assigned</span></code></dt>
+<dt id="sql_app.models.PC.hostname"><code class="name">var <span class="ident">hostname</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1284,7 +1783,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.hostname"><code class="name">var <span class="ident">hostname</span></code></dt>
+<dt id="sql_app.models.PC.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1309,7 +1808,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.PC.ld_pc"><code class="name">var <span class="ident">ld_pc</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1334,7 +1833,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.ld_pc"><code class="name">var <span class="ident">ld_pc</span></code></dt>
+<dt id="sql_app.models.PC.logs_pc"><code class="name">var <span class="ident">logs_pc</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1359,7 +1858,69 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.logs_pc"><code class="name">var <span class="ident">logs_pc</span></code></dt>
+<dt id="sql_app.models.PC.username"><code class="name">var <span class="ident">username</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+</dl>
+</dd>
+<dt id="sql_app.models.Team"><code class="flex name class">
+<span>class <span class="ident">Team</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class defining database table teams</p>
+<p>A simple constructor that allows initialization from kwargs.</p>
+<p>Sets attributes on the constructed instance using the names and
+values in <code>kwargs</code>.</p>
+<p>Only keys that are present as
+attributes of the instance's class are allowed. These could be,
+for example, any mapped columns or relationships.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class Team(Base):
+    &#34;&#34;&#34;
+    Class defining database table teams
+    &#34;&#34;&#34;
+    __tablename__ = &#34;teams&#34;
+
+    id = Column(Integer, primary_key=True, index=True)
+    name = Column(String, index=True, nullable=False)
+
+    devices = relationship(&#34;Device&#34;, back_populates=&#34;team&#34;)
+    body_devices = relationship(&#34;BodyDevice&#34;, back_populates=&#34;team&#34;)
+    head_devices = relationship(&#34;HeadDevice&#34;, back_populates=&#34;team&#34;)</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>sqlalchemy.orm.decl_api.Base</li>
+</ul>
+<h3>Instance variables</h3>
+<dl>
+<dt id="sql_app.models.Team.body_devices"><code class="name">var <span class="ident">body_devices</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1384,7 +1945,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.team"><code class="name">var <span class="ident">team</span></code></dt>
+<dt id="sql_app.models.Team.devices"><code class="name">var <span class="ident">devices</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1409,7 +1970,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.team_id"><code class="name">var <span class="ident">team_id</span></code></dt>
+<dt id="sql_app.models.Team.head_devices"><code class="name">var <span class="ident">head_devices</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1434,7 +1995,32 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.PC.username"><code class="name">var <span class="ident">username</span></code></dt>
+<dt id="sql_app.models.Team.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dd>
+<div class="desc"></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
+
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
+</details>
+</dd>
+<dt id="sql_app.models.Team.name"><code class="name">var <span class="ident">name</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1461,12 +2047,12 @@ for example, any mapped columns or relationships.</p></div>
 </dd>
 </dl>
 </dd>
-<dt id="sql_app.models.Team"><code class="flex name class">
-<span>class <span class="ident">Team</span></span>
+<dt id="sql_app.models.USBLog"><code class="flex name class">
+<span>class <span class="ident">USBLog</span></span>
 <span>(</span><span>**kwargs)</span>
 </code></dt>
 <dd>
-<div class="desc"><p>Class defining database table teams</p>
+<div class="desc"><p>Class defining database table usb_logs</p>
 <p>A simple constructor that allows initialization from kwargs.</p>
 <p>Sets attributes on the constructed instance using the names and
 values in <code>kwargs</code>.</p>
@@ -1477,17 +2063,22 @@ for example, any mapped columns or relationships.</p></div>
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">class Team(Base):
+<pre><code class="python">class USBLog(Base):
     &#34;&#34;&#34;
-    Class defining database table teams
+    Class defining database table usb_logs
     &#34;&#34;&#34;
-    __tablename__ = &#34;teams&#34;
+    __tablename__ = &#34;usb_logs&#34;
 
     id = Column(Integer, primary_key=True, index=True)
-    name = Column(String, index=True, nullable=False)
+    pc_id = Column(Integer, ForeignKey(&#34;pc.id&#34;))
+    timestamp = Column(DateTime(timezone=True), server_default=func.now())
+    status = Column(String, index=True, nullable=False)
+    device_id = Column(Integer, ForeignKey(&#34;devices.id&#34;))
 
-    # relationships for foreign keys, thus connecting table with pc table
-    pcs = relationship(&#34;PC&#34;, back_populates=&#34;team&#34;)</code></pre>
+    # relationships for foreign keys, thus connecting table with devices and pc
+    # tables
+    device = relationship(&#34;Device&#34;, back_populates=&#34;logs&#34;)
+    pc = relationship(&#34;PC&#34;, back_populates=&#34;logs_pc&#34;)</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -1495,7 +2086,7 @@ for example, any mapped columns or relationships.</p></div>
 </ul>
 <h3>Instance variables</h3>
 <dl>
-<dt id="sql_app.models.Team.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.USBLog.device"><code class="name">var <span class="ident">device</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1520,7 +2111,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Team.name"><code class="name">var <span class="ident">name</span></code></dt>
+<dt id="sql_app.models.USBLog.device_id"><code class="name">var <span class="ident">device_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1545,7 +2136,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.Team.pcs"><code class="name">var <span class="ident">pcs</span></code></dt>
+<dt id="sql_app.models.USBLog.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1570,48 +2161,32 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-</dl>
-</dd>
-<dt id="sql_app.models.USBLog"><code class="flex name class">
-<span>class <span class="ident">USBLog</span></span>
-<span>(</span><span>**kwargs)</span>
-</code></dt>
+<dt id="sql_app.models.USBLog.pc"><code class="name">var <span class="ident">pc</span></code></dt>
 <dd>
-<div class="desc"><p>Class defining database table usb_logs</p>
-<p>A simple constructor that allows initialization from kwargs.</p>
-<p>Sets attributes on the constructed instance using the names and
-values in <code>kwargs</code>.</p>
-<p>Only keys that are present as
-attributes of the instance's class are allowed. These could be,
-for example, any mapped columns or relationships.</p></div>
+<div class="desc"></div>
 <details class="source">
 <summary>
 <span>Expand source code</span>
 </summary>
-<pre><code class="python">class USBLog(Base):
-    &#34;&#34;&#34;
-    Class defining database table usb_logs
-    &#34;&#34;&#34;
-    __tablename__ = &#34;usb_logs&#34;
-
-    id = Column(Integer, primary_key=True, index=True)
-    pc_id = Column(Integer, ForeignKey(&#34;pc.id&#34;))
-    timestamp = Column(DateTime(timezone=True), server_default=func.now())
-    status = Column(String, index=True, nullable=False)
-    device_id = Column(Integer, ForeignKey(&#34;devices.id&#34;))
+<pre><code class="python">def __get__(self, instance, owner):
+    if instance is None:
+        return self
 
-    # relationships for foreign keys, thus connecting table with devices and pc
-    # tables
-    device = relationship(&#34;Device&#34;, back_populates=&#34;logs&#34;)
-    pc = relationship(&#34;PC&#34;, back_populates=&#34;logs_pc&#34;)</code></pre>
+    dict_ = instance_dict(instance)
+    if self._supports_population and self.key in dict_:
+        return dict_[self.key]
+    else:
+        try:
+            state = instance_state(instance)
+        except AttributeError as err:
+            util.raise_(
+                orm_exc.UnmappedInstanceError(instance),
+                replace_context=err,
+            )
+        return self.impl.get(state, dict_)</code></pre>
 </details>
-<h3>Ancestors</h3>
-<ul class="hlist">
-<li>sqlalchemy.orm.decl_api.Base</li>
-</ul>
-<h3>Instance variables</h3>
-<dl>
-<dt id="sql_app.models.USBLog.device"><code class="name">var <span class="ident">device</span></code></dt>
+</dd>
+<dt id="sql_app.models.USBLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1636,7 +2211,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.device_id"><code class="name">var <span class="ident">device_id</span></code></dt>
+<dt id="sql_app.models.USBLog.status"><code class="name">var <span class="ident">status</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1661,7 +2236,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.id"><code class="name">var <span class="ident">id</span></code></dt>
+<dt id="sql_app.models.USBLog.timestamp"><code class="name">var <span class="ident">timestamp</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1686,7 +2261,42 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.pc"><code class="name">var <span class="ident">pc</span></code></dt>
+</dl>
+</dd>
+<dt id="sql_app.models.User"><code class="flex name class">
+<span>class <span class="ident">User</span></span>
+<span>(</span><span>**kwargs)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class defining user in database with its own role</p>
+<p>A simple constructor that allows initialization from kwargs.</p>
+<p>Sets attributes on the constructed instance using the names and
+values in <code>kwargs</code>.</p>
+<p>Only keys that are present as
+attributes of the instance's class are allowed. These could be,
+for example, any mapped columns or relationships.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class User(Base):
+    &#34;&#34;&#34;
+    Class defining user in database with its own role
+    &#34;&#34;&#34;
+    __tablename__ = &#34;users&#34;
+
+    id = Column(Integer, primary_key=True, index=True)
+    username = Column(String, index=True, nullable=False)
+    password = Column(String, index=True, nullable=False)
+    role = Column(String, index=True, nullable=False)</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>sqlalchemy.orm.decl_api.Base</li>
+</ul>
+<h3>Instance variables</h3>
+<dl>
+<dt id="sql_app.models.User.id"><code class="name">var <span class="ident">id</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1711,7 +2321,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.pc_id"><code class="name">var <span class="ident">pc_id</span></code></dt>
+<dt id="sql_app.models.User.password"><code class="name">var <span class="ident">password</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1736,7 +2346,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.status"><code class="name">var <span class="ident">status</span></code></dt>
+<dt id="sql_app.models.User.role"><code class="name">var <span class="ident">role</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1761,7 +2371,7 @@ for example, any mapped columns or relationships.</p></div>
         return self.impl.get(state, dict_)</code></pre>
 </details>
 </dd>
-<dt id="sql_app.models.USBLog.timestamp"><code class="name">var <span class="ident">timestamp</span></code></dt>
+<dt id="sql_app.models.User.username"><code class="name">var <span class="ident">username</span></code></dt>
 <dd>
 <div class="desc"></div>
 <details class="source">
@@ -1806,21 +2416,30 @@ for example, any mapped columns or relationships.</p></div>
 <ul>
 <li>
 <h4><code><a title="sql_app.models.BodyDevice" href="#sql_app.models.BodyDevice">BodyDevice</a></code></h4>
-<ul class="">
+<ul class="two-column">
 <li><code><a title="sql_app.models.BodyDevice.b_logs" href="#sql_app.models.BodyDevice.b_logs">b_logs</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.comment" href="#sql_app.models.BodyDevice.comment">comment</a></code></li>
 <li><code><a title="sql_app.models.BodyDevice.id" href="#sql_app.models.BodyDevice.id">id</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.inventory_number" href="#sql_app.models.BodyDevice.inventory_number">inventory_number</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.license" href="#sql_app.models.BodyDevice.license">license</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.license_id" href="#sql_app.models.BodyDevice.license_id">license_id</a></code></li>
 <li><code><a title="sql_app.models.BodyDevice.serial_number" href="#sql_app.models.BodyDevice.serial_number">serial_number</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.team" href="#sql_app.models.BodyDevice.team">team</a></code></li>
+<li><code><a title="sql_app.models.BodyDevice.team_id" href="#sql_app.models.BodyDevice.team_id">team_id</a></code></li>
 </ul>
 </li>
 <li>
 <h4><code><a title="sql_app.models.Device" href="#sql_app.models.Device">Device</a></code></h4>
 <ul class="two-column">
-<li><code><a title="sql_app.models.Device.assigned" href="#sql_app.models.Device.assigned">assigned</a></code></li>
+<li><code><a title="sql_app.models.Device.comment" href="#sql_app.models.Device.comment">comment</a></code></li>
 <li><code><a title="sql_app.models.Device.id" href="#sql_app.models.Device.id">id</a></code></li>
+<li><code><a title="sql_app.models.Device.inventory_number" href="#sql_app.models.Device.inventory_number">inventory_number</a></code></li>
 <li><code><a title="sql_app.models.Device.licenses" href="#sql_app.models.Device.licenses">licenses</a></code></li>
 <li><code><a title="sql_app.models.Device.logs" href="#sql_app.models.Device.logs">logs</a></code></li>
 <li><code><a title="sql_app.models.Device.product_id" href="#sql_app.models.Device.product_id">product_id</a></code></li>
 <li><code><a title="sql_app.models.Device.serial_number" href="#sql_app.models.Device.serial_number">serial_number</a></code></li>
+<li><code><a title="sql_app.models.Device.team" href="#sql_app.models.Device.team">team</a></code></li>
+<li><code><a title="sql_app.models.Device.team_id" href="#sql_app.models.Device.team_id">team_id</a></code></li>
 <li><code><a title="sql_app.models.Device.vendor_id" href="#sql_app.models.Device.vendor_id">vendor_id</a></code></li>
 </ul>
 </li>
@@ -1837,10 +2456,16 @@ for example, any mapped columns or relationships.</p></div>
 </li>
 <li>
 <h4><code><a title="sql_app.models.HeadDevice" href="#sql_app.models.HeadDevice">HeadDevice</a></code></h4>
-<ul class="">
+<ul class="two-column">
+<li><code><a title="sql_app.models.HeadDevice.comment" href="#sql_app.models.HeadDevice.comment">comment</a></code></li>
 <li><code><a title="sql_app.models.HeadDevice.h_logs" href="#sql_app.models.HeadDevice.h_logs">h_logs</a></code></li>
 <li><code><a title="sql_app.models.HeadDevice.id" href="#sql_app.models.HeadDevice.id">id</a></code></li>
+<li><code><a title="sql_app.models.HeadDevice.inventory_number" href="#sql_app.models.HeadDevice.inventory_number">inventory_number</a></code></li>
+<li><code><a title="sql_app.models.HeadDevice.license" href="#sql_app.models.HeadDevice.license">license</a></code></li>
+<li><code><a title="sql_app.models.HeadDevice.license_id" href="#sql_app.models.HeadDevice.license_id">license_id</a></code></li>
 <li><code><a title="sql_app.models.HeadDevice.serial_number" href="#sql_app.models.HeadDevice.serial_number">serial_number</a></code></li>
+<li><code><a title="sql_app.models.HeadDevice.team" href="#sql_app.models.HeadDevice.team">team</a></code></li>
+<li><code><a title="sql_app.models.HeadDevice.team_id" href="#sql_app.models.HeadDevice.team_id">team_id</a></code></li>
 </ul>
 </li>
 <li>
@@ -1859,32 +2484,34 @@ for example, any mapped columns or relationships.</p></div>
 </li>
 <li>
 <h4><code><a title="sql_app.models.License" href="#sql_app.models.License">License</a></code></h4>
-<ul class="">
+<ul class="two-column">
+<li><code><a title="sql_app.models.License.bodydevice_lic" href="#sql_app.models.License.bodydevice_lic">bodydevice_lic</a></code></li>
 <li><code><a title="sql_app.models.License.devices" href="#sql_app.models.License.devices">devices</a></code></li>
 <li><code><a title="sql_app.models.License.expiration_date" href="#sql_app.models.License.expiration_date">expiration_date</a></code></li>
+<li><code><a title="sql_app.models.License.headdevice_lic" href="#sql_app.models.License.headdevice_lic">headdevice_lic</a></code></li>
 <li><code><a title="sql_app.models.License.id" href="#sql_app.models.License.id">id</a></code></li>
+<li><code><a title="sql_app.models.License.license_id" href="#sql_app.models.License.license_id">license_id</a></code></li>
 <li><code><a title="sql_app.models.License.name" href="#sql_app.models.License.name">name</a></code></li>
 </ul>
 </li>
 <li>
 <h4><code><a title="sql_app.models.PC" href="#sql_app.models.PC">PC</a></code></h4>
-<ul class="two-column">
-<li><code><a title="sql_app.models.PC.assigned" href="#sql_app.models.PC.assigned">assigned</a></code></li>
+<ul class="">
 <li><code><a title="sql_app.models.PC.hostname" href="#sql_app.models.PC.hostname">hostname</a></code></li>
 <li><code><a title="sql_app.models.PC.id" href="#sql_app.models.PC.id">id</a></code></li>
 <li><code><a title="sql_app.models.PC.ld_pc" href="#sql_app.models.PC.ld_pc">ld_pc</a></code></li>
 <li><code><a title="sql_app.models.PC.logs_pc" href="#sql_app.models.PC.logs_pc">logs_pc</a></code></li>
-<li><code><a title="sql_app.models.PC.team" href="#sql_app.models.PC.team">team</a></code></li>
-<li><code><a title="sql_app.models.PC.team_id" href="#sql_app.models.PC.team_id">team_id</a></code></li>
 <li><code><a title="sql_app.models.PC.username" href="#sql_app.models.PC.username">username</a></code></li>
 </ul>
 </li>
 <li>
 <h4><code><a title="sql_app.models.Team" href="#sql_app.models.Team">Team</a></code></h4>
 <ul class="">
+<li><code><a title="sql_app.models.Team.body_devices" href="#sql_app.models.Team.body_devices">body_devices</a></code></li>
+<li><code><a title="sql_app.models.Team.devices" href="#sql_app.models.Team.devices">devices</a></code></li>
+<li><code><a title="sql_app.models.Team.head_devices" href="#sql_app.models.Team.head_devices">head_devices</a></code></li>
 <li><code><a title="sql_app.models.Team.id" href="#sql_app.models.Team.id">id</a></code></li>
 <li><code><a title="sql_app.models.Team.name" href="#sql_app.models.Team.name">name</a></code></li>
-<li><code><a title="sql_app.models.Team.pcs" href="#sql_app.models.Team.pcs">pcs</a></code></li>
 </ul>
 </li>
 <li>
@@ -1899,6 +2526,15 @@ for example, any mapped columns or relationships.</p></div>
 <li><code><a title="sql_app.models.USBLog.timestamp" href="#sql_app.models.USBLog.timestamp">timestamp</a></code></li>
 </ul>
 </li>
+<li>
+<h4><code><a title="sql_app.models.User" href="#sql_app.models.User">User</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.models.User.id" href="#sql_app.models.User.id">id</a></code></li>
+<li><code><a title="sql_app.models.User.password" href="#sql_app.models.User.password">password</a></code></li>
+<li><code><a title="sql_app.models.User.role" href="#sql_app.models.User.role">role</a></code></li>
+<li><code><a title="sql_app.models.User.username" href="#sql_app.models.User.username">username</a></code></li>
+</ul>
+</li>
 </ul>
 </li>
 </ul>
diff --git a/server/doc/sql_app/schemas.html b/server/doc/sql_app/schemas.html
index ffeb06a..d37e2ed 100644
--- a/server/doc/sql_app/schemas.html
+++ b/server/doc/sql_app/schemas.html
@@ -76,6 +76,8 @@ class DeviceBase(BaseModel):
     vendor_id: str
     product_id: str
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class DeviceCreate(DeviceBase):
@@ -87,7 +89,6 @@ class Device(DeviceCreate):
     Class used for creating and reading devices entries
     &#34;&#34;&#34;
     id: int
-    assigned: bool
     logs: List[USBLog] = []
     licenses: List[DeviceLicense] = []
 
@@ -95,6 +96,15 @@ class Device(DeviceCreate):
         orm_mode = True
 
 
+class DeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading data from client
+    &#34;&#34;&#34;
+    vendor_id: str
+    product_id: str
+    serial_number: str
+
+
 class LDLogBase(BaseModel):
     timestamp: datetime
     status: str
@@ -118,6 +128,8 @@ class LDLog(LDLogCreate):
 
 class BodyDeviceBase(BaseModel):
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class BodyDeviceCreate(BodyDeviceBase):
@@ -135,8 +147,17 @@ class BodyDevice(BodyDeviceCreate):
         orm_mode = True
 
 
+class BodyDeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading body device data from client
+    &#34;&#34;&#34;
+    serial_number: str
+
+
 class HeadDeviceBase(BaseModel):
     serial_number: str
+    inventory_number: str
+    comment: str
 
 
 class HeadDeviceCreate(HeadDeviceBase):
@@ -154,6 +175,13 @@ class HeadDevice(HeadDeviceCreate):
         orm_mode = True
 
 
+class HeadDeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading head device data from client
+    &#34;&#34;&#34;
+    serial_number: str
+
+
 class PCBase(BaseModel):
     username: str
     hostname: str
@@ -168,8 +196,8 @@ class PC(PCCreate):
     Class used for creating and reading pc entries
     &#34;&#34;&#34;
     id: int
-    assigned: bool
     logs_pc: List[USBLog] = []
+    logs_ld: List[LDLog] = []
 
     class Config:
         orm_mode = True
@@ -188,7 +216,7 @@ class Team(TeamCreate):
     Class used for creating and reading team entries
     &#34;&#34;&#34;
     id: int
-    pcs: List[PC] = []
+    devices: List[Device] = []
 
     class Config:
         orm_mode = True
@@ -196,6 +224,7 @@ class Team(TeamCreate):
 
 class LicenseBase(BaseModel):
     name: str
+    license_id: str
     expiration_date: date
 
 
@@ -209,6 +238,8 @@ class License(LicenseCreate):
     &#34;&#34;&#34;
     id: int
     devices: List[DeviceLicense] = []
+    head_devices: List[HeadDevice] = []
+    body_devices: List[BodyDevice] = []
 
     class Config:
         orm_mode = True
@@ -221,7 +252,7 @@ class USBTempBase(BaseModel):
     username: str
     hostname: str
     timestamp: str
-    device: DeviceBase
+    device: DeviceTemp
     status: str
 
 
@@ -244,8 +275,8 @@ class LDTempBase(BaseModel):
     username: str
     hostname: str
     timestamp: str
-    head_device: HeadDeviceBase
-    body_device: BodyDeviceBase
+    head_device: HeadDeviceTemp
+    body_device: BodyDeviceTemp
     status: str
 
 
@@ -258,6 +289,26 @@ class LDTemp(LDTempCreate):
     head_id: int
     body_id: int
 
+    class Config:
+        orm_mode = True
+
+
+class UserBase(BaseModel):
+    &#34;&#34;&#34;
+    Classes used for creating new User entry
+    &#34;&#34;&#34;
+    username: str
+    password: str
+    role: str
+
+
+class UserCreate(UserBase):
+    pass
+
+
+class User(UserCreate):
+    id: int
+
     class Config:
         orm_mode = True</code></pre>
 </details>
@@ -300,6 +351,11 @@ class LDTemp(LDTempCreate):
 <li>pydantic.main.BaseModel</li>
 <li>pydantic.utils.Representation</li>
 </ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li>pydantic.main.BodyDevice</li>
+<li>pydantic.main.BodyDevice</li>
+</ul>
 <h3>Class variables</h3>
 <dl>
 <dt id="sql_app.schemas.BodyDevice.Config"><code class="name">var <span class="ident">Config</span></code></dt>
@@ -328,7 +384,9 @@ class LDTemp(LDTempCreate):
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">class BodyDeviceBase(BaseModel):
-    serial_number: str</code></pre>
+    serial_number: str
+    inventory_number: str
+    comment: str</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -341,6 +399,14 @@ class LDTemp(LDTempCreate):
 </ul>
 <h3>Class variables</h3>
 <dl>
+<dt id="sql_app.schemas.BodyDeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.BodyDeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.BodyDeviceBase.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt>
 <dd>
 <div class="desc"></div>
@@ -372,6 +438,37 @@ class LDTemp(LDTempCreate):
 <li><a title="sql_app.schemas.BodyDevice" href="#sql_app.schemas.BodyDevice">BodyDevice</a></li>
 </ul>
 </dd>
+<dt id="sql_app.schemas.BodyDeviceTemp"><code class="flex name class">
+<span>class <span class="ident">BodyDeviceTemp</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class used for reading body device data from client</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class BodyDeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading body device data from client
+    &#34;&#34;&#34;
+    serial_number: str</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.schemas.BodyDeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
 <dt id="sql_app.schemas.Device"><code class="flex name class">
 <span>class <span class="ident">Device</span></span>
 <span>(</span><span>**data: Any)</span>
@@ -389,7 +486,6 @@ class LDTemp(LDTempCreate):
     Class used for creating and reading devices entries
     &#34;&#34;&#34;
     id: int
-    assigned: bool
     logs: List[USBLog] = []
     licenses: List[DeviceLicense] = []
 
@@ -415,6 +511,8 @@ class LDTemp(LDTempCreate):
 <li>pydantic.main.Device</li>
 <li>pydantic.main.Device</li>
 <li>pydantic.main.Device</li>
+<li>pydantic.main.Device</li>
+<li>pydantic.main.Device</li>
 </ul>
 <h3>Class variables</h3>
 <dl>
@@ -422,10 +520,6 @@ class LDTemp(LDTempCreate):
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.Device.assigned"><code class="name">var <span class="ident">assigned</span> : bool</code></dt>
-<dd>
-<div class="desc"></div>
-</dd>
 <dt id="sql_app.schemas.Device.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
 <dd>
 <div class="desc"></div>
@@ -454,7 +548,9 @@ class LDTemp(LDTempCreate):
 <pre><code class="python">class DeviceBase(BaseModel):
     vendor_id: str
     product_id: str
-    serial_number: str</code></pre>
+    serial_number: str
+    inventory_number: str
+    comment: str</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -467,6 +563,14 @@ class LDTemp(LDTempCreate):
 </ul>
 <h3>Class variables</h3>
 <dl>
+<dt id="sql_app.schemas.DeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.DeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.DeviceBase.product_id"><code class="name">var <span class="ident">product_id</span> : str</code></dt>
 <dd>
 <div class="desc"></div>
@@ -550,6 +654,8 @@ class LDTemp(LDTempCreate):
 <li>pydantic.main.DeviceLicense</li>
 <li>pydantic.main.DeviceLicense</li>
 <li>pydantic.main.DeviceLicense</li>
+<li>pydantic.main.DeviceLicense</li>
+<li>pydantic.main.DeviceLicense</li>
 </ul>
 <h3>Class variables</h3>
 <dl>
@@ -629,6 +735,47 @@ class LDTemp(LDTempCreate):
 <li><a title="sql_app.schemas.DeviceLicense" href="#sql_app.schemas.DeviceLicense">DeviceLicense</a></li>
 </ul>
 </dd>
+<dt id="sql_app.schemas.DeviceTemp"><code class="flex name class">
+<span>class <span class="ident">DeviceTemp</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class used for reading data from client</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class DeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading data from client
+    &#34;&#34;&#34;
+    vendor_id: str
+    product_id: str
+    serial_number: str</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.schemas.DeviceTemp.product_id"><code class="name">var <span class="ident">product_id</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.DeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.DeviceTemp.vendor_id"><code class="name">var <span class="ident">vendor_id</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
 <dt id="sql_app.schemas.HeadDevice"><code class="flex name class">
 <span>class <span class="ident">HeadDevice</span></span>
 <span>(</span><span>**data: Any)</span>
@@ -658,6 +805,11 @@ class LDTemp(LDTempCreate):
 <li>pydantic.main.BaseModel</li>
 <li>pydantic.utils.Representation</li>
 </ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li>pydantic.main.HeadDevice</li>
+<li>pydantic.main.HeadDevice</li>
+</ul>
 <h3>Class variables</h3>
 <dl>
 <dt id="sql_app.schemas.HeadDevice.Config"><code class="name">var <span class="ident">Config</span></code></dt>
@@ -686,7 +838,9 @@ class LDTemp(LDTempCreate):
 <span>Expand source code</span>
 </summary>
 <pre><code class="python">class HeadDeviceBase(BaseModel):
-    serial_number: str</code></pre>
+    serial_number: str
+    inventory_number: str
+    comment: str</code></pre>
 </details>
 <h3>Ancestors</h3>
 <ul class="hlist">
@@ -699,6 +853,14 @@ class LDTemp(LDTempCreate):
 </ul>
 <h3>Class variables</h3>
 <dl>
+<dt id="sql_app.schemas.HeadDeviceBase.comment"><code class="name">var <span class="ident">comment</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.HeadDeviceBase.inventory_number"><code class="name">var <span class="ident">inventory_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.HeadDeviceBase.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt>
 <dd>
 <div class="desc"></div>
@@ -730,6 +892,37 @@ class LDTemp(LDTempCreate):
 <li><a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a></li>
 </ul>
 </dd>
+<dt id="sql_app.schemas.HeadDeviceTemp"><code class="flex name class">
+<span>class <span class="ident">HeadDeviceTemp</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Class used for reading head device data from client</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class HeadDeviceTemp(BaseModel):
+    &#34;&#34;&#34;
+    Class used for reading head device data from client
+    &#34;&#34;&#34;
+    serial_number: str</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.schemas.HeadDeviceTemp.serial_number"><code class="name">var <span class="ident">serial_number</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
 <dt id="sql_app.schemas.LDLog"><code class="flex name class">
 <span>class <span class="ident">LDLog</span></span>
 <span>(</span><span>**data: Any)</span>
@@ -764,6 +957,14 @@ class LDTemp(LDTempCreate):
 <ul class="hlist">
 <li>pydantic.main.LDLog</li>
 <li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
+<li>pydantic.main.LDLog</li>
 </ul>
 <h3>Class variables</h3>
 <dl>
@@ -912,8 +1113,8 @@ class LDTemp(LDTempCreate):
     username: str
     hostname: str
     timestamp: str
-    head_device: HeadDeviceBase
-    body_device: BodyDeviceBase
+    head_device: HeadDeviceTemp
+    body_device: BodyDeviceTemp
     status: str</code></pre>
 </details>
 <h3>Ancestors</h3>
@@ -927,11 +1128,11 @@ class LDTemp(LDTempCreate):
 </ul>
 <h3>Class variables</h3>
 <dl>
-<dt id="sql_app.schemas.LDTempBase.body_device"><code class="name">var <span class="ident">body_device</span> : <a title="sql_app.schemas.BodyDeviceBase" href="#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a></code></dt>
+<dt id="sql_app.schemas.LDTempBase.body_device"><code class="name">var <span class="ident">body_device</span> : <a title="sql_app.schemas.BodyDeviceTemp" href="#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a></code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.LDTempBase.head_device"><code class="name">var <span class="ident">head_device</span> : <a title="sql_app.schemas.HeadDeviceBase" href="#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a></code></dt>
+<dt id="sql_app.schemas.LDTempBase.head_device"><code class="name">var <span class="ident">head_device</span> : <a title="sql_app.schemas.HeadDeviceTemp" href="#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a></code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
@@ -997,6 +1198,8 @@ class LDTemp(LDTempCreate):
     &#34;&#34;&#34;
     id: int
     devices: List[DeviceLicense] = []
+    head_devices: List[HeadDevice] = []
+    body_devices: List[BodyDevice] = []
 
     class Config:
         orm_mode = True</code></pre>
@@ -1019,10 +1222,18 @@ class LDTemp(LDTempCreate):
 <dd>
 <div class="desc"></div>
 </dd>
+<dt id="sql_app.schemas.License.body_devices"><code class="name">var <span class="ident">body_devices</span> : List[<a title="sql_app.schemas.BodyDevice" href="#sql_app.schemas.BodyDevice">BodyDevice</a>]</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.License.devices"><code class="name">var <span class="ident">devices</span> : List[<a title="sql_app.schemas.DeviceLicense" href="#sql_app.schemas.DeviceLicense">DeviceLicense</a>]</code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
+<dt id="sql_app.schemas.License.head_devices"><code class="name">var <span class="ident">head_devices</span> : List[<a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a>]</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.License.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
 <dd>
 <div class="desc"></div>
@@ -1042,6 +1253,7 @@ class LDTemp(LDTempCreate):
 </summary>
 <pre><code class="python">class LicenseBase(BaseModel):
     name: str
+    license_id: str
     expiration_date: date</code></pre>
 </details>
 <h3>Ancestors</h3>
@@ -1059,6 +1271,10 @@ class LDTemp(LDTempCreate):
 <dd>
 <div class="desc"></div>
 </dd>
+<dt id="sql_app.schemas.LicenseBase.license_id"><code class="name">var <span class="ident">license_id</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
 <dt id="sql_app.schemas.LicenseBase.name"><code class="name">var <span class="ident">name</span> : str</code></dt>
 <dd>
 <div class="desc"></div>
@@ -1107,8 +1323,8 @@ class LDTemp(LDTempCreate):
     Class used for creating and reading pc entries
     &#34;&#34;&#34;
     id: int
-    assigned: bool
     logs_pc: List[USBLog] = []
+    logs_ld: List[LDLog] = []
 
     class Config:
         orm_mode = True</code></pre>
@@ -1128,8 +1344,6 @@ class LDTemp(LDTempCreate):
 <li>pydantic.main.PC</li>
 <li>pydantic.main.PC</li>
 <li>pydantic.main.PC</li>
-<li>pydantic.main.PC</li>
-<li>pydantic.main.PC</li>
 </ul>
 <h3>Class variables</h3>
 <dl>
@@ -1137,11 +1351,11 @@ class LDTemp(LDTempCreate):
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.PC.assigned"><code class="name">var <span class="ident">assigned</span> : bool</code></dt>
+<dt id="sql_app.schemas.PC.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.PC.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
+<dt id="sql_app.schemas.PC.logs_ld"><code class="name">var <span class="ident">logs_ld</span> : List[<a title="sql_app.schemas.LDLog" href="#sql_app.schemas.LDLog">LDLog</a>]</code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
@@ -1229,7 +1443,7 @@ class LDTemp(LDTempCreate):
     Class used for creating and reading team entries
     &#34;&#34;&#34;
     id: int
-    pcs: List[PC] = []
+    devices: List[Device] = []
 
     class Config:
         orm_mode = True</code></pre>
@@ -1252,11 +1466,11 @@ class LDTemp(LDTempCreate):
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.Team.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
+<dt id="sql_app.schemas.Team.devices"><code class="name">var <span class="ident">devices</span> : List[<a title="sql_app.schemas.Device" href="#sql_app.schemas.Device">Device</a>]</code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
-<dt id="sql_app.schemas.Team.pcs"><code class="name">var <span class="ident">pcs</span> : List[<a title="sql_app.schemas.PC" href="#sql_app.schemas.PC">PC</a>]</code></dt>
+<dt id="sql_app.schemas.Team.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
@@ -1512,7 +1726,7 @@ class LDTemp(LDTempCreate):
     username: str
     hostname: str
     timestamp: str
-    device: DeviceBase
+    device: DeviceTemp
     status: str</code></pre>
 </details>
 <h3>Ancestors</h3>
@@ -1527,7 +1741,7 @@ class LDTemp(LDTempCreate):
 </ul>
 <h3>Class variables</h3>
 <dl>
-<dt id="sql_app.schemas.USBTempBase.device"><code class="name">var <span class="ident">device</span> : <a title="sql_app.schemas.DeviceBase" href="#sql_app.schemas.DeviceBase">DeviceBase</a></code></dt>
+<dt id="sql_app.schemas.USBTempBase.device"><code class="name">var <span class="ident">device</span> : <a title="sql_app.schemas.DeviceTemp" href="#sql_app.schemas.DeviceTemp">DeviceTemp</a></code></dt>
 <dd>
 <div class="desc"></div>
 </dd>
@@ -1571,6 +1785,114 @@ class LDTemp(LDTempCreate):
 <li>pydantic.utils.Representation</li>
 </ul>
 </dd>
+<dt id="sql_app.schemas.User"><code class="flex name class">
+<span>class <span class="ident">User</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Classes used for creating new User entry</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class User(UserCreate):
+    id: int
+
+    class Config:
+        orm_mode = True</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></li>
+<li><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></li>
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.schemas.User.Config"><code class="name">var <span class="ident">Config</span></code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.User.id"><code class="name">var <span class="ident">id</span> : int</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
+<dt id="sql_app.schemas.UserBase"><code class="flex name class">
+<span>class <span class="ident">UserBase</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Classes used for creating new User entry</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class UserBase(BaseModel):
+    &#34;&#34;&#34;
+    Classes used for creating new User entry
+    &#34;&#34;&#34;
+    username: str
+    password: str
+    role: str</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></li>
+</ul>
+<h3>Class variables</h3>
+<dl>
+<dt id="sql_app.schemas.UserBase.password"><code class="name">var <span class="ident">password</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.UserBase.role"><code class="name">var <span class="ident">role</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+<dt id="sql_app.schemas.UserBase.username"><code class="name">var <span class="ident">username</span> : str</code></dt>
+<dd>
+<div class="desc"></div>
+</dd>
+</dl>
+</dd>
+<dt id="sql_app.schemas.UserCreate"><code class="flex name class">
+<span>class <span class="ident">UserCreate</span></span>
+<span>(</span><span>**data: Any)</span>
+</code></dt>
+<dd>
+<div class="desc"><p>Classes used for creating new User entry</p>
+<p>Create a new model by parsing and validating input data from keyword arguments.</p>
+<p>Raises ValidationError if the input data cannot be parsed to form a valid model.</p></div>
+<details class="source">
+<summary>
+<span>Expand source code</span>
+</summary>
+<pre><code class="python">class UserCreate(UserBase):
+    pass</code></pre>
+</details>
+<h3>Ancestors</h3>
+<ul class="hlist">
+<li><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></li>
+<li>pydantic.main.BaseModel</li>
+<li>pydantic.utils.Representation</li>
+</ul>
+<h3>Subclasses</h3>
+<ul class="hlist">
+<li><a title="sql_app.schemas.User" href="#sql_app.schemas.User">User</a></li>
+</ul>
+</dd>
 </dl>
 </section>
 </article>
@@ -1598,6 +1920,8 @@ class LDTemp(LDTempCreate):
 <li>
 <h4><code><a title="sql_app.schemas.BodyDeviceBase" href="#sql_app.schemas.BodyDeviceBase">BodyDeviceBase</a></code></h4>
 <ul class="">
+<li><code><a title="sql_app.schemas.BodyDeviceBase.comment" href="#sql_app.schemas.BodyDeviceBase.comment">comment</a></code></li>
+<li><code><a title="sql_app.schemas.BodyDeviceBase.inventory_number" href="#sql_app.schemas.BodyDeviceBase.inventory_number">inventory_number</a></code></li>
 <li><code><a title="sql_app.schemas.BodyDeviceBase.serial_number" href="#sql_app.schemas.BodyDeviceBase.serial_number">serial_number</a></code></li>
 </ul>
 </li>
@@ -1605,10 +1929,15 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.BodyDeviceCreate" href="#sql_app.schemas.BodyDeviceCreate">BodyDeviceCreate</a></code></h4>
 </li>
 <li>
+<h4><code><a title="sql_app.schemas.BodyDeviceTemp" href="#sql_app.schemas.BodyDeviceTemp">BodyDeviceTemp</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.schemas.BodyDeviceTemp.serial_number" href="#sql_app.schemas.BodyDeviceTemp.serial_number">serial_number</a></code></li>
+</ul>
+</li>
+<li>
 <h4><code><a title="sql_app.schemas.Device" href="#sql_app.schemas.Device">Device</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.Device.Config" href="#sql_app.schemas.Device.Config">Config</a></code></li>
-<li><code><a title="sql_app.schemas.Device.assigned" href="#sql_app.schemas.Device.assigned">assigned</a></code></li>
 <li><code><a title="sql_app.schemas.Device.id" href="#sql_app.schemas.Device.id">id</a></code></li>
 <li><code><a title="sql_app.schemas.Device.licenses" href="#sql_app.schemas.Device.licenses">licenses</a></code></li>
 <li><code><a title="sql_app.schemas.Device.logs" href="#sql_app.schemas.Device.logs">logs</a></code></li>
@@ -1617,6 +1946,8 @@ class LDTemp(LDTempCreate):
 <li>
 <h4><code><a title="sql_app.schemas.DeviceBase" href="#sql_app.schemas.DeviceBase">DeviceBase</a></code></h4>
 <ul class="">
+<li><code><a title="sql_app.schemas.DeviceBase.comment" href="#sql_app.schemas.DeviceBase.comment">comment</a></code></li>
+<li><code><a title="sql_app.schemas.DeviceBase.inventory_number" href="#sql_app.schemas.DeviceBase.inventory_number">inventory_number</a></code></li>
 <li><code><a title="sql_app.schemas.DeviceBase.product_id" href="#sql_app.schemas.DeviceBase.product_id">product_id</a></code></li>
 <li><code><a title="sql_app.schemas.DeviceBase.serial_number" href="#sql_app.schemas.DeviceBase.serial_number">serial_number</a></code></li>
 <li><code><a title="sql_app.schemas.DeviceBase.vendor_id" href="#sql_app.schemas.DeviceBase.vendor_id">vendor_id</a></code></li>
@@ -1644,6 +1975,14 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.DeviceLicenseCreate" href="#sql_app.schemas.DeviceLicenseCreate">DeviceLicenseCreate</a></code></h4>
 </li>
 <li>
+<h4><code><a title="sql_app.schemas.DeviceTemp" href="#sql_app.schemas.DeviceTemp">DeviceTemp</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.schemas.DeviceTemp.product_id" href="#sql_app.schemas.DeviceTemp.product_id">product_id</a></code></li>
+<li><code><a title="sql_app.schemas.DeviceTemp.serial_number" href="#sql_app.schemas.DeviceTemp.serial_number">serial_number</a></code></li>
+<li><code><a title="sql_app.schemas.DeviceTemp.vendor_id" href="#sql_app.schemas.DeviceTemp.vendor_id">vendor_id</a></code></li>
+</ul>
+</li>
+<li>
 <h4><code><a title="sql_app.schemas.HeadDevice" href="#sql_app.schemas.HeadDevice">HeadDevice</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.HeadDevice.Config" href="#sql_app.schemas.HeadDevice.Config">Config</a></code></li>
@@ -1654,6 +1993,8 @@ class LDTemp(LDTempCreate):
 <li>
 <h4><code><a title="sql_app.schemas.HeadDeviceBase" href="#sql_app.schemas.HeadDeviceBase">HeadDeviceBase</a></code></h4>
 <ul class="">
+<li><code><a title="sql_app.schemas.HeadDeviceBase.comment" href="#sql_app.schemas.HeadDeviceBase.comment">comment</a></code></li>
+<li><code><a title="sql_app.schemas.HeadDeviceBase.inventory_number" href="#sql_app.schemas.HeadDeviceBase.inventory_number">inventory_number</a></code></li>
 <li><code><a title="sql_app.schemas.HeadDeviceBase.serial_number" href="#sql_app.schemas.HeadDeviceBase.serial_number">serial_number</a></code></li>
 </ul>
 </li>
@@ -1661,6 +2002,12 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.HeadDeviceCreate" href="#sql_app.schemas.HeadDeviceCreate">HeadDeviceCreate</a></code></h4>
 </li>
 <li>
+<h4><code><a title="sql_app.schemas.HeadDeviceTemp" href="#sql_app.schemas.HeadDeviceTemp">HeadDeviceTemp</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.schemas.HeadDeviceTemp.serial_number" href="#sql_app.schemas.HeadDeviceTemp.serial_number">serial_number</a></code></li>
+</ul>
+</li>
+<li>
 <h4><code><a title="sql_app.schemas.LDLog" href="#sql_app.schemas.LDLog">LDLog</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.LDLog.Config" href="#sql_app.schemas.LDLog.Config">Config</a></code></li>
@@ -1706,7 +2053,9 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.License" href="#sql_app.schemas.License">License</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.License.Config" href="#sql_app.schemas.License.Config">Config</a></code></li>
+<li><code><a title="sql_app.schemas.License.body_devices" href="#sql_app.schemas.License.body_devices">body_devices</a></code></li>
 <li><code><a title="sql_app.schemas.License.devices" href="#sql_app.schemas.License.devices">devices</a></code></li>
+<li><code><a title="sql_app.schemas.License.head_devices" href="#sql_app.schemas.License.head_devices">head_devices</a></code></li>
 <li><code><a title="sql_app.schemas.License.id" href="#sql_app.schemas.License.id">id</a></code></li>
 </ul>
 </li>
@@ -1714,6 +2063,7 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.LicenseBase" href="#sql_app.schemas.LicenseBase">LicenseBase</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.LicenseBase.expiration_date" href="#sql_app.schemas.LicenseBase.expiration_date">expiration_date</a></code></li>
+<li><code><a title="sql_app.schemas.LicenseBase.license_id" href="#sql_app.schemas.LicenseBase.license_id">license_id</a></code></li>
 <li><code><a title="sql_app.schemas.LicenseBase.name" href="#sql_app.schemas.LicenseBase.name">name</a></code></li>
 </ul>
 </li>
@@ -1724,8 +2074,8 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.PC" href="#sql_app.schemas.PC">PC</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.PC.Config" href="#sql_app.schemas.PC.Config">Config</a></code></li>
-<li><code><a title="sql_app.schemas.PC.assigned" href="#sql_app.schemas.PC.assigned">assigned</a></code></li>
 <li><code><a title="sql_app.schemas.PC.id" href="#sql_app.schemas.PC.id">id</a></code></li>
+<li><code><a title="sql_app.schemas.PC.logs_ld" href="#sql_app.schemas.PC.logs_ld">logs_ld</a></code></li>
 <li><code><a title="sql_app.schemas.PC.logs_pc" href="#sql_app.schemas.PC.logs_pc">logs_pc</a></code></li>
 </ul>
 </li>
@@ -1743,8 +2093,8 @@ class LDTemp(LDTempCreate):
 <h4><code><a title="sql_app.schemas.Team" href="#sql_app.schemas.Team">Team</a></code></h4>
 <ul class="">
 <li><code><a title="sql_app.schemas.Team.Config" href="#sql_app.schemas.Team.Config">Config</a></code></li>
+<li><code><a title="sql_app.schemas.Team.devices" href="#sql_app.schemas.Team.devices">devices</a></code></li>
 <li><code><a title="sql_app.schemas.Team.id" href="#sql_app.schemas.Team.id">id</a></code></li>
-<li><code><a title="sql_app.schemas.Team.pcs" href="#sql_app.schemas.Team.pcs">pcs</a></code></li>
 </ul>
 </li>
 <li>
@@ -1796,6 +2146,24 @@ class LDTemp(LDTempCreate):
 <li>
 <h4><code><a title="sql_app.schemas.USBTempCreate" href="#sql_app.schemas.USBTempCreate">USBTempCreate</a></code></h4>
 </li>
+<li>
+<h4><code><a title="sql_app.schemas.User" href="#sql_app.schemas.User">User</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.schemas.User.Config" href="#sql_app.schemas.User.Config">Config</a></code></li>
+<li><code><a title="sql_app.schemas.User.id" href="#sql_app.schemas.User.id">id</a></code></li>
+</ul>
+</li>
+<li>
+<h4><code><a title="sql_app.schemas.UserBase" href="#sql_app.schemas.UserBase">UserBase</a></code></h4>
+<ul class="">
+<li><code><a title="sql_app.schemas.UserBase.password" href="#sql_app.schemas.UserBase.password">password</a></code></li>
+<li><code><a title="sql_app.schemas.UserBase.role" href="#sql_app.schemas.UserBase.role">role</a></code></li>
+<li><code><a title="sql_app.schemas.UserBase.username" href="#sql_app.schemas.UserBase.username">username</a></code></li>
+</ul>
+</li>
+<li>
+<h4><code><a title="sql_app.schemas.UserCreate" href="#sql_app.schemas.UserCreate">UserCreate</a></code></h4>
+</li>
 </ul>
 </li>
 </ul>
diff --git a/server/sql_app/api/auth.py b/server/sql_app/api/auth.py
index a66baca..425d8ba 100644
--- a/server/sql_app/api/auth.py
+++ b/server/sql_app/api/auth.py
@@ -50,14 +50,23 @@ fake_users_db = {
 
 
 def verify_password(plain_password, hashed_password):
+    """
+    Verifies plain text password with hashed password
+    """
     return pwd_context.verify(plain_password, hashed_password)
 
 
 def get_hash_password(password):
+    """
+    Returns hashed password
+    """
     return pwd_context.hash(password)
 
 
 def auth_user(db, username: str, password: str):
+    """
+    Determines if given password belongs to user with given username
+    """
     user = crud.find_user(db, username)
     if not user:
         return None
diff --git a/server/sql_app/api/bodydevices_web.py b/server/sql_app/api/bodydevices_web.py
index 48b345e..b00c8d8 100644
--- a/server/sql_app/api/bodydevices_web.py
+++ b/server/sql_app/api/bodydevices_web.py
@@ -33,111 +33,139 @@ def get_db():
 async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
                        Authorize: AuthJWT = Depends()):
     """
-    Returns template with all body devices and its current states
+    Returns template with all body devices and necessary attributes
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
 
+    device_dict = []
     devices = crud.get_body_devices(db, skip=skip, limit=limit)
-    statuses = []
-    # adding state for each device in list
-    for i in range(0, len(devices)):
-        statuses.append(devices[i].b_logs[len(devices[i].b_logs) - 1].status)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
-        return templates.TemplateResponse("body_devices.html", {"request": request, "devs": len(devices), "devices": devices,
-                                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
     else:
         current_user = "guest"
-        return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devs": len(devices), "devices": devices,
-                                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
 
 
 @body_device_web.post("/body-devices-web", response_class=HTMLResponse)
-async def filter_devices(request: Request, skip: int = 0, limit: int = 100, lic: str = Form("all"),
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"),
                          db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
-    Endpoint used for filtering body devices by license. returns html template with only
-    body devices that has assigned license defined by user input
+    Endpoint used for filtering body devices by user given inputs. returns html template with only
+    body devices that has attributes defined by user input
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
-    devices = crud.get_body_devices(db, skip=skip, limit=limit)
-    def_devices = []
+    device_dict = []
+    devices_f = crud.get_filtered_bodydevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_bodydevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
     for dev in devices:
-        for l in dev.debug_licenses:
-            if dev not in def_devices and l.b_licenses.name == lic:
-                def_devices.append(dev)
-    # if input was default all
-    if lic == "all":
-        def_devices = devices
-    statuses = []
-    for i in range(0, len(def_devices)):
-        statuses.append(def_devices[i].b_logs[len(def_devices[i].b_logs) - 1].status)
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
-        return templates.TemplateResponse("body_devices.html",
-                                          {"request": request, "devs": len(def_devices), "devices": def_devices,
-                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
     else:
         current_user = "guest"
-        return templates.TemplateResponse("body_devices_normal.html",
-                                          {"request": request, "devs": len(def_devices), "devices": def_devices,
-                                           "statuses": statuses, "licenses": licenses, "user": current_user})
+        return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict,
+                                                                       "devs": devices, "teams": teams,
+                                                                       "licenses": licenses,
+                                                                       "user": current_user})
 
 
 @body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse)
 async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
                           Authorize: AuthJWT = Depends()):
     """
-    Returns template with one body device and all available licenses that can be assigned to it.
+    Returns template with one body device and all available licenses that can be assigned to it. Plus available teams
+    that can be assigned to device, inventory number and comment text input for this device.
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
     if current_user != "admin":
         return RedirectResponse(url=f"/logs-web", status_code=303)
     device = crud.get_body_device(db, device_id)
-    dev_licenses = crud.get_bodydevice_license(db, device_id)
-    lic_names = []
-    dev_lics = []
-    for dev_lic in dev_licenses:
-        dev_lics.append(dev_lic.b_licenses)
-    for dev_lic in dev_licenses:
-        lic_names.append(dev_lic.b_licenses.name)
     licenses = crud.get_licenses(db, 0, 100)
     lic_left = []
     for lic in licenses:
-        if lic.name not in lic_names and lic not in lic_left:
+        if lic != device.license:
             lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
     return templates.TemplateResponse("body_device_license.html",
-                                      {"request": request, "device": device, "licenses": lic_left, "dev_lic": dev_lics})
+                                      {"request": request, "device": device, "licenses": lic_left, "teams": teams})
 
 
-@body_device_web.post("/body-devices-web/{device_id}")
+@body_device_web.post("/body-devices-web-lic/{device_id}")
 async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
                        Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for connecting body device with license. Adds entry to bodydevices_licenses
-    table and redirects to body-devices-web endpoint
+    Endpoint called from template from body_device_license.html template. Connects body device with license
+    and redirects to body-devices-web endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
     if current_user != "admin":
         return RedirectResponse(url=f"/logs-web", status_code=303)
-    crud.create_body_device_license(db, device_id, int(lic), datetime.now())
+    crud.update_bodydevice_license(db, device_id, int(lic))
     return RedirectResponse(url=f"/body-devices-web", status_code=303)
 
 
-@body_device_web.post("/body-devices-web-del/{device_id}")
-async def delete_post(device_id: int, b_lic: str = Form(...), db: Session = Depends(get_db),
+@body_device_web.post("/body-devices-web-team/{device_id}")
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
                       Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for connecting body device with license. Adds entry to devices_licenses
-    table and redirects to body-devices-web endpoint
+    Endpoint called from template from body_device_license.html template, connects device with new team
+    and redirects to body-devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_bodydevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f"/body-devices-web", status_code=303)
+
+
+@body_device_web.post("/body-devices-inv/{device_id}")
+async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template from body_device_license.html template, updates devices inventory number
+    and redirects to body-devices-web endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
     if current_user != "admin":
         return RedirectResponse(url=f"/logs-web", status_code=303)
-    crud.delete_bodydevice_license(db, device_id, int(b_lic))
-    return RedirectResponse(url=f"/body-devices-web", status_code=303)
\ No newline at end of file
+    crud.update_bodydevice_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f"/body-devices-web", status_code=303)
+
+
+@body_device_web.post("/body-devices-comm/{device_id}")
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template from body_device_license.html template, updates devices comment
+    and redirects to body-devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_bodydevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f"/body-devices-web", status_code=303)
diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py
index 73fdf61..ff0f029 100644
--- a/server/sql_app/api/devices_web.py
+++ b/server/sql_app/api/devices_web.py
@@ -33,7 +33,7 @@ def get_db():
 async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
                        Authorize: AuthJWT = Depends()):
     """
-    Returns template with all devices and its current states
+    Returns template with all devices and its necessary attributes
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -65,7 +65,7 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
                          lic_id: str = Form("all"), team: str = Form("all"),
                          db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
-    Endpoint used for filtering devices by license. returns html template with only
+    Endpoint used for filtering devices by user given inputs. returns html template with only
     devices that has assigned license defined by user input
     """
     Authorize.jwt_optional()
@@ -99,7 +99,8 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
 async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
                           Authorize: AuthJWT = Depends()):
     """
-    Returns template with one device and all available licenses that can be assigned to it.
+    Returns template with one device and all available licenses that can be assigned to it. Plus all teams that can
+    be assigned to device, inventory number text input and comment text input
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -128,7 +129,7 @@ async def connect_dev_lic(request: Request, device_id: int, db: Session = Depend
 async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
                        Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for connecting device with license. Adds entry to devices_licenses
+    Endpoint called from devicelicense.html template. Adds entry to devices_licenses
     table and redirects to devices-web endpoint
     """
     Authorize.jwt_optional()
@@ -143,8 +144,8 @@ async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depen
 async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = Depends(get_db),
                       Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
-    table and redirects to devices-web endpoint
+    Endpoint called from devicelicense.html template for deleting device-license connection. Deletes entry in
+    bodydevices_licenses table and redirects to devices-web endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -153,12 +154,12 @@ async def delete_post(device_id: int, lic_del: str = Form(...), db: Session = De
     crud.delete_device_license(db, device_id, int(lic_del))
     return RedirectResponse(url=f"/devices-web", status_code=303)
 
+
 @device_web.post("/devices-web-team/{device_id}")
 async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
-                      Authorize: AuthJWT = Depends()):
+                       Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
-    table and redirects to devices-web endpoint
+    Endpoint called from devicelicense.html template, connects device with team and redirects to devices-web endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -167,12 +168,13 @@ async def dev_team_con(device_id: int, team_con: str = Form(...), db: Session =
     crud.update_device(db, device_id, team_con)
     return RedirectResponse(url=f"/devices-web", status_code=303)
 
+
 @device_web.post("/devices-web-inv/{device_id}")
 async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
                       Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
-    table and redirects to devices-web endpoint
+    Endpoint called from template devicelicense.html, updates inventory number of device and redirects to devices-web
+    endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
@@ -181,12 +183,13 @@ async def dev_inv_new(device_id: int, dev_inv: str = Form(...), db: Session = De
     crud.update_device_inv(db, device_id, dev_inv)
     return RedirectResponse(url=f"/devices-web", status_code=303)
 
+
 @device_web.post("/devices-web-comment/{device_id}")
 async def dev_comm_new(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
-                      Authorize: AuthJWT = Depends()):
+                       Authorize: AuthJWT = Depends()):
     """
-    Endpoint called from template for deleting device-license connection. Adds entry to bodydevices_licenses
-    table and redirects to devices-web endpoint
+    Endpoint called from template devicelicense.html, updates comment of device and redirects to devices-web
+    endpoint
     """
     Authorize.jwt_optional()
     current_user = Authorize.get_jwt_subject()
diff --git a/server/sql_app/api/headdevices_web.py b/server/sql_app/api/headdevices_web.py
new file mode 100644
index 0000000..2e6452b
--- /dev/null
+++ b/server/sql_app/api/headdevices_web.py
@@ -0,0 +1,169 @@
+from datetime import datetime
+
+from fastapi import Depends, APIRouter, Form
+from fastapi import Request
+from fastapi.responses import HTMLResponse, RedirectResponse
+from fastapi.templating import Jinja2Templates
+from fastapi_jwt_auth import AuthJWT
+from pydantic import BaseModel
+from sqlalchemy.orm import Session
+from sql_app.api.auth import fake_users_db
+from sql_app import crud, models
+from ..database import SessionLocal, engine
+
+models.Base.metadata.create_all(bind=engine)
+
+# Path to html templates used in this file
+templates = Jinja2Templates(directory="templates/head_devices")
+
+# prefix used for all endpoints in this file
+head_device_web = APIRouter(prefix="")
+
+
+# Dependency
+def get_db():
+    db = SessionLocal()
+    try:
+        yield db
+    finally:
+        db.close()
+
+
+@head_device_web.get("/head-devices-web", response_class=HTMLResponse)
+async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    """
+    Returns template with all head devices and necessary attributes
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+
+    device_dict = []
+    devices = crud.get_head_devices(db, skip=skip, limit=limit)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == "admin":
+        return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
+    else:
+        current_user = "guest"
+        return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
+
+
+@head_device_web.post("/head-devices-web", response_class=HTMLResponse)
+async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
+                         body_id: str = Form("all"), lic_id: str = Form("all"), team: str = Form("all"),
+                         db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+    """
+    Endpoint used for filtering head devices by user given inputs. returns html template with only
+    head devices that has attributes defined by user input
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    device_dict = []
+    devices_f = crud.get_filtered_headdevices(db, body_id, lic_id, team)
+    ids = []
+    for d in devices_f:
+        ids.append(d[0])
+    devices = crud.get_headdevices_with_ids(db, ids)
+    teams = crud.get_teams(db, skip=skip, limit=limit)
+    for dev in devices:
+        lic = crud.get_license(db, dev.license_id)
+        device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]})
+    licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if current_user == "admin":
+        return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict,
+                                                                "devs": devices, "teams": teams, "licenses": licenses,
+                                                                "user": current_user})
+    else:
+        current_user = "guest"
+        return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict,
+                                                                       "devs": devices, "teams": teams,
+                                                                       "licenses": licenses,
+                                                                       "user": current_user})
+
+
+@head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse)
+async def connect_dev_lic(request: Request, device_id: int, db: Session = Depends(get_db),
+                          Authorize: AuthJWT = Depends()):
+    """
+    Returns template with one head device and all available licenses that can be assigned to it, plus team and comment
+    and inventory number inputs.
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    device = crud.get_head_device(db, device_id)
+    licenses = crud.get_licenses(db, 0, 100)
+    lic_left = []
+    for lic in licenses:
+        if lic != device.license:
+            lic_left.append(lic)
+    teams = crud.get_teams(db, 0, 100)
+    return templates.TemplateResponse("headlicense.html",
+                                      {"request": request, "device": device, "licenses": lic_left, "teams": teams})
+
+
+@head_device_web.post("/head-devices-web-lic/{device_id}")
+async def connect_post(device_id: int, lic: str = Form(...), db: Session = Depends(get_db),
+                       Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template for connecting head device with license and redirects to head-devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_headdevice_license(db, device_id, int(lic))
+    return RedirectResponse(url=f"/head-devices-web", status_code=303)
+
+
+@head_device_web.post("/head-devices-web-team/{device_id}")
+async def delete_post(device_id: int, team_con: str = Form(...), db: Session = Depends(get_db),
+                      Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from template for connecting head device with team and redirects to body-devices-web endpoint
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_headdevice_team(db, device_id, int(team_con))
+    return RedirectResponse(url=f"/head-devices-web", status_code=303)
+
+
+@head_device_web.post("/head-devices-inv/{device_id}")
+async def device_inv(device_id: int, dev_inv: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from within from headlicense.html template. Changes head devices inventory number with new one
+    given from user
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_headdevice_inv(db, device_id, dev_inv)
+    return RedirectResponse(url=f"/head-devices-web", status_code=303)
+
+
+@head_device_web.post("/head-devices-comm/{device_id}")
+async def device_inv(device_id: int, dev_com: str = Form(...), db: Session = Depends(get_db),
+                     Authorize: AuthJWT = Depends()):
+    """
+    Endpoint called from within from headlicense.html template. Changes head devices comment with new one
+    given from user
+    """
+    Authorize.jwt_optional()
+    current_user = Authorize.get_jwt_subject()
+    if current_user != "admin":
+        return RedirectResponse(url=f"/logs-web", status_code=303)
+    crud.update_headdevice_comm(db, device_id, dev_com)
+    return RedirectResponse(url=f"/head-devices-web", status_code=303)
\ No newline at end of file
diff --git a/server/sql_app/crud.py b/server/sql_app/crud.py
index 6892343..2935853 100644
--- a/server/sql_app/crud.py
+++ b/server/sql_app/crud.py
@@ -32,18 +32,63 @@ def find_device_by_serial(db: Session, ser: str):
     """
     return db.query(models.Device).filter(and_(models.Device.serial_number == ser)).first()
 
+
 def get_devices_with_ids(db: Session, ids: []):
     """
     returns all devices with given ids
     """
     return db.query(models.Device).filter(models.Device.id.in_(ids)).all()
 
+
+def get_bodydevices_with_ids(db: Session, ids: []):
+    """
+    returns all bodydevices with given ids
+    """
+    return db.query(models.BodyDevice).filter(models.BodyDevice.id.in_(ids)).all()
+
+
+def get_headdevices_with_ids(db: Session, ids: []):
+    """
+    returns all headdevices with given ids
+    """
+    return db.query(models.HeadDevice).filter(models.HeadDevice.id.in_(ids)).all()
+
+
+def find_headdevices_by_team(db: Session, team_id: int):
+    """
+    Returns all head devices in specific team
+    """
+    return db.query(models.HeadDevice).filter(models.HeadDevice.team_id == team_id).all()
+
+
+def find_bodydevices_by_team(db: Session, team_id: int):
+    """
+    Returns all body devices in specific team
+    """
+    return db.query(models.BodyDevice).filter(models.BodyDevice.team_id == team_id).all()
+
+
+def find_headdevices_by_license(db: Session, lic_id: int):
+    """
+    Returns all head devices with specific license
+    """
+    return db.query(models.HeadDevice).filter(models.HeadDevice.license_id == lic_id).all()
+
+
+def find_bodydevices_by_license(db: Session, lic_id: int):
+    """
+    Returns all body devices with specific license
+    """
+    return db.query(models.BodyDevice).filter(models.BodyDevice.license_id == lic_id).all()
+
+
 def get_devices_by_team(db: Session, team: int):
     """
     returns all devices with same team
     """
     return db.query(models.Device).filter(models.Device.team_id == team).all()
 
+
 def create_device(db: Session, device: schemas.DeviceTemp):
     """
     creates new device with data from given DeviceBase object
@@ -121,28 +166,6 @@ def get_devicelicense_by_devicelicense(db: Session, device_id: int, license_id:
                                                       models.DeviceLicense.license_id == license_id)).first()
 
 
-def get_bodydevicelicense_by_bodydevicelicense(db: Session, device_id: int, license_id: int):
-    """
-    returns entry in bodydevices_licenses table with given body device id and license id
-    """
-    return db.query(models.BodyDeviceLicense).filter(and_(models.BodyDeviceLicense.bodydevice_id == device_id,
-                                                          models.BodyDeviceLicense.license_id == license_id)).first()
-
-
-def get_license_bodydevice(db: Session, license_id: int):
-    """
-    returns all entries in bodydevices_licenses with given license_id
-    """
-    return db.query(models.BodyDeviceLicense).filter(models.BodyDeviceLicense.license_id == license_id).all()
-
-
-def get_bodydevice_license(db: Session, device_id: int):
-    """
-    returns all entries in bodydevices_licenses with given license_id
-    """
-    return db.query(models.BodyDeviceLicense).filter(models.BodyDeviceLicense.bodydevice_id == device_id).all()
-
-
 def create_device_license(db: Session, device: int, license: int, time: datetime):
     """
     creates new entry in devices_licenses table with device id, license id and time.
@@ -165,28 +188,6 @@ def delete_device_license(db: Session, device: int, license: int):
     return db_lic
 
 
-def delete_bodydevice_license(db: Session, device: int, license: int):
-    """
-    deletes entry in devices_licenses table with device id, license id and time.
-    """
-    db_device_license = get_bodydevicelicense_by_bodydevicelicense(db, device, license)
-    db_lic = db.delete(db_device_license)
-    db.commit()
-    return db_lic
-
-
-def create_body_device_license(db: Session, device: int, license: int, time: datetime):
-    """
-    creates new entry in devices_licenses table with device id, license id and time.
-    """
-    db_device_license = models.BodyDeviceLicense(bodydevice_id=device, license_id=license,
-                                                 assigned_datetime=time)
-    db.add(db_device_license)
-    db.commit()
-    db.refresh(db_device_license)
-    return db_device_license
-
-
 def find_pc_by_username(db: Session, name: str):
     """
     Finds one pc by given username
@@ -415,17 +416,147 @@ def find_body_device(db: Session, serial: schemas.BodyDeviceTemp):
     return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial.serial_number).first()
 
 
+def find_bodydevice_by_serial(db: Session, serial: str):
+    """
+    Finds one specific body device by given serial number
+    """
+    return db.query(models.BodyDevice).filter(models.BodyDevice.serial_number == serial).first()
+
+
+def find_headdevice_by_serial(db: Session, serial: str):
+    """
+    Finds one specific head device by given serial number
+    """
+    return db.query(models.HeadDevice).filter(models.HeadDevice.serial_number == serial).first()
+
+
 def create_body_device(db: Session, log: schemas.BodyDeviceTemp):
     """
     Creates new Body device
     """
-    db_body = models.BodyDevice(serial_number=log.serial_number)
+    db_body = models.BodyDevice(serial_number=log.serial_number, inventory_number="", comment="")
     db.add(db_body)
     db.commit()
     db.refresh(db_body)
     return db_body
 
 
+def update_bodydevice_license(db: Session, device_id: int, lic_id: int):
+    """
+    Updates body devices license with one given by user
+    """
+    old_dev = get_body_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_team(db: Session, device_id: int, team_id: int):
+    """
+    Updates body devices team with one given by user
+    """
+    old_dev = get_body_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_inv(db: Session, device_id: int, dev_inv: str):
+    """
+    Updates body devices inventory number with new one given by user
+    """
+    old_dev = get_body_device(db, device_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv,
+           'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_bodydevice_comm(db: Session, device_id: int, comm: str):
+    """
+    Updates body devices comment with new one given by user
+    """
+    old_dev = get_body_device(db, device_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_license(db: Session, device_id: int, lic_id: int):
+    """
+    Updates head devices license with one given by user
+    """
+    old_dev = get_head_device(db, device_id)
+    lic = get_license(db, lic_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': lic.id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_team(db: Session, device_id: int, team_id: int):
+    """
+    Updates head devices team with one given by user
+    """
+    old_dev = get_head_device(db, device_id)
+    team = get_team(db, team_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': old_dev.comment, 'team_id': team.id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_inv(db: Session, device_id: int, dev_inv: str):
+    """
+    Updates head devices inventory number with new one given by user
+    """
+    old_dev = get_head_device(db, device_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': dev_inv,
+           'comment': old_dev.comment, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
+def update_headdevice_comm(db: Session, device_id: int, comm: str):
+    """
+    Updates head devices comment with new one given by user
+    """
+    old_dev = get_head_device(db, device_id)
+    new = {'id': old_dev.id, 'serial_number': old_dev.serial_number, 'inventory_number': old_dev.inventory_number,
+           'comment': comm, 'team_id': old_dev.team_id, 'license_id': old_dev.license_id}
+    for key, value in new.items():
+        setattr(old_dev, key, value)
+    db.commit()
+    db.refresh(old_dev)
+    return old_dev
+
+
 def get_ld_logs(db: Session, skip: int = 0, limit: int = 100):
     """
     Returns all ld debugger logs in database
@@ -477,41 +608,134 @@ def get_filtered_ldlogs(db: Session, pc: str, tema: str, lic: str):
     Function creates query string used for filtering by pc username, team name and license name.
     Depending on selected filters assembles query string for database
     """
-    execute_string = "SELECT * FROM ld_logs AS logs"
-    pcs = find_pc_by_username(db, pc)
+    execute_string = "SELECT * FROM ld_logs AS logs WHERE"
+    before_me = False
+    all_all = True
     if pc != "all":
-        if pcs is not None:
-            execute_string += "  WHERE logs.pc_id = " + str(pcs.id)
+        all_all = False
+        pc = find_pc_by_username(db, pc)
+        if pc != None:
+            if before_me:
+                execute_string += " AND logs.pc_id = " + str(pc.id)
+            else:
+                before_me = True
+                execute_string += " logs.pc_id = " + str(pc.id)
+        else:
+            if before_me:
+                execute_string += " AND logs.pc_id = -1"
+            else:
+                before_me = True
+                execute_string += " logs.pc_id = -1"
     if tema != "all":
+        all_all = False
         team = find_team(db, tema)
-        if team is not None:
-            devs = get_devices_by_team(db, team.id)
-            d_ids = "("
-            for p in devs:
-                d_ids += str(p.id) + ", "
-            def_d_ids = d_ids[:-2] + ")"
-            if pc != "all" and pcs is not None:
-                if len(def_d_ids) > 1:
-                    execute_string += " AND logs.device_id IN " + def_d_ids
+        if team != None:
+            head_devices = find_headdevices_by_team(db, team.id)
+            body_devices = find_bodydevices_by_team(db, team.id)
+            if len(head_devices) > 0 and len(body_devices) > 0:
+                h_ids = "("
+                for h in head_devices:
+                    h_ids += str(h.id) + ", "
+                def_h_ids = h_ids[:-2] + ")"
+                b_ids = "("
+                for b in body_devices:
+                    b_ids += str(b.id) + ", "
+                def_b_ids = b_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")"
+                else:
+                    before_me = True
+                    execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")"
+            elif len(head_devices) == 0 and len(body_devices) > 0:
+                b_ids = "("
+                for b in body_devices:
+                    b_ids += str(b.id) + ", "
+                def_b_ids = b_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND logs.body_id IN " + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += " logs.body_id IN " + def_b_ids
+            elif len(head_devices) > 0 and len(body_devices) == 0:
+                h_ids = "("
+                for h in head_devices:
+                    h_ids += str(h.id) + ", "
+                def_h_ids = h_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND logs.head_id IN " + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += " logs.head_id IN " + def_h_ids
             else:
-                if len(def_d_ids) > 1:
-                    execute_string += " WHERE logs.device_id IN " + def_d_ids
+                if before_me:
+                    execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)"
+                else:
+                    before_me = True
+                    execute_string += " (logs.head_id = -1 OR logs.body_id = -1)"
+        else:
+            if before_me:
+                execute_string += " AND logs.pc_id = -1"
+            else:
+                before_me = True
+                execute_string += " logs.pc_id = -1"
     if lic != "all":
-        license = get_licenses_by_name(db, lic)
-        if license is not None:
-            device_licenses = get_license_bodydevice(db, license.id)
-            dev_ids = "("
-            for dev in device_licenses:
-                dev_ids += str(dev.bodydevice_id) + ", "
-            defin_ids = dev_ids[:-2] + ")"
-            if pc != "all" or tema != "all":
-                if len(defin_ids) > 1:
-                    execute_string += " AND logs.body_id IN " + defin_ids
+        all_all = False
+        license = find_license(db, lic)
+        if license != None:
+            head_devices = find_headdevices_by_license(db, license.id)
+            body_devices = find_bodydevices_by_license(db, license.id)
+            if len(head_devices) > 0 and len(body_devices) > 0:
+                h_ids = "("
+                for h in head_devices:
+                    h_ids += str(h.id) + ", "
+                def_h_ids = h_ids[:-2] + ")"
+                b_ids = "("
+                for b in body_devices:
+                    b_ids += str(b.id) + ", "
+                def_b_ids = b_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")"
+                else:
+                    before_me = True
+                    execute_string += " (logs.head_id IN " + def_h_ids + " OR logs.body_id IN " + def_b_ids + ")"
+            elif len(head_devices) == 0 and len(body_devices) > 0:
+                b_ids = "("
+                for b in body_devices:
+                    b_ids += str(b.id) + ", "
+                def_b_ids = b_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND logs.body_id IN " + def_b_ids
+                else:
+                    before_me = True
+                    execute_string += " logs.body_id IN " + def_b_ids
+            elif len(head_devices) > 0 and len(body_devices) == 0:
+                h_ids = "("
+                for h in head_devices:
+                    h_ids += str(h.id) + ", "
+                def_h_ids = h_ids[:-2] + ")"
+                if before_me:
+                    execute_string += " AND logs.head_id IN " + def_h_ids
+                else:
+                    before_me = True
+                    execute_string += " logs.head_id IN " + def_h_ids
             else:
-                if len(defin_ids) > 1:
-                    execute_string += " WHERE logs.body_id IN " + defin_ids
+                if before_me:
+                    execute_string += " AND (logs.head_id = -1 OR logs.body_id = -1)"
+                else:
+                    before_me = True
+                    execute_string += " (logs.head_id = -1 OR logs.body_id = -1)"
+        else:
+            if before_me:
+                execute_string += " AND logs.pc_id = -1"
+            else:
+                before_me = True
+                execute_string += " logs.pc_id = -1"
+    if all_all:
+        before_me = True
+        execute_string = "SELECT * FROM ld_logs AS logs"
 
-    # executing assembled query string
+    if not before_me:
+        execute_string = "SELECT * FROM ld_logs AS logs WHERE logs.id = -1"
     result = db.execute(execute_string)
     return result
 
@@ -526,6 +750,8 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
     if pc != "all":
         if pcs is not None:
             execute_string += "  WHERE logs.pc_id = " + str(pcs.id)
+        else:
+            execute_string += "  WHERE logs.pc_id = -1"
     if tema != "all":
         team = find_team(db, tema)
         if team is not None:
@@ -534,16 +760,28 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
             for p in devs:
                 d_ids += str(p.id) + ", "
             def_d_ids = d_ids[:-2] + ")"
-            if pc != "all" and pcs is not None:
+            if pc != "all":
                 if len(def_d_ids) > 1:
                     execute_string += " AND logs.device_id IN " + def_d_ids
+                else:
+                    execute_string += " AND logs.device_id IN (-1)"
             else:
                 if len(def_d_ids) > 1:
                     execute_string += " WHERE logs.device_id IN " + def_d_ids
+                else:
+                    execute_string += " WHERE logs.device_id IN (-1)"
+        else:
+            if pc != "all":
+                execute_string += " AND logs.device_id IN (-1)"
+            else:
+                execute_string += " WHERE logs.device_id IN (-1)"
     if lic != "all":
         license = get_licenses_by_name(db, lic)
-        if license is not None:
-            device_licenses = get_license_devices(db, license.id)
+        if len(license) > 0:
+            ids = []
+            for l in license:
+                ids.append(l.id)
+            device_licenses = find_devicelicenses_by_licid_array(db, ids)
             dev_ids = "("
             for dev in device_licenses:
                 dev_ids += str(dev.device_id) + ", "
@@ -551,18 +789,151 @@ def get_filtered_logs(db: Session, pc: str, tema: str, lic: str):
             if pc != "all" or tema != "all":
                 if len(defin_ids) > 1:
                     execute_string += " AND logs.device_id IN " + defin_ids
+                else:
+                    execute_string += " AND logs.device_id IN (-1)"
             else:
                 if len(defin_ids) > 1:
                     execute_string += " WHERE logs.device_id IN " + defin_ids
+                else:
+                    execute_string += " WHERE logs.device_id IN (-1)"
+        else:
+            if pc != "all" or tema != "all":
+                execute_string += " AND logs.device_id IN (-1)"
+            else:
+                execute_string += " WHERE logs.device_id IN (-1)"
 
     # executing assembled query string
     result = db.execute(execute_string)
     return result
 
 
+def get_filtered_bodydevices(db: Session, body_id: str, license_id: str, team: str):
+    """
+    returns filtered body devices based on given attributes
+    """
+    execute_string = "SELECT * FROM body_devices AS device WHERE"
+    before_me = False
+    all_all = True
+    if body_id != "all":
+        all_all = False
+        body_dev = find_bodydevice_by_serial(db, body_id)
+        if body_dev != None:
+            if before_me:
+                execute_string += " AND device.id = " + str(body_dev.id)
+            else:
+                before_me = True
+                execute_string += " device.id = " + str(body_dev.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if license_id != "all":
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += " AND device.license_id = " + str(license.id)
+            else:
+                before_me = True
+                execute_string += " device.license_id = " + str(license.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if team != "all":
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += " AND device.team_id = " + str(tem.id)
+            else:
+                before_me = True
+                execute_string += " device.team_id = " + str(tem.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if all_all:
+        before_me = True
+        execute_string = "SELECT * FROM body_devices AS devices"
+
+    if not before_me:
+        execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1"
+    result = db.execute(execute_string)
+    return result
+
+
+def get_filtered_headdevices(db: Session, body_id: str, license_id: str, team: str):
+    """
+    returns filtered head devices based on given attributes
+    """
+    execute_string = "SELECT * FROM head_devices AS device WHERE"
+    before_me = False
+    all_all = True
+    if body_id != "all":
+        all_all = False
+        head_dev = find_headdevice_by_serial(db, body_id)
+        if head_dev != None:
+            if before_me:
+                execute_string += " AND device.id = " + str(head_dev.id)
+            else:
+                before_me = True
+                execute_string += " device.id = " + str(head_dev.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if license_id != "all":
+        all_all = False
+        license = find_license(db, license_id)
+        if license != None:
+            if before_me:
+                execute_string += " AND device.license_id = " + str(license.id)
+            else:
+                before_me = True
+                execute_string += " device.license_id = " + str(license.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if team != "all":
+        all_all = False
+        tem = find_team(db, team)
+        if tem != None:
+            if before_me:
+                execute_string += " AND device.team_id = " + str(tem.id)
+            else:
+                before_me = True
+                execute_string += " device.team_id = " + str(tem.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
+    if all_all:
+        before_me = True
+        execute_string = "SELECT * FROM body_devices AS devices"
+
+    if not before_me:
+        execute_string = "SELECT * FROM body_devices AS devices WHERE devices.id = -1"
+    result = db.execute(execute_string)
+    return result
+
+
 def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license_id: str, team: str):
     """
-    returns filtered devices based on given atributes
+    returns filtered keyman devices based on given attributes
     """
     execute_string = "SELECT * FROM devices AS device WHERE"
     before_me = False
@@ -576,6 +947,12 @@ def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license
             else:
                 before_me = True
                 execute_string += " device.id = " + str(keyman_dev.id)
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
     if license_name != "all":
         all_all = False
         license = get_licenses_by_name(db, license_name)
@@ -588,20 +965,30 @@ def get_filtered_devices(db: Session, keyman_id: str, license_name: str, license
             for l in dev_lics:
                 lic_ids += str(l.device_id) + ", "
             def_lic_ids = lic_ids[:-2] + ")"
+            if len(def_lic_ids) < 1:
+                def_lic_ids = "(-1)"
             if before_me:
                 execute_string += " AND device.id IN " + def_lic_ids
             else:
                 before_me = True
                 execute_string += " device.id IN " + def_lic_ids
+        else:
+            if before_me:
+                execute_string += " AND device.id = -1"
+            else:
+                before_me = True
+                execute_string += " device.id = -1"
     if license_id != "all":
         all_all = False
         license = find_license(db, license_id)
-        licen_devs = get_license_devices(db, license.id)
-        ids = "("
-        for lic in licen_devs:
-            ids += str(lic.device_id) + ", "
-        def_ids = ids[:-2] + ")"
         if license != None:
+            licen_devs = get_license_devices(db, license.id)
+            ids = "("
+            for lic in licen_devs:
+                ids += str(lic.device_id) + ", "
+            def_ids = ids[:-2] + ")"
+            if len(def_ids) < 1:
+                def_ids = "(-1)"
             if before_me:
                 execute_string += " AND device.id IN " + def_ids
             else:
diff --git a/server/sql_app/main.py b/server/sql_app/main.py
index 637bfaf..5c5bbb5 100644
--- a/server/sql_app/main.py
+++ b/server/sql_app/main.py
@@ -12,6 +12,7 @@ from sql_app.api.teams_web import teams_web
 from sql_app.api.auth import auth
 from sql_app.api.ld_logs_web import ldlogs_web
 from sql_app.api.bodydevices_web import body_device_web
+from sql_app.api.headdevices_web import head_device_web
 from sql_app.api.users_web import users
 from fastapi import FastAPI
 
@@ -34,9 +35,10 @@ app.include_router(usblogs_web)
 app.include_router(ldlogs_web)
 app.include_router(body_device_web)
 app.include_router(users)
+app.include_router(head_device_web)
 app.include_router(auth)
 
 '''
 if __name__ == "__main__":
-    uvicorn.run(app, host="192.168.64.1", port=8000)
+    uvicorn.run(app, host="192.168.0.22", port=8000)
 '''
diff --git a/server/sql_app/schemas.py b/server/sql_app/schemas.py
index eeab5a6..afb2bdc 100644
--- a/server/sql_app/schemas.py
+++ b/server/sql_app/schemas.py
@@ -69,6 +69,9 @@ class Device(DeviceCreate):
 
 
 class DeviceTemp(BaseModel):
+    """
+    Class used for reading data from client
+    """
     vendor_id: str
     product_id: str
     serial_number: str
@@ -117,6 +120,9 @@ class BodyDevice(BodyDeviceCreate):
 
 
 class BodyDeviceTemp(BaseModel):
+    """
+    Class used for reading body device data from client
+    """
     serial_number: str
 
 
@@ -142,6 +148,9 @@ class HeadDevice(HeadDeviceCreate):
 
 
 class HeadDeviceTemp(BaseModel):
+    """
+    Class used for reading head device data from client
+    """
     serial_number: str
 
 
diff --git a/server/templates/auth/login.html b/server/templates/auth/login.html
index fa536c5..cccf299 100644
--- a/server/templates/auth/login.html
+++ b/server/templates/auth/login.html
@@ -7,9 +7,9 @@
 <body>
 <form action="/login" method="post">
   <label for="username">Username:</label><br>
-  <input type="text" id="username" name="username"><br><br>
-    <label for="password">Password:</label>
-  <input type="password" id="password" name="password">
+  <input type="text" id="username" name="username"><br>
+    <label for="password">Password:</label><br>
+  <input type="password" id="password" name="password"><br>
   <input type="submit" value="LogIn">
 </form>
 </body>
diff --git a/server/templates/auth/signup.html b/server/templates/auth/signup.html
index b8b19ff..03334be 100644
--- a/server/templates/auth/signup.html
+++ b/server/templates/auth/signup.html
@@ -7,9 +7,9 @@
 <body>
 <form action="/signup" method="post">
   <label for="username">Username:</label><br>
-  <input type="text" id="username" name="username"><br><br>
-    <label for="password">Password:</label>
-  <input type="password" id="password" name="password">
+  <input type="text" id="username" name="username"><br>
+    <label for="password">Password:</label><br>
+  <input type="password" id="password" name="password"><br>
   <input type="submit" value="Signup">
 </form>
 </body>
diff --git a/server/templates/body-devices/body_device_license.html b/server/templates/body-devices/body_device_license.html
index d0c1896..f738966 100644
--- a/server/templates/body-devices/body_device_license.html
+++ b/server/templates/body-devices/body_device_license.html
@@ -5,26 +5,45 @@
     <title>Body Device License Connect</title>
 </head>
 <body>
-<h6><p>Vendor ID: {{device.vendor_id}}</p>
+<h6>
     <p>Serial Number: {{device.serial_number}}</p>
 </h6>
-<form action="/body-devices-web/{{device.id}}" method="post">
+<h4>
+    License ID: {{device.license.license_id}}
+</h4>
+<form action="/body-devices-web-lic/{{device.id}}" method="post">
   <label for="lic">Licenses:</label>
   <select id="lic" name="lic">
       {% for license in licenses %}
-    <option value={{license.id}}>{{license.name}}</option>
+    <option value={{license.id}}>{{license.license_id}}</option>
       {% endfor %}
   </select>
   <input type="submit" value="Connect">
 </form>
-<form action="/body-devices-web-del/{{device.id}}" method="post">
-  <label for="b_lic">Licenses:</label>
-  <select id="b_lic" name="b_lic" >
-      {% for license in dev_lic %}
-    <option value={{license.id}}>{{license.name}}</option>
+<div style='padding-top:20px'>
+<form action="/body-devices-web-team/{{device.id}}" method="post">
+  <label for="team_con">Teams:</label>
+  <select id="team_con" name="team_con" >
+      {% for team in teams %}
+    <option value={{team.id}}>{{team.name}}</option>
       {% endfor %}
   </select>
-  <input type="submit" value="Delete">
+  <input type="submit" value="Connect">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/body-devices-inv/{{device.id}}" method="post">
+  <label for="dev_inv">Inventory Number:</label><br>
+  <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}">
+  <input type="submit" value="Submit">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/body-devices-comm/{{device.id}}" method="post">
+  <label for="dev_com">Comment:</label><br>
+  <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}">
+  <input type="submit" value="Submit">
 </form>
+</div>
 </body>
 </html>
\ No newline at end of file
diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html
index a929689..3492e41 100644
--- a/server/templates/body-devices/body_devices.html
+++ b/server/templates/body-devices/body_devices.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web" selected>Lauterbach Devices</option>
+      <option value="/body-devices-web" selected>Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -58,11 +59,25 @@
   <input type="submit" value="OK">
 </form>
 <form action="/body-devices-web" method="post">
-    <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
-    <datalist id="licenses">
+    <label for="body_id">Body Device ID:</label>
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <datalist id="body_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <datalist id="licenses_ids">
         {% for license in licenses %}
-        <option value="{{license.name}}"></option>
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
         {% endfor %}
     </datalist>
   <input type="submit" value="Filter">
@@ -71,30 +86,29 @@
     <TR>
         <TH>ID</TH>
         <TH>Lauterbach Body ID</TH>
-        <TH>Licenses</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
         <TH>Status</TH>
+        <TH>Comment</TH>
     </TR>
-    {% for i in range(devs) %}
+    {% for dev in devices %}
     <TR>
-        <TD class="ID"><a href="/body-device-license/{{devices[i].id}}">{{devices[i].id}}</a></TD>
-        <TD class="Serial Number">{{devices[i].serial_number}}</TD>
-        <TD class="License">
-            {% for lic in devices[i].debug_licenses %}
-                {{lic.b_licenses.name}}<BR>
-            {% endfor %}
-        </TD>
-        <TD class="Status">{{statuses[i]}}</TD>
+        <TD class="ID"><a href="/body-device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD>
+        <TD class="Lauterbach Body ID">{{dev['device'].serial_number}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].ldpc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
     </TR>
     {% endfor %}
-    <TR>
-        <TD class="ID"></TD>
-        <TD class="Serial Number"></TD>
-        <TD class="License">
-            <form action="/license-create" method="get">
-                <input type="submit" value="Add">
-            </form>
-        </TD>
-    </TR>
 </table>
 </body>
 </html>
\ No newline at end of file
diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html
index db8159f..39ba939 100644
--- a/server/templates/body-devices/body_devices_normal.html
+++ b/server/templates/body-devices/body_devices_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web" selected>Lauterbach Devices</option>
+      <option value="/body-devices-web" selected>Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -57,11 +58,25 @@
   <input type="submit" value="OK">
 </form>
 <form action="/body-devices-web" method="post">
-    <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
-    <datalist id="licenses">
+    <label for="body_id">Body Device ID:</label>
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <datalist id="body_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <datalist id="licenses_ids">
         {% for license in licenses %}
-        <option value="{{license.name}}"></option>
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
         {% endfor %}
     </datalist>
   <input type="submit" value="Filter">
@@ -70,19 +85,27 @@
     <TR>
         <TH>ID</TH>
         <TH>Lauterbach Body ID</TH>
-        <TH>Licenses</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
         <TH>Status</TH>
+        <TH>Comment</TH>
     </TR>
-    {% for i in range(devs) %}
+    {% for dev in devices %}
     <TR>
-        <TD class="ID">{{devices[i].id}}</TD>
-        <TD class="Serial Number">{{devices[i].serial_number}}</TD>
-        <TD class="License">
-            {% for lic in devices[i].debug_licenses %}
-                {{lic.b_licenses.name}}<BR>
-            {% endfor %}
-        </TD>
-        <TD class="Status">{{statuses[i]}}</TD>
+        <TD class="ID">{{dev['device'].id}}</TD>
+        <TD class="Lauterbach Body ID">{{dev['device'].serial_number}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].ldpc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
     </TR>
     {% endfor %}
 </table>
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index b0e09e2..4d8c620 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web" selected>Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html
index abd3400..1c77480 100644
--- a/server/templates/devices/devices_normal.html
+++ b/server/templates/devices/devices_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web" selected>Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/head_devices/head_devices.html b/server/templates/head_devices/head_devices.html
new file mode 100644
index 0000000..42117e4
--- /dev/null
+++ b/server/templates/head_devices/head_devices.html
@@ -0,0 +1,114 @@
+<html>
+<head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
+    <title>Head Devices Details</title>
+</head>
+<body>
+<div style='float:left;padding-right:20px'>
+<b>Your role: {{user}}</b>
+</div>
+<div style='float:left;padding-right:5px'>
+<form action="/login" method="get">
+    <input type="submit" value="Login" />
+</form>
+</div>
+<div style='float:left;padding-right:5px'>
+<form action="/signup" method="get">
+    <input type="submit" value="Sign Up" />
+</form>
+</div>
+<form action="/logout" method="get">
+    <input type="submit" value="Logout" />
+</form>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web" selected>Lauterbach Head Devices</option>
+      <option value="/teams-web">Teams</option>
+      <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
+      <option value="/users-web">Users</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
+<form action="/head-devices-web" method="post">
+    <label for="body_id">Head Device ID:</label>
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <datalist id="body_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <datalist id="licenses_ids">
+        {% for license in licenses %}
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
+        {% endfor %}
+    </datalist>
+  <input type="submit" value="Filter">
+</form>
+<table id="devices">
+    <TR>
+        <TH>ID</TH>
+        <TH>Lauterbach Head ID</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
+        <TH>Status</TH>
+        <TH>Comment</TH>
+    </TR>
+    {% for dev in devices %}
+    <TR>
+        <TD class="ID"><a href="/head-device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD>
+        <TD class="Lauterbach Head ID">{{dev['device'].serial_number}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].ldpc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
+    </TR>
+    {% endfor %}
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/head_devices/head_devices_normal.html b/server/templates/head_devices/head_devices_normal.html
new file mode 100644
index 0000000..8df6d97
--- /dev/null
+++ b/server/templates/head_devices/head_devices_normal.html
@@ -0,0 +1,113 @@
+<html>
+<head>
+    <style>
+        #devices {
+  font-family: Arial, Helvetica, sans-serif;
+  border-collapse: collapse;
+  width: 100%;
+}
+
+#devices td, #devices th {
+  border: 1px solid #ddd;
+  padding: 8px;
+}
+
+#devices tr:nth-child(even){background-color: #f2f2f2;}
+
+#devices tr:hover {background-color: #ddd;}
+
+#devices th {
+  padding-top: 12px;
+  padding-bottom: 12px;
+  text-align: left;
+  background-color: #47BBF5;
+  color: black;
+}
+    </style>
+    <title>Devices Details</title>
+</head>
+<body>
+<div style='float:left;padding-right:20px'>
+<b>Your role: {{user}}</b>
+</div>
+<div style='float:left;padding-right:5px'>
+<form action="/login" method="get">
+    <input type="submit" value="Login" />
+</form>
+</div>
+<div style='float:left;padding-right:5px'>
+<form action="/signup" method="get">
+    <input type="submit" value="Sign Up" />
+</form>
+</div>
+<form action="/logout" method="get">
+    <input type="submit" value="Logout" />
+</form>
+<form action="" method="get">
+  <label for="view">Choose view:</label>
+  <select id="view" name="view" onchange="this.form.action=this.value;">
+      <option value="/logs-web">Vector Logs</option>
+      <option value="/ldlogs-web">Lauterbach Logs</option>
+      <option value="/devices-web">Keyman Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web" selected>Lauterbach Head Devices</option>
+      <option value="/teams-web">Teams</option>
+      <option value="/pcs-web">PCs</option>
+      <option value="/licenses-web">Licenses</option>
+  </select>
+  <input type="submit" value="OK">
+</form>
+<form action="/head-devices-web" method="post">
+    <label for="body_id">Head Device ID:</label>
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <datalist id="body_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <datalist id="licenses_ids">
+        {% for license in licenses %}
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
+        {% endfor %}
+    </datalist>
+  <input type="submit" value="Filter">
+</form>
+<table id="devices">
+    <TR>
+        <TH>ID</TH>
+        <TH>Lauterbach Head ID</TH>
+        <TH>License ID</TH>
+        <TH>Inventory Number</TH>
+        <TH>Team</TH>
+        <TH>Last Username</TH>
+        <TH>Last Hostname</TH>
+        <TH>Last Detection</TH>
+        <TH>Status</TH>
+        <TH>Comment</TH>
+    </TR>
+    {% for dev in devices %}
+    <TR>
+        <TD class="ID">{{dev['device'].id}}</TD>
+        <TD class="Lauterbach Head ID">{{dev['device'].serial_number}}</TD>
+        <TD class="License ID">{{dev['license'].license_id}}</TD>
+        <TD class="Inventory Number">{{dev['device'].inventory_number}}</TD>
+        <TD class="Team">{{dev['device'].team.name}}</TD>
+        <TD class="Last Username">{{dev['log'].ldpc.username}}</TD>
+        <TD class="Last Hostname">{{dev['log'].ldpc.hostname}}</TD>
+        <TD class="Last Detection">{{dev['log'].timestamp}}</TD>
+        <TD class="Status">{{dev['log'].status}}</TD>
+        <TD class="Comment">{{dev['device'].comment}}</TD>
+    </TR>
+    {% endfor %}
+</table>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/head_devices/headlicense.html b/server/templates/head_devices/headlicense.html
new file mode 100644
index 0000000..784e0bf
--- /dev/null
+++ b/server/templates/head_devices/headlicense.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>Head Device License Connect</title>
+</head>
+<body>
+<h6>
+    <p>Serial Number: {{device.serial_number}}</p>
+</h6>
+<h4>
+    License ID: {{device.license.license_id}}
+</h4>
+<form action="/head-devices-web-lic/{{device.id}}" method="post">
+  <label for="lic">Licenses:</label>
+  <select id="lic" name="lic">
+      {% for license in licenses %}
+    <option value={{license.id}}>{{license.license_id}}</option>
+      {% endfor %}
+  </select>
+  <input type="submit" value="Connect">
+</form>
+<div style='padding-top:20px'>
+<form action="/head-devices-web-team/{{device.id}}" method="post">
+  <label for="team_con">Teams:</label>
+  <select id="team_con" name="team_con" >
+      {% for team in teams %}
+    <option value={{team.id}}>{{team.name}}</option>
+      {% endfor %}
+  </select>
+  <input type="submit" value="Connect">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/head-devices-inv/{{device.id}}" method="post">
+  <label for="dev_inv">Inventory Number:</label><br>
+  <input type="text" id="dev_inv" name="dev_inv" value="{{device.inventory_number}}">
+  <input type="submit" value="Submit">
+</form>
+</div>
+<div style='padding-top:20px'>
+<form action="/head-devices-comm/{{device.id}}" method="post">
+  <label for="dev_com">Comment:</label><br>
+  <input type="text" id="dev_com" name="dev_com" value="{{device.comment}}">
+  <input type="submit" value="Submit">
+</form>
+</div>
+</body>
+</html>
\ No newline at end of file
diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html
index 7723f2a..e7f36cf 100644
--- a/server/templates/ld-logs/ldlogs.html
+++ b/server/templates/ld-logs/ldlogs.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web" selected>Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -76,7 +77,7 @@
     <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
     <datalist id="licenses">
         {% for license in licenses %}
-        <option value="{{license.name}}"></option>
+        <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
   <input type="submit" value="Filter">
@@ -86,7 +87,8 @@
         <TH>ID</TH>
         <TH>PC Username</TH>
         <TH>PC Hostname</TH>
-        <TH>Team</TH>
+        <TH>Head Team</TH>
+        <TH>Body Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
         <TH>Lauterbach Head ID</TH>
@@ -97,11 +99,8 @@
         <TD class="ID">{{log.id}}</TD>
         <TD class="Username">{{log.ldpc.username}}</TD>
         <TD class="Hostname">{{log.ldpc.hostname}}</TD>
-        {% if log.ldpc.team == None %}
-            <TD class="Team">NONE</TD>
-        {% else %}
-            <TD class="Team">{{log.ldpc.team.name}}</TD>
-        {% endif %}
+        <TD class="Head Team">{{log.head_device.team.name}}</TD>
+        <TD class="Body Team">{{log.body_device.team.name}}</TD>
         <TD class="Timestamp">{{log.timestamp}}</TD>
         <TD class="Status">{{log.status}}</TD>
         <TD class="HeadDeviceSerialNumber">{{log.head_device.serial_number}}</TD>
diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html
index 303b83f..bcdf40a 100644
--- a/server/templates/ld-logs/ldlogs_normal.html
+++ b/server/templates/ld-logs/ldlogs_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web" selected>Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -75,7 +76,7 @@
     <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
     <datalist id="licenses">
         {% for license in licenses %}
-        <option value="{{license.name}}"></option>
+        <option value="{{license.name}} : {{license.license_id}}"></option>
         {% endfor %}
     </datalist>
   <input type="submit" value="Filter">
@@ -85,7 +86,8 @@
         <TH>ID</TH>
         <TH>PC Username</TH>
         <TH>PC Hostname</TH>
-        <TH>Team</TH>
+        <TH>Head Team</TH>
+        <TH>Body Team</TH>
         <TH>Timestamp</TH>
         <TH>Status</TH>
         <TH>Lauterbach Head ID</TH>
@@ -96,17 +98,14 @@
         <TD class="ID">{{log.id}}</TD>
         <TD class="Username">{{log.ldpc.username}}</TD>
         <TD class="Hostname">{{log.ldpc.hostname}}</TD>
-        {% if log.ldpc.team == None %}
-            <TD class="Team">NONE</TD>
-        {% else %}
-            <TD class="Team">{{log.ldpc.team.name}}</TD>
-        {% endif %}
+        <TD class="Head Team">{{log.head_device.team.name}}</TD>
+        <TD class="Body Team">{{log.body_device.team.name}}</TD>
         <TD class="Timestamp">{{log.timestamp}}</TD>
         <TD class="Status">{{log.status}}</TD>
         <TD class="HeadDeviceSerialNumber">{{log.head_device.serial_number}}</TD>
         <TD class="BodyDeviceSerialNumber">{{log.body_device.serial_number}}</TD>
     </TR>
-    {% endfor %}
+        {% endfor %}
 </table>
 </body>
 </html>
\ No newline at end of file
diff --git a/server/templates/licenses/license_create.html b/server/templates/licenses/license_create.html
index 707ce4e..03b9d6a 100644
--- a/server/templates/licenses/license_create.html
+++ b/server/templates/licenses/license_create.html
@@ -6,12 +6,12 @@
 </head>
 <body>
 <form action="/licenses-web" method="post">
-  <label for="name">Name:</label><br>
-  <input type="text" id="name" name="name"><br><br>
-    <label for="lic_id">License ID:</label><br>
-  <input type="text" id="lic_id" name="lic_id"><br><br>
+  <label for="name">Name:</label>
+  <input type="text" id="name" name="name"><br>
+    <label for="lic_id">License ID:</label>
+  <input type="text" id="lic_id" name="lic_id"><br>
     <label for="expdate">Expiration Date</label>
-  <input type="date" id="expdate" name="expdate" min={{minimum_date}}>
+  <input type="date" id="expdate" name="expdate" min={{minimum_date}}><br>
   <input type="submit" value="Submit">
 </form>
 </body>
diff --git a/server/templates/pcs/pcs.html b/server/templates/pcs/pcs.html
index a723452..ec873ad 100644
--- a/server/templates/pcs/pcs.html
+++ b/server/templates/pcs/pcs.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/pcs/pcs_normal.html b/server/templates/pcs/pcs_normal.html
index 1ca892d..c5051aa 100644
--- a/server/templates/pcs/pcs_normal.html
+++ b/server/templates/pcs/pcs_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web" selected>PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/teams/team_change.html b/server/templates/teams/team_change.html
index 3ef6f23..247d43b 100644
--- a/server/templates/teams/team_change.html
+++ b/server/templates/teams/team_change.html
@@ -7,8 +7,8 @@
 <body>
 <h4>Team: {{team.name}}</h4>
 <form action="/teams-change-process/{{team.id}}" method="post">
-  <label for="name">Name:</label><br>
-  <input type="text" id="name" name="name"><br><br>
+  <label for="name">Name:</label>
+  <input type="text" id="name" name="name"><br>
   <input type="submit" value="Submit">
 </form>
 </body>
diff --git a/server/templates/teams/team_create.html b/server/templates/teams/team_create.html
index 28fb63d..85fc777 100644
--- a/server/templates/teams/team_create.html
+++ b/server/templates/teams/team_create.html
@@ -6,8 +6,8 @@
 </head>
 <body>
 <form action="/teams-web-con" method="post">
-  <label for="name">Name:</label><br>
-  <input type="text" id="name" name="name"><br><br>
+  <label for="name">Name:</label>
+  <input type="text" id="name" name="name"><br>
   <input type="submit" value="Submit">
 </form>
 </body>
diff --git a/server/templates/teams/teams.html b/server/templates/teams/teams.html
index 6957999..539f3da 100644
--- a/server/templates/teams/teams.html
+++ b/server/templates/teams/teams.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/teams/teams_normal.html b/server/templates/teams/teams_normal.html
index c928f52..2a2ac88 100644
--- a/server/templates/teams/teams_normal.html
+++ b/server/templates/teams/teams_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web" selected>Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/usb-logs/crossroad.html b/server/templates/usb-logs/crossroad.html
index 01db9b9..3f16cf0 100644
--- a/server/templates/usb-logs/crossroad.html
+++ b/server/templates/usb-logs/crossroad.html
@@ -12,7 +12,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
@@ -24,34 +25,50 @@
 <table>
     <TR>
         <TH>URL</TH>
+        <TH>Name</TH>
         <TH>Purpose</TH>
     </TR>
     <TR>
         <TD class="URL">/logs-web</TD>
-        <TD class="Purpose">Shows all saves Keyman logs. User can filter through license, team and user</TD>
+        <TD class="Name">Vector Logs</TD>
+        <TD class="Purpose">Shows all saved Keyman logs. User can filter through license, team and user</TD>
     </TR>
     <TR>
         <TD class="URL">/ldlogs-web</TD>
-        <TD class="Purpose">Shows all saves LD debugger logs. User can filter through license, team and user</TD>
+        <TD class="Name">Lauterbach Logs</TD>
+        <TD class="Purpose">Shows all saved LD debugger logs. User can filter through license, team and user</TD>
     </TR>
     <TR>
         <TD class="URL">/devices-web</TD>
-        <TD class="Purpose">Shows all Keyman devices saved in database and its last state (connected, disconnected)</TD>
+        <TD class="Name">Keyman Devices</TD>
+        <TD class="Purpose">Shows all Keyman devices saved in database and its license, inventory number, last pc and
+                            last detection. User can filter through keyman id, license type, license id and team</TD>
     </TR>
     <TR>
         <TD class="URL">/body-devices-web</TD>
-        <TD class="Purpose">Shows all LD Body devices saved in database and its last state (connected, disconnected)</TD>
+        <TD class="Name">Lauterbach Body Devices</TD>
+        <TD class="Purpose">Shows all Lauterbach Body devices saved in database and its license, inventory number, last pc and
+                            last detection. User can filter through body device serial nummber, license id and team</TD>
+    </TR>
+     <TR>
+        <TD class="URL">/head-devices-web</TD>
+        <TD class="Name">Lauterbach Head Devices</TD>
+        <TD class="Purpose">Shows all Lauterbach Head devices saved in database and its license, inventory number, last pc and
+                            last detection. User can filter through body device serial nummber, license id and team</TD>
     </TR>
     <TR>
         <TD class="URL">/teams-web</TD>
-        <TD class="Purpose">Shows all teams currently saved in database and its members</TD>
+        <TD class="Name">Teams</TD>
+        <TD class="Purpose">Shows all teams currently saved in database</TD>
     </TR>
     <TR>
         <TD class="URL">/pcs-web</TD>
-        <TD class="Purpose">Shows all PCS currently saved in database and its team</TD>
+        <TD class="Name">PCs</TD>
+        <TD class="Purpose">Shows all PCS currently saved in database</TD>
     </TR>
     <TR>
         <TD class="URL">/licenses-web</TD>
+        <TD class="Name">Licenses</TD>
         <TD class="Purpose">Shows all Licenses currently saved in database and its expiration date</TD>
     </TR>
 </table>
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index 34e14cd..fdecc00 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -49,7 +49,8 @@
       <option value="/logs-web" selected>Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html
index 99c3a9c..d954447 100644
--- a/server/templates/usb-logs/logs_normal.html
+++ b/server/templates/usb-logs/logs_normal.html
@@ -49,7 +49,8 @@
       <option value="/logs-web" selected>Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
diff --git a/server/templates/users/users.html b/server/templates/users/users.html
index 6b56b9a..bdbec4b 100644
--- a/server/templates/users/users.html
+++ b/server/templates/users/users.html
@@ -46,7 +46,8 @@
       <option value="/logs-web">Vector Logs</option>
       <option value="/ldlogs-web">Lauterbach Logs</option>
       <option value="/devices-web">Keyman Devices</option>
-      <option value="/body-devices-web">Lauterbach Devices</option>
+      <option value="/body-devices-web">Lauterbach Body Devices</option>
+      <option value="/head-devices-web">Lauterbach Head Devices</option>
       <option value="/teams-web">Teams</option>
       <option value="/pcs-web">PCs</option>
       <option value="/licenses-web">Licenses</option>
-- 
GitLab


From 709c735b187f6b414aed23b5760330c5e0336305 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mat=C4=9Bj=20Zeman?= <zemanm98@students.zcu.cz>
Date: Sun, 15 May 2022 13:56:30 +0000
Subject: [PATCH 65/67] README, changed main page url

---
 server/README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/README.md b/server/README.md
index c75cf40..7b87216 100644
--- a/server/README.md
+++ b/server/README.md
@@ -30,7 +30,7 @@ And docker will create image for server application and postgresql database. Dat
 Data from database are easily accesibly from web browser. Main web views url is
 
 ```bash
-http://localhost:8000/api/v1/logs-web
+http://localhost:8000/
 ```
 
 On this page there is select box at the top of the page for accessing different views on other data in database as well as creating new ones
-- 
GitLab


From a7d16717c1525c98c69e7d2ece752095857bc715 Mon Sep 17 00:00:00 2001
From: Pultak <pultak5@gmail.com>
Date: Mon, 16 May 2022 13:36:35 +0200
Subject: [PATCH 66/67] re #9845 tests fix after refactoring

---
 ld_client/LDClient/detection/AInfoFetcher.cs          | 2 +-
 ld_client/LDClient/network/ApiClient.cs               | 1 +
 ld_client/LDClientTests/detection/InfoFetcherTests.cs | 8 ++++----
 3 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/ld_client/LDClient/detection/AInfoFetcher.cs b/ld_client/LDClient/detection/AInfoFetcher.cs
index bdacb4a..2b61efa 100644
--- a/ld_client/LDClient/detection/AInfoFetcher.cs
+++ b/ld_client/LDClient/detection/AInfoFetcher.cs
@@ -115,7 +115,7 @@ public abstract class AInfoFetcher : IInfoFetcher {
             BodySerialNumber = bodySerialNumber;
 
             // Finally, delete the file.
-            //File.Delete(filePath);
+            File.Delete(filePath);
         } catch (Exception exception) {
             Program.DefaultLogger.Error($"Failed to retrieve debugger info. File {filePath} may not exist or it does not have the right format. {exception.Message}");
             return false;
diff --git a/ld_client/LDClient/network/ApiClient.cs b/ld_client/LDClient/network/ApiClient.cs
index 8668e54..792505a 100644
--- a/ld_client/LDClient/network/ApiClient.cs
+++ b/ld_client/LDClient/network/ApiClient.cs
@@ -70,6 +70,7 @@ namespace LDClient.network {
         /// </summary>
         /// <param name="payload">instance of a payload to be sent off to the server</param>
         public async Task SendPayloadAsync(Payload payload) {
+            Program.DefaultLogger.Debug("SendPayloadAsync called.");
             try {
                 // Create an instance of Stopwatch (to measure how much
                 // the action took).
diff --git a/ld_client/LDClientTests/detection/InfoFetcherTests.cs b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
index 3285226..35020fa 100644
--- a/ld_client/LDClientTests/detection/InfoFetcherTests.cs
+++ b/ld_client/LDClientTests/detection/InfoFetcherTests.cs
@@ -8,8 +8,8 @@ using NUnit.Framework;
 namespace LDClientTests.detection; 
 
 internal class InfoFetcherTests {
-    private InfoFetcher _defaultFetcher;
-    private InfoFetcher _fetcherWithoutPars;
+    private AInfoFetcher _defaultFetcher;
+    private AInfoFetcher _fetcherWithoutPars;
         
 
     private readonly string[] _defaultArguments = new[] { "argument 1", "argument 2" , "argument 3"};
@@ -25,14 +25,14 @@ internal class InfoFetcherTests {
         _mockFileUtils = new Mock<IFileUtils>(MockBehavior.Strict);
     
 
-        _defaultFetcher = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
+        _defaultFetcher = new T32RemFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
             _defaultArguments, 0, 50) {
             FileUtils = _mockFileUtils.Object,
             ProcessUtils = _mockProcessUtils.Object
         };
 
 
-        _fetcherWithoutPars = new InfoFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
+        _fetcherWithoutPars = new T32RemFetcher(DefaultMaxAttempts, 50, "info.txt", "executable.exe",
             null, 0, 50) {
             FileUtils = _mockFileUtils.Object,
             ProcessUtils = _mockProcessUtils.Object
-- 
GitLab


From 93d0ec10d1deeb8c7388559f49aa07ad536d5c52 Mon Sep 17 00:00:00 2001
From: Matej Zeman <zeman339@gmail.com>
Date: Mon, 16 May 2022 17:08:02 +0200
Subject: [PATCH 67/67] re #9846 Filter text fields keeps their searched
 content.

---
 server/sql_app/api/bodydevices_web.py         | 18 +++++++++---
 server/sql_app/api/devices_web.py             | 22 +++++++++++---
 server/sql_app/api/headdevices_web.py         | 18 +++++++++---
 server/sql_app/api/ld_logs_web.py             | 18 +++++++++---
 server/sql_app/api/usb_logs_web.py            | 21 ++++++++++----
 server/sql_app/api/users_web.py               |  2 +-
 .../templates/body-devices/body_devices.html  |  6 ++--
 .../body-devices/body_devices_normal.html     |  6 ++--
 server/templates/devices/devices.html         |  8 ++---
 server/templates/devices/devices_normal.html  | 29 ++++++++++++++++---
 .../templates/head_devices/head_devices.html  |  6 ++--
 .../head_devices/head_devices_normal.html     |  6 ++--
 server/templates/ld-logs/ldlogs.html          |  6 ++--
 server/templates/ld-logs/ldlogs_normal.html   |  6 ++--
 server/templates/usb-logs/logs.html           |  6 ++--
 server/templates/usb-logs/logs_normal.html    |  6 ++--
 server/templates/users/users.html             |  3 ++
 17 files changed, 132 insertions(+), 55 deletions(-)

diff --git a/server/sql_app/api/bodydevices_web.py b/server/sql_app/api/bodydevices_web.py
index b00c8d8..26ae5f9 100644
--- a/server/sql_app/api/bodydevices_web.py
+++ b/server/sql_app/api/bodydevices_web.py
@@ -48,12 +48,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
     if current_user == "admin":
         return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": "", "lic_val": "",
+                                                                "team_val": ""})
     else:
         current_user = "guest"
         return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": "", "lic_val": "",
+                                                                "team_val": ""})
 
 
 @body_device_web.post("/body-devices-web", response_class=HTMLResponse)
@@ -77,16 +79,24 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
         lic = crud.get_license(db, dev.license_id)
         device_dict.append({"device": dev, "license": lic, "log": dev.b_logs[len(dev.b_logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if body_id == "all":
+        body_id = ""
+    if lic_id == "all":
+        lic_id = ""
+    if team == "all":
+        team = ""
     if current_user == "admin":
         return templates.TemplateResponse("body_devices.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": body_id, "lic_val": lic_id,
+                                                                "team_val": team})
     else:
         current_user = "guest"
         return templates.TemplateResponse("body_devices_normal.html", {"request": request, "devices": device_dict,
                                                                        "devs": devices, "teams": teams,
                                                                        "licenses": licenses,
-                                                                       "user": current_user})
+                                                                       "user": current_user, "body_val": body_id, "lic_val": lic_id,
+                                                                       "team_val": team})
 
 
 @body_device_web.get("/body-device-license/{device_id}", response_class=HTMLResponse)
diff --git a/server/sql_app/api/devices_web.py b/server/sql_app/api/devices_web.py
index ff0f029..82f9458 100644
--- a/server/sql_app/api/devices_web.py
+++ b/server/sql_app/api/devices_web.py
@@ -51,12 +51,15 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
         return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict,
-                                                           "licenses": licenses, "devs": devices,
+                                                           "licenses": licenses, "devs": devices, "keyman_val": "",
+                                                           "licn_val": "", "lici_val": "", "team_val": "",
                                                            "teams": teams, "user": current_user})
     else:
         current_user = "guest"
         return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict,
-                                                                  "licenses": licenses, "user": current_user})
+                                                                  "licenses": licenses, "devs": devices, "keyman_val": "",
+                                                                  "licn_val": "", "lici_val": "", "team_val": "",
+                                                                  "teams": teams, "user": current_user})
 
 
 @device_web.post("/devices-web", response_class=HTMLResponse)
@@ -85,14 +88,25 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
         else:
             device_dict.append({"device": dev, "license": dev.licenses, "log": dev.logs[len(dev.logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if keyman_id == "all":
+        keyman_id = ""
+    if lic_name == "all":
+        lic_name = ""
+    if lic_id == "all":
+        lic_id = ""
+    if team == "all":
+        team = ""
     if current_user == "admin":
         return templates.TemplateResponse("devices.html", {"request": request, "devices": device_dict,
-                                                           "licenses": licenses, "devs": devices,
+                                                           "licenses": licenses, "devs": devices, "keyman_val": keyman_id,
+                                                           "licn_val": lic_name, "lici_val": lic_id, "team_val": team,
                                                            "teams": teams, "user": current_user})
     else:
         current_user = "guest"
         return templates.TemplateResponse("devices_normal.html", {"request": request, "devices": device_dict,
-                                                                  "licenses": licenses, "user": current_user})
+                                                                  "licenses": licenses, "devs": devices, "keyman_val": keyman_id,
+                                                                  "licn_val": lic_name, "lici_val": lic_id, "team_val": team,
+                                                                  "teams": teams, "user": current_user})
 
 
 @device_web.get("/device-license/{device_id}", response_class=HTMLResponse)
diff --git a/server/sql_app/api/headdevices_web.py b/server/sql_app/api/headdevices_web.py
index 2e6452b..974d128 100644
--- a/server/sql_app/api/headdevices_web.py
+++ b/server/sql_app/api/headdevices_web.py
@@ -48,12 +48,14 @@ async def read_devices(request: Request, skip: int = 0, limit: int = 100, db: Se
     if current_user == "admin":
         return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": "", "lic_val": "",
+                                                                "team_val": ""})
     else:
         current_user = "guest"
         return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": "", "lic_val": "",
+                                                                "team_val": ""})
 
 
 @head_device_web.post("/head-devices-web", response_class=HTMLResponse)
@@ -77,16 +79,24 @@ async def filter_devices(request: Request, skip: int = 0, limit: int = 100,
         lic = crud.get_license(db, dev.license_id)
         device_dict.append({"device": dev, "license": lic, "log": dev.h_logs[len(dev.h_logs) - 1]})
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if body_id == "all":
+        body_id = ""
+    if lic_id == "all":
+        lic_id = ""
+    if team == "all":
+        team = ""
     if current_user == "admin":
         return templates.TemplateResponse("head_devices.html", {"request": request, "devices": device_dict,
                                                                 "devs": devices, "teams": teams, "licenses": licenses,
-                                                                "user": current_user})
+                                                                "user": current_user, "body_val": body_id, "lic_val": lic_id,
+                                                                "team_val": team})
     else:
         current_user = "guest"
         return templates.TemplateResponse("head_devices_normal.html", {"request": request, "devices": device_dict,
                                                                        "devs": devices, "teams": teams,
                                                                        "licenses": licenses,
-                                                                       "user": current_user})
+                                                                       "user": current_user, "body_val": body_id, "lic_val": lic_id,
+                                                                       "team_val": team})
 
 
 @head_device_web.get("/head-device-license/{device_id}", response_class=HTMLResponse)
diff --git a/server/sql_app/api/ld_logs_web.py b/server/sql_app/api/ld_logs_web.py
index aef3733..c2059fb 100644
--- a/server/sql_app/api/ld_logs_web.py
+++ b/server/sql_app/api/ld_logs_web.py
@@ -46,12 +46,14 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
         return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                          "licenses": licenses, "user": current_user})
+                                                          "licenses": licenses, "user": current_user, "pc_val": "",
+                                                          "team_val": "", "lic_val": ""})
     else:
         current_user = "guest"
         return templates.TemplateResponse("ldlogs_normal.html",
                                           {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                           "licenses": licenses, "user": current_user})
+                                           "licenses": licenses, "user": current_user, "pc_val": "",
+                                                          "team_val": "", "lic_val": ""})
 
 
 @ldlogs_web.post("/ldlogs-web", response_class=HTMLResponse)
@@ -71,11 +73,19 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form(
     pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if team == "all":
+        team = ""
+    if pc == "all":
+        pc = ""
+    if lic == "all":
+        lic = ""
     if current_user == "admin":
         return templates.TemplateResponse("ldlogs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                          "licenses": licenses, "user": current_user})
+                                                          "licenses": licenses, "user": current_user, "pc_val": pc,
+                                                          "team_val": team, "lic_val": lic})
     else:
         current_user = "guest"
         return templates.TemplateResponse("ldlogs_normal.html",
                                           {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                           "licenses": licenses, "user": current_user})
+                                           "licenses": licenses, "user": current_user, "pc_val": pc,
+                                                          "team_val": team, "lic_val": lic})
diff --git a/server/sql_app/api/usb_logs_web.py b/server/sql_app/api/usb_logs_web.py
index 75ebdc6..13729ef 100644
--- a/server/sql_app/api/usb_logs_web.py
+++ b/server/sql_app/api/usb_logs_web.py
@@ -46,17 +46,18 @@ async def read_logs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
     if current_user == "admin":
         return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                        "licenses": licenses, "user": current_user})
+                                                        "licenses": licenses, "user": current_user, "pc_val": "",
+                                                        "team_val": "", "lic_val": ""})
     else:
         current_user = "guest"
         return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                        "licenses": licenses, "user": current_user})
+                                                        "licenses": licenses, "user": current_user, "pc_val": "",
+                                                        "team_val": "", "lic_val": ""})
 
 
 @usblogs_web.post("/logs-web", response_class=HTMLResponse)
 async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form("all"), lic: str = Form("all"),
-                      skip: int = 0, limit: int = 100,
-                      db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
+                      skip: int = 0, limit: int = 100, db: Session = Depends(get_db), Authorize: AuthJWT = Depends()):
     """
     Endpoint used for filtering usb logs by user given form inputs.
     """
@@ -70,13 +71,21 @@ async def filter_logs(request: Request, pc: str = Form("all"), team: str = Form(
     pc_obj = crud.get_pcs(db, skip=skip, limit=limit)
     teams = crud.get_teams(db, skip=skip, limit=limit)
     licenses = crud.get_licenses(db, skip=skip, limit=limit)
+    if team == "all":
+        team = ""
+    if pc == "all":
+        pc = ""
+    if lic == "all":
+        lic = ""
     if current_user == "admin":
         return templates.TemplateResponse("logs.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                        "licenses": licenses, "user": current_user})
+                                                        "licenses": licenses, "user": current_user, "pc_val": pc,
+                                                        "team_val": team, "lic_val": lic})
     else:
         current_user = "guest"
         return templates.TemplateResponse("logs_normal.html", {"request": request, "logs": logs, "pcs": pc_obj, "teams": teams,
-                                                        "licenses": licenses, "user": current_user})
+                                                        "licenses": licenses, "user": current_user, "pc_val": pc,
+                                                        "team_val": team, "lic_val": lic})
 
 
 @usblogs_web.get("/", response_class=HTMLResponse)
diff --git a/server/sql_app/api/users_web.py b/server/sql_app/api/users_web.py
index 523b22f..41a49d0 100644
--- a/server/sql_app/api/users_web.py
+++ b/server/sql_app/api/users_web.py
@@ -37,7 +37,7 @@ async def read_usrs(request: Request, skip: int = 0, limit: int = 100, db: Sessi
     current_user = Authorize.get_jwt_subject()
     users = crud.get_users(db, skip, limit)
     if current_user == "admin":
-        return templates.TemplateResponse("users.html", {"request": request, "users": users})
+        return templates.TemplateResponse("users.html", {"request": request, "users": users, "user": current_user})
     else:
         return RedirectResponse(url=f"/logs-web", status_code=303)
 
diff --git a/server/templates/body-devices/body_devices.html b/server/templates/body-devices/body_devices.html
index 3492e41..8eff2b3 100644
--- a/server/templates/body-devices/body_devices.html
+++ b/server/templates/body-devices/body_devices.html
@@ -60,21 +60,21 @@
 </form>
 <form action="/body-devices-web" method="post">
     <label for="body_id">Body Device ID:</label>
-    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();">
     <datalist id="body_ids">
         {% for dev in devs %}
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_id">License ID:</label>
-    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_ids">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}">{{team.name}}</option>
diff --git a/server/templates/body-devices/body_devices_normal.html b/server/templates/body-devices/body_devices_normal.html
index 39ba939..f312309 100644
--- a/server/templates/body-devices/body_devices_normal.html
+++ b/server/templates/body-devices/body_devices_normal.html
@@ -59,21 +59,21 @@
 </form>
 <form action="/body-devices-web" method="post">
     <label for="body_id">Body Device ID:</label>
-    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();">
     <datalist id="body_ids">
         {% for dev in devs %}
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_id">License ID:</label>
-    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_ids">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}">{{team.name}}</option>
diff --git a/server/templates/devices/devices.html b/server/templates/devices/devices.html
index 4d8c620..92620fe 100644
--- a/server/templates/devices/devices.html
+++ b/server/templates/devices/devices.html
@@ -60,28 +60,28 @@
 </form>
 <form action="/devices-web" method="post">
     <label for="keyman_id">Keyman ID:</label>
-    <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="" placeholder="all">
+    <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="{{keyman_val}}" placeholder="all" onClick="this.select();">
     <datalist id="keyman_ids">
         {% for dev in devs %}
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_name">License Type:</label>
-    <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="" placeholder="all">
+    <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="{{licn_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_names">
         {% for license in licenses %}
         <option value="{{license.name}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_id">License ID:</label>
-    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lici_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_ids">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}">{{team.name}}</option>
diff --git a/server/templates/devices/devices_normal.html b/server/templates/devices/devices_normal.html
index 1c77480..71f5fb9 100644
--- a/server/templates/devices/devices_normal.html
+++ b/server/templates/devices/devices_normal.html
@@ -58,13 +58,34 @@
   <input type="submit" value="OK">
 </form>
 <form action="/devices-web" method="post">
-    <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
-    <datalist id="licenses">
+    <label for="keyman_id">Keyman ID:</label>
+    <input id="keyman_id" name="keyman_id" type="text" list="keyman_ids" value="{{keyman_val}}" placeholder="all" onClick="this.select();">
+    <datalist id="keyman_ids">
+        {% for dev in devs %}
+        <option value="{{dev.serial_number}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="lic_name">License Type:</label>
+    <input id="lic_name" name="lic_name" type="text" list="licenses_names" value="{{licn_val}}" placeholder="all" onClick="this.select();">
+    <datalist id="licenses_names">
         {% for license in licenses %}
         <option value="{{license.name}}"></option>
         {% endfor %}
     </datalist>
+    <label for="lic_id">License ID:</label>
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lici_val}}" placeholder="all" onClick="this.select();">
+    <datalist id="licenses_ids">
+        {% for license in licenses %}
+        <option value="{{license.license_id}}"></option>
+        {% endfor %}
+    </datalist>
+    <label for="team">Team:</label>
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
+    <datalist id="teams">
+        {% for team in teams %}
+        <option value="{{team.name}}">{{team.name}}</option>
+        {% endfor %}
+    </datalist>
   <input type="submit" value="Filter">
 </form>
 <table id="devices">
@@ -83,7 +104,7 @@
     </TR>
     {% for dev in devices %}
     <TR>
-        <TD class="ID">{{dev['device'].id}}</TD>
+        <TD class="ID"><a href="/device-license/{{dev['device'].id}}">{{dev['device'].id}}</a></TD>
         <TD class="Serial Number">{{dev['device'].serial_number}}</TD>
         <TD class="License">{{dev['license'].name}}</TD>
         <TD class="License ID">{{dev['license'].license_id}}</TD>
diff --git a/server/templates/head_devices/head_devices.html b/server/templates/head_devices/head_devices.html
index 42117e4..6c86bda 100644
--- a/server/templates/head_devices/head_devices.html
+++ b/server/templates/head_devices/head_devices.html
@@ -60,21 +60,21 @@
 </form>
 <form action="/head-devices-web" method="post">
     <label for="body_id">Head Device ID:</label>
-    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();">
     <datalist id="body_ids">
         {% for dev in devs %}
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_id">License ID:</label>
-    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_ids">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}">{{team.name}}</option>
diff --git a/server/templates/head_devices/head_devices_normal.html b/server/templates/head_devices/head_devices_normal.html
index 8df6d97..baf26a0 100644
--- a/server/templates/head_devices/head_devices_normal.html
+++ b/server/templates/head_devices/head_devices_normal.html
@@ -59,21 +59,21 @@
 </form>
 <form action="/head-devices-web" method="post">
     <label for="body_id">Head Device ID:</label>
-    <input id="body_id" name="body_id" type="text" list="body_ids" value="" placeholder="all">
+    <input id="body_id" name="body_id" type="text" list="body_ids" value="{{body_val}}" placeholder="all" onClick="this.select();">
     <datalist id="body_ids">
         {% for dev in devs %}
         <option value="{{dev.serial_number}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic_id">License ID:</label>
-    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="" placeholder="all">
+    <input id="lic_id" name="lic_id" type="text" list="licenses_ids" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses_ids">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-    <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+    <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}">{{team.name}}</option>
diff --git a/server/templates/ld-logs/ldlogs.html b/server/templates/ld-logs/ldlogs.html
index e7f36cf..cb48627 100644
--- a/server/templates/ld-logs/ldlogs.html
+++ b/server/templates/ld-logs/ldlogs.html
@@ -60,21 +60,21 @@
 </form>
 <form action="/ldlogs-web" method="post">
   <label for="pc">PC:</label>
-  <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all">
+  <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();">
     <datalist id="pcs">
         {% for pc in pcs %}
         <option value="{{pc.username}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-  <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+  <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses">
         {% for license in licenses %}
         <option value="{{license.license_id}}"></option>
diff --git a/server/templates/ld-logs/ldlogs_normal.html b/server/templates/ld-logs/ldlogs_normal.html
index bcdf40a..c87571f 100644
--- a/server/templates/ld-logs/ldlogs_normal.html
+++ b/server/templates/ld-logs/ldlogs_normal.html
@@ -59,21 +59,21 @@
 </form>
 <form action="/ldlogs-web" method="post">
   <label for="pc">PC:</label>
-  <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all">
+  <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();">
     <datalist id="pcs">
         {% for pc in pcs %}
         <option value="{{pc.username}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-  <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+  <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses">
         {% for license in licenses %}
         <option value="{{license.name}} : {{license.license_id}}"></option>
diff --git a/server/templates/usb-logs/logs.html b/server/templates/usb-logs/logs.html
index fdecc00..3bafd19 100644
--- a/server/templates/usb-logs/logs.html
+++ b/server/templates/usb-logs/logs.html
@@ -60,21 +60,21 @@
 </form>
 <form action="/logs-web" method="post">
   <label for="pc">PC:</label>
-  <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all">
+  <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();">
     <datalist id="pcs">
         {% for pc in pcs %}
         <option value="{{pc.username}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-  <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+  <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses">
         {% for license in licenses %}
         <option value="{{license.name}}"></option>
diff --git a/server/templates/usb-logs/logs_normal.html b/server/templates/usb-logs/logs_normal.html
index d954447..a43a0e4 100644
--- a/server/templates/usb-logs/logs_normal.html
+++ b/server/templates/usb-logs/logs_normal.html
@@ -59,21 +59,21 @@
 </form>
 <form action="/logs-web" method="post">
   <label for="pc">PC:</label>
-  <input id="pc" name="pc" type="text" list="pcs" value="" placeholder="all">
+  <input id="pc" name="pc" type="text" list="pcs" value="{{pc_val}}" placeholder="all" onClick="this.select();">
     <datalist id="pcs">
         {% for pc in pcs %}
         <option value="{{pc.username}}"></option>
         {% endfor %}
     </datalist>
     <label for="team">Team:</label>
-  <input id="team" name="team" type="text" list="teams" value="" placeholder="all">
+  <input id="team" name="team" type="text" list="teams" value="{{team_val}}" placeholder="all" onClick="this.select();">
     <datalist id="teams">
         {% for team in teams %}
         <option value="{{team.name}}"></option>
         {% endfor %}
     </datalist>
     <label for="lic">License:</label>
-    <input id="lic" name="lic" type="text" list="licenses" value="" placeholder="all">
+    <input id="lic" name="lic" type="text" list="licenses" value="{{lic_val}}" placeholder="all" onClick="this.select();">
     <datalist id="licenses">
         {% for license in licenses %}
         <option value="{{license.name}}"></option>
diff --git a/server/templates/users/users.html b/server/templates/users/users.html
index bdbec4b..1f71950 100644
--- a/server/templates/users/users.html
+++ b/server/templates/users/users.html
@@ -27,6 +27,9 @@
     <title>Users Details</title>
 </head>
 <body>
+<div style='float:left;padding-right:20px'>
+<b>Your role: {{user}}</b>
+</div>
 <div style='float:left;padding-right:5px'>
 <form action="/login" method="get">
     <input type="submit" value="Login" />
-- 
GitLab