diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..01b559c57b44c9724181e969c6cf0fcc40953ab0
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,15 @@
+# Set the default behavior, in case people don't have core.autocrlf set.
+* text=auto
+
+# Explicitly declare text files you want to always be normalized and converted
+# to native line endings on checkout.
+
+# Declare files that will always have LF line endings on checkout.
+*.yml text eol=lf
+
+# Declare files that will always have CRLF line endings on checkout.
+*.cs text eol=crlf
+
+# Denote all files that are truly binary and should not be modified.
+*.png binary
+*.jpg binary
diff --git a/src/Jackett.Console/Program.cs b/src/Jackett.Console/Program.cs
index a11037ac2e3d5c6d651363c36d4377666d68d14f..59976e8cb71f876f936de5edc6aea6e6691654cd 100644
--- a/src/Jackett.Console/Program.cs
+++ b/src/Jackett.Console/Program.cs
@@ -1,236 +1,236 @@
-using CommandLine;
-using CommandLine.Text;
-using Jackett;
-using Jackett.Console;
-using Jackett.Indexers;
-using Jackett.Utils;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Reflection;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace JackettConsole
-{
-    public class Program
-    {
-        static void Main(string[] args)
-        {
-            try
-            {
-                var options = new ConsoleOptions();
-                if (!Parser.Default.ParseArguments(args, options) || options.ShowHelp == true)
-                {
-                    if (options.LastParserState != null && options.LastParserState.Errors.Count > 0)
-                    {
-                        var help = new HelpText();
-                        var errors = help.RenderParsingErrorsText(options, 2); // indent with two spaces
-                        Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
-                        Console.WriteLine("Switch error: " + errors);
-                        Console.WriteLine("See --help for further details on switches.");
-                        Environment.ExitCode = 1;
-                        return;
-                    }
-                    else
-                    {
-
-                        var text = HelpText.AutoBuild(options, (HelpText current) => HelpText.DefaultParsingErrorsHandler(options, current));
-                        text.Copyright = " ";
-                        text.Heading = "Jackett v" + Engine.ConfigService.GetVersion() + " options:";
-                        Console.WriteLine(text);
-                        Environment.ExitCode = 1;
-                        return;
-                    }
-                }
-                else
-                {
-
-                    if (options.ListenPublic && options.ListenPrivate)
-                    {
-                        Console.WriteLine("You can only use listen private OR listen publicly.");
-                        Environment.ExitCode = 1;
-                        return;
-                    }
-                    /*  ======     Options    =====  */
-
-                    // SSL Fix
-                    Startup.DoSSLFix = options.SSLFix;
-
-                    // Use curl
-                    if (options.Client != null)
-                        Startup.ClientOverride = options.Client.ToLowerInvariant();
-
-                    // Use Proxy
-                    if (options.ProxyConnection != null)
-                    {
-                        Startup.ProxyConnection = options.ProxyConnection.ToLowerInvariant();
-                        Engine.Logger.Info("Proxy enabled. " + Startup.ProxyConnection);
-                    }
-                    // Logging
-                    if (options.Logging)
-                        Startup.LogRequests = true;
-
-                    // Tracing
-                    if (options.Tracing)
-                        Startup.TracingEnabled = true;
-
-                    // Log after the fact as using the logger will cause the options above to be used
-
-                    if (options.Logging)
-                        Engine.Logger.Info("Logging enabled.");
-
-                    if (options.Tracing)
-                        Engine.Logger.Info("Tracing enabled.");
-
-                    if (options.SSLFix == true)
-                        Engine.Logger.Info("SSL ECC workaround enabled.");
-                    else if (options.SSLFix == false)
-                        Engine.Logger.Info("SSL ECC workaround has been disabled.");
-
-                    // Ignore SSL errors on Curl
-                    Startup.IgnoreSslErrors = options.IgnoreSslErrors;
-                    if (options.IgnoreSslErrors == true)
-                    {
-                        Engine.Logger.Info("Jackett will ignore SSL certificate errors.");
-                    }
-
-                    // Choose Data Folder
-                    if (!string.IsNullOrWhiteSpace(options.DataFolder))
-                    {
-                        Startup.CustomDataFolder = options.DataFolder.Replace("\"", string.Empty).Replace("'", string.Empty).Replace(@"\\", @"\");
-                        Engine.Logger.Info("Jackett Data will be stored in: " + Startup.CustomDataFolder);
-                    }
-
-                    /*  ======     Actions    =====  */
-
-                    // Install service
-                    if (options.Install)
-                    {
-                        Engine.ServiceConfig.Install();
-                        return;
-                    }
-
-                    // Uninstall service
-                    if (options.Uninstall)
-                    {
-                        Engine.Server.ReserveUrls(doInstall: false);
-                        Engine.ServiceConfig.Uninstall();
-                        return;
-                    }
-
-                    // Reserve urls
-                    if (options.ReserveUrls)
-                    {
-                        Engine.Server.ReserveUrls(doInstall: true);
-                        return;
-                    }
-
-                    // Start Service
-                    if (options.StartService)
-                    {
-                        if (!Engine.ServiceConfig.ServiceRunning())
-                        {
-                            Engine.ServiceConfig.Start();
-                        }
-                        return;
-                    }
-
-                    // Stop Service
-                    if (options.StopService)
-                    {
-                        if (Engine.ServiceConfig.ServiceRunning())
-                        {
-                            Engine.ServiceConfig.Stop();
-                        }
-                        return;
-                    }
-
-                    // Migrate settings
-                    if (options.MigrateSettings)
-                    {
-                        Engine.ConfigService.PerformMigration();
-                        return;
-                    }
-
-
-                    // Show Version
-                    if (options.ShowVersion)
-                    {
-                        Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
-                        return;
-                    }
-
-                    /*  ======     Overrides    =====  */
-
-                    // Override listen public
-                    if (options.ListenPublic || options.ListenPrivate)
-                    {
-                        if (Engine.Server.Config.AllowExternal != options.ListenPublic)
-                        {
-                            Engine.Logger.Info("Overriding external access to " + options.ListenPublic);
-                            Engine.Server.Config.AllowExternal = options.ListenPublic;
-                            if (System.Environment.OSVersion.Platform != PlatformID.Unix)
-                            {
-                                if (ServerUtil.IsUserAdministrator())
-                                {
-                                    Engine.Server.ReserveUrls(doInstall: true);
-                                }
-                                else
-                                {
-                                    Engine.Logger.Error("Unable to switch to public listening without admin rights.");
-                                    Environment.ExitCode = 1;
-                                    return;
-                                }
-                            }
-
-                            Engine.Server.SaveConfig();
-                        }
-                    }
-
-                    // Override port
-                    if (options.Port != 0)
-                    {
-                        if (Engine.Server.Config.Port != options.Port)
-                        {
-                            Engine.Logger.Info("Overriding port to " + options.Port);
-                            Engine.Server.Config.Port = options.Port;
-                            if (System.Environment.OSVersion.Platform != PlatformID.Unix)
-                            {
-                                if (ServerUtil.IsUserAdministrator())
-                                {
-                                    Engine.Server.ReserveUrls(doInstall: true);
-                                }
-                                else
-                                {
-                                    Engine.Logger.Error("Unable to switch ports when not running as administrator");
-                                    Environment.ExitCode = 1;
-                                    return;
-                                }
-                            }
-
-                            Engine.Server.SaveConfig();
-                        }
-                    }
-
-                    Startup.NoRestart = options.NoRestart;
-                }
-
-                Engine.Server.Initalize();
-                Engine.Server.Start();
-                Engine.RunTime.Spin();
-                Engine.Logger.Info("Server thread exit");
-            }
-            catch (Exception e)
-            {
-                Engine.Logger.Error(e, "Top level exception");
-            }
-        }
-    }
-}
-
+using CommandLine;
+using CommandLine.Text;
+using Jackett;
+using Jackett.Console;
+using Jackett.Indexers;
+using Jackett.Utils;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace JackettConsole
+{
+    public class Program
+    {
+        static void Main(string[] args)
+        {
+            try
+            {
+                var options = new ConsoleOptions();
+                if (!Parser.Default.ParseArguments(args, options) || options.ShowHelp == true)
+                {
+                    if (options.LastParserState != null && options.LastParserState.Errors.Count > 0)
+                    {
+                        var help = new HelpText();
+                        var errors = help.RenderParsingErrorsText(options, 2); // indent with two spaces
+                        Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
+                        Console.WriteLine("Switch error: " + errors);
+                        Console.WriteLine("See --help for further details on switches.");
+                        Environment.ExitCode = 1;
+                        return;
+                    }
+                    else
+                    {
+
+                        var text = HelpText.AutoBuild(options, (HelpText current) => HelpText.DefaultParsingErrorsHandler(options, current));
+                        text.Copyright = " ";
+                        text.Heading = "Jackett v" + Engine.ConfigService.GetVersion() + " options:";
+                        Console.WriteLine(text);
+                        Environment.ExitCode = 1;
+                        return;
+                    }
+                }
+                else
+                {
+
+                    if (options.ListenPublic && options.ListenPrivate)
+                    {
+                        Console.WriteLine("You can only use listen private OR listen publicly.");
+                        Environment.ExitCode = 1;
+                        return;
+                    }
+                    /*  ======     Options    =====  */
+
+                    // SSL Fix
+                    Startup.DoSSLFix = options.SSLFix;
+
+                    // Use curl
+                    if (options.Client != null)
+                        Startup.ClientOverride = options.Client.ToLowerInvariant();
+
+                    // Use Proxy
+                    if (options.ProxyConnection != null)
+                    {
+                        Startup.ProxyConnection = options.ProxyConnection.ToLowerInvariant();
+                        Engine.Logger.Info("Proxy enabled. " + Startup.ProxyConnection);
+                    }
+                    // Logging
+                    if (options.Logging)
+                        Startup.LogRequests = true;
+
+                    // Tracing
+                    if (options.Tracing)
+                        Startup.TracingEnabled = true;
+
+                    // Log after the fact as using the logger will cause the options above to be used
+
+                    if (options.Logging)
+                        Engine.Logger.Info("Logging enabled.");
+
+                    if (options.Tracing)
+                        Engine.Logger.Info("Tracing enabled.");
+
+                    if (options.SSLFix == true)
+                        Engine.Logger.Info("SSL ECC workaround enabled.");
+                    else if (options.SSLFix == false)
+                        Engine.Logger.Info("SSL ECC workaround has been disabled.");
+
+                    // Ignore SSL errors on Curl
+                    Startup.IgnoreSslErrors = options.IgnoreSslErrors;
+                    if (options.IgnoreSslErrors == true)
+                    {
+                        Engine.Logger.Info("Jackett will ignore SSL certificate errors.");
+                    }
+
+                    // Choose Data Folder
+                    if (!string.IsNullOrWhiteSpace(options.DataFolder))
+                    {
+                        Startup.CustomDataFolder = options.DataFolder.Replace("\"", string.Empty).Replace("'", string.Empty).Replace(@"\\", @"\");
+                        Engine.Logger.Info("Jackett Data will be stored in: " + Startup.CustomDataFolder);
+                    }
+
+                    /*  ======     Actions    =====  */
+
+                    // Install service
+                    if (options.Install)
+                    {
+                        Engine.ServiceConfig.Install();
+                        return;
+                    }
+
+                    // Uninstall service
+                    if (options.Uninstall)
+                    {
+                        Engine.Server.ReserveUrls(doInstall: false);
+                        Engine.ServiceConfig.Uninstall();
+                        return;
+                    }
+
+                    // Reserve urls
+                    if (options.ReserveUrls)
+                    {
+                        Engine.Server.ReserveUrls(doInstall: true);
+                        return;
+                    }
+
+                    // Start Service
+                    if (options.StartService)
+                    {
+                        if (!Engine.ServiceConfig.ServiceRunning())
+                        {
+                            Engine.ServiceConfig.Start();
+                        }
+                        return;
+                    }
+
+                    // Stop Service
+                    if (options.StopService)
+                    {
+                        if (Engine.ServiceConfig.ServiceRunning())
+                        {
+                            Engine.ServiceConfig.Stop();
+                        }
+                        return;
+                    }
+
+                    // Migrate settings
+                    if (options.MigrateSettings)
+                    {
+                        Engine.ConfigService.PerformMigration();
+                        return;
+                    }
+
+
+                    // Show Version
+                    if (options.ShowVersion)
+                    {
+                        Console.WriteLine("Jackett v" + Engine.ConfigService.GetVersion());
+                        return;
+                    }
+
+                    /*  ======     Overrides    =====  */
+
+                    // Override listen public
+                    if (options.ListenPublic || options.ListenPrivate)
+                    {
+                        if (Engine.Server.Config.AllowExternal != options.ListenPublic)
+                        {
+                            Engine.Logger.Info("Overriding external access to " + options.ListenPublic);
+                            Engine.Server.Config.AllowExternal = options.ListenPublic;
+                            if (System.Environment.OSVersion.Platform != PlatformID.Unix)
+                            {
+                                if (ServerUtil.IsUserAdministrator())
+                                {
+                                    Engine.Server.ReserveUrls(doInstall: true);
+                                }
+                                else
+                                {
+                                    Engine.Logger.Error("Unable to switch to public listening without admin rights.");
+                                    Environment.ExitCode = 1;
+                                    return;
+                                }
+                            }
+
+                            Engine.Server.SaveConfig();
+                        }
+                    }
+
+                    // Override port
+                    if (options.Port != 0)
+                    {
+                        if (Engine.Server.Config.Port != options.Port)
+                        {
+                            Engine.Logger.Info("Overriding port to " + options.Port);
+                            Engine.Server.Config.Port = options.Port;
+                            if (System.Environment.OSVersion.Platform != PlatformID.Unix)
+                            {
+                                if (ServerUtil.IsUserAdministrator())
+                                {
+                                    Engine.Server.ReserveUrls(doInstall: true);
+                                }
+                                else
+                                {
+                                    Engine.Logger.Error("Unable to switch ports when not running as administrator");
+                                    Environment.ExitCode = 1;
+                                    return;
+                                }
+                            }
+
+                            Engine.Server.SaveConfig();
+                        }
+                    }
+
+                    Startup.NoRestart = options.NoRestart;
+                }
+
+                Engine.Server.Initalize();
+                Engine.Server.Start();
+                Engine.RunTime.Spin();
+                Engine.Logger.Info("Server thread exit");
+            }
+            catch (Exception e)
+            {
+                Engine.Logger.Error(e, "Top level exception");
+            }
+        }
+    }
+}
+
diff --git a/src/Jackett.Test/TestWebClient.cs b/src/Jackett.Test/TestWebClient.cs
index 33e1bee079fa25e58f5969ab0fe5749843ece9f9..d299175ae7c1d76f0c0a161d41fdaef4157fd08a 100644
--- a/src/Jackett.Test/TestWebClient.cs
+++ b/src/Jackett.Test/TestWebClient.cs
@@ -1,6 +1,6 @@
-using Jackett.Services;
+using Jackett.Services;
 using Jackett.Utils.Clients;
-using NLog;
+using NLog;
 using System;
 using System.Collections.Generic;
 using System.Linq;
@@ -14,10 +14,10 @@ namespace JackettTest
         private Dictionary<WebRequest, Func<WebRequest, WebClientByteResult>> byteCallbacks = new Dictionary<WebRequest, Func<WebRequest, WebClientByteResult>>();
         private Dictionary<WebRequest, Func<WebRequest, WebClientStringResult>> stringCallbacks = new Dictionary<WebRequest, Func<WebRequest, WebClientStringResult>>();
 
-        public TestWebClient(IProcessService p, Logger l, IConfigurationService c)
+        public TestWebClient(IProcessService p, Logger l, IConfigurationService c)
             : base(p: p,
                    l: l,
-                   c: c)
+                   c: c)
         {
         }
 
diff --git a/src/Jackett.Updater/Program.cs b/src/Jackett.Updater/Program.cs
index 0959a14939620d3f04ce190961eaf12213a1bd2e..5ad1d5ea7a644420075cf9198d9ff665e1418fa3 100644
--- a/src/Jackett.Updater/Program.cs
+++ b/src/Jackett.Updater/Program.cs
@@ -1,259 +1,259 @@
-using CommandLine;
-using Jackett.Services;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Web;
-/*
-// no supported by appveyor, disabeling for now
-#if __MonoCS__
-using Mono.Unix.Native;
-#endif
-*/
-
-namespace Jackett.Updater
-{
-    class Program
-    {
-        static void Main(string[] args)
-        {
-            new Program().Run(args);
-        }
-
-        private void Run(string[] args)
-        {
-            Engine.SetupLogging(null, "updater.txt");
-            Engine.Logger.Info("Jackett Updater v" + GetCurrentVersion());
-            Engine.Logger.Info("Options \"" + string.Join("\" \"", args) + "\"");
-            try {
-                var options = new UpdaterConsoleOptions();
-                if (Parser.Default.ParseArguments(args, options))
-                {
-                    ProcessUpdate(options);
-                }
-                else
-                {
-                    Engine.Logger.Error("Failed to process update arguments!");
-                    Console.ReadKey();
-                }
-            }
-            catch (Exception e)
-            {
-                Engine.Logger.Error(e, "Exception applying update!");
-            }
-        }
-
-        private string GetCurrentVersion()
-        {
-            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
-            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
-            return fvi.FileVersion;
-        }
-
-        private void KillPids(int[] pids)
-        {
-            foreach (var pid in pids)
-            {
-                try
-                {
-                    var proc = Process.GetProcessById(pid);
-                    Engine.Logger.Info("Killing process " + proc.Id);
-                    proc.Kill();
-                    var exited = proc.WaitForExit(5000);
-                    if (!exited)
-                        Engine.Logger.Info("Process " + pid.ToString() + " didn't exit within 5 seconds");
-/*
-// no supported by appveyor, disabeling for now
-#if __MonoCS__
-                    Engine.Logger.Info("Sending SIGKILL to process " + pid.ToString());
-                    Syscall.kill(proc.Id, Signum.SIGKILL);
-#endif
-*/
-                }
-                catch (ArgumentException e)
-                {
-                    Engine.Logger.Info("Process " + pid.ToString() + " is already dead");
-                }
-                catch (Exception e)
-                {
-                    Engine.Logger.Info("Error killing process " + pid.ToString());
-                    Engine.Logger.Info(e);
-                }
-            }
-        }
-
-        private void ProcessUpdate(UpdaterConsoleOptions options)
-        {
-            var updateLocation = GetUpdateLocation();
-            if(!(updateLocation.EndsWith("\\") || updateLocation.EndsWith("/")))
-            {
-                updateLocation += Path.DirectorySeparatorChar;
-            }
-
-            var pids = new int[] { };
-            if (options.KillPids != null)
-            {
-                var pidsStr = options.KillPids.Split(',').Where(pid => !string.IsNullOrWhiteSpace(pid)).ToArray();
-                pids = Array.ConvertAll(pidsStr, pid => int.Parse(pid));
-            }
-
-            var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
-            var trayRunning = false;
-            var trayProcesses = Process.GetProcessesByName("JackettTray");
-            if (isWindows)
-            {
-                if (trayProcesses.Count() > 0)
-                {  
-                    foreach (var proc in trayProcesses)
-                    {
-                        try
-                        {
-                            Engine.Logger.Info("Killing tray process " + proc.Id);
-                            proc.Kill();
-                            trayRunning = true;
-                        }
-                        catch { }
-                    }
-                }
-
-                // on unix we don't have to wait (we can overwrite files which are in use)
-                // On unix we kill the PIDs after the update so e.g. systemd can automatically restart the process
-                KillPids(pids);
-            }
-            Engine.Logger.Info("Finding files in: " + updateLocation);
-            var files = Directory.GetFiles(updateLocation, "*.*", SearchOption.AllDirectories);
-            foreach(var file in files)
-            {
-                var fileName = Path.GetFileName(file).ToLowerInvariant();
-
-                if (fileName.EndsWith(".zip") ||
-                    fileName.EndsWith(".tar") ||
-                    fileName.EndsWith(".gz"))
-                {
-                    continue;
-                }
-                try {
-                    Engine.Logger.Info("Copying " + fileName);
-                    var dest = Path.Combine(options.Path, file.Substring(updateLocation.Length));
-                    var destDir = Path.GetDirectoryName(dest);
-                    if (!Directory.Exists(destDir))
-                    {
-                        Engine.Logger.Info("Creating directory " + destDir);
-                        Directory.CreateDirectory(destDir);
-                    }
-                    File.Copy(file, dest, true);
-                }
-                catch(Exception e)
-                {
-                    Engine.Logger.Error(e);
-                }
-            }
-
-            // delete old dirs
-            string[] oldDirs = new string[] { "Content/logos" };
-
-            foreach (var oldDir in oldDirs)
-            {
-                try
-                {
-                    var deleteDir = Path.Combine(options.Path, oldDir);
-                    if (Directory.Exists(deleteDir))
-                    {
-                        Engine.Logger.Info("Deleting directory " + deleteDir);
-                        Directory.Delete(deleteDir, true);
-                    }
-                }
-                catch (Exception e)
-                {
-                    Engine.Logger.Error(e);
-                }
-            }
-
-
-            // delete old files
-            string[] oldFiles = new string[] {
-                "Content/css/jquery.dataTables.css",
-                "Content/css/jquery.dataTables_themeroller.css",
-                "Definitions/tspate.yml",
-                "Definitions/freakstrackingsystem.yml",
-                "Definitions/rarbg.yml",
-                "Definitions/t411.yml",
-                "Definitions/hdbc.yml", // renamed to hdbitscom
-            };
-
-            foreach (var oldFIle in oldFiles)
-            {
-                try
-                {
-                    var deleteFile = Path.Combine(options.Path, oldFIle);
-                    if (File.Exists(deleteFile))
-                    {
-                        Engine.Logger.Info("Deleting file " + deleteFile);
-                        File.Delete(deleteFile);
-                    }
-                }
-                catch (Exception e)
-                {
-                    Engine.Logger.Error(e);
-                }
-            }
-
-            // kill pids after the update on UNIX
-            if (!isWindows)
-                KillPids(pids);
-
-            if (options.NoRestart == false)
-            {
-                if (trayRunning)
-                {
-                    var startInfo = new ProcessStartInfo()
-                    {
-                        Arguments = options.Args,
-                        FileName = Path.Combine(options.Path, "JackettTray.exe"),
-                        UseShellExecute = true
-                    };
-
-                    Process.Start(startInfo);
-                }
-
-                if(string.Equals(options.Type, "JackettService.exe", StringComparison.InvariantCultureIgnoreCase))
-                {
-                    var serviceHelper = new ServiceConfigService(null, null);
-                    if (serviceHelper.ServiceExists())
-                    {
-                        serviceHelper.Start();
-                    }
-                } else
-                {
-                    var startInfo = new ProcessStartInfo()
-                    {
-                        Arguments = options.Args,
-                        FileName = Path.Combine(options.Path, "JackettConsole.exe"),
-                        UseShellExecute = true
-                    };
-
-                    if (!isWindows)
-                    {
-                        startInfo.Arguments = startInfo.FileName + " " + startInfo.Arguments;
-                        startInfo.FileName = "mono";
-                    }
-
-                    Engine.Logger.Info("Starting Jackett: " + startInfo.FileName + " " + startInfo.Arguments);
-                    Process.Start(startInfo);
-                }
-            }
-        }
-
-        private string GetUpdateLocation()
-        {
-            var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
-            return new FileInfo(HttpUtility.UrlDecode(location.AbsolutePath)).DirectoryName;
-        }
-    }
-}
+using CommandLine;
+using Jackett.Services;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Web;
+/*
+// no supported by appveyor, disabeling for now
+#if __MonoCS__
+using Mono.Unix.Native;
+#endif
+*/
+
+namespace Jackett.Updater
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            new Program().Run(args);
+        }
+
+        private void Run(string[] args)
+        {
+            Engine.SetupLogging(null, "updater.txt");
+            Engine.Logger.Info("Jackett Updater v" + GetCurrentVersion());
+            Engine.Logger.Info("Options \"" + string.Join("\" \"", args) + "\"");
+            try {
+                var options = new UpdaterConsoleOptions();
+                if (Parser.Default.ParseArguments(args, options))
+                {
+                    ProcessUpdate(options);
+                }
+                else
+                {
+                    Engine.Logger.Error("Failed to process update arguments!");
+                    Console.ReadKey();
+                }
+            }
+            catch (Exception e)
+            {
+                Engine.Logger.Error(e, "Exception applying update!");
+            }
+        }
+
+        private string GetCurrentVersion()
+        {
+            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
+            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
+            return fvi.FileVersion;
+        }
+
+        private void KillPids(int[] pids)
+        {
+            foreach (var pid in pids)
+            {
+                try
+                {
+                    var proc = Process.GetProcessById(pid);
+                    Engine.Logger.Info("Killing process " + proc.Id);
+                    proc.Kill();
+                    var exited = proc.WaitForExit(5000);
+                    if (!exited)
+                        Engine.Logger.Info("Process " + pid.ToString() + " didn't exit within 5 seconds");
+/*
+// no supported by appveyor, disabeling for now
+#if __MonoCS__
+                    Engine.Logger.Info("Sending SIGKILL to process " + pid.ToString());
+                    Syscall.kill(proc.Id, Signum.SIGKILL);
+#endif
+*/
+                }
+                catch (ArgumentException e)
+                {
+                    Engine.Logger.Info("Process " + pid.ToString() + " is already dead");
+                }
+                catch (Exception e)
+                {
+                    Engine.Logger.Info("Error killing process " + pid.ToString());
+                    Engine.Logger.Info(e);
+                }
+            }
+        }
+
+        private void ProcessUpdate(UpdaterConsoleOptions options)
+        {
+            var updateLocation = GetUpdateLocation();
+            if(!(updateLocation.EndsWith("\\") || updateLocation.EndsWith("/")))
+            {
+                updateLocation += Path.DirectorySeparatorChar;
+            }
+
+            var pids = new int[] { };
+            if (options.KillPids != null)
+            {
+                var pidsStr = options.KillPids.Split(',').Where(pid => !string.IsNullOrWhiteSpace(pid)).ToArray();
+                pids = Array.ConvertAll(pidsStr, pid => int.Parse(pid));
+            }
+
+            var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
+            var trayRunning = false;
+            var trayProcesses = Process.GetProcessesByName("JackettTray");
+            if (isWindows)
+            {
+                if (trayProcesses.Count() > 0)
+                {  
+                    foreach (var proc in trayProcesses)
+                    {
+                        try
+                        {
+                            Engine.Logger.Info("Killing tray process " + proc.Id);
+                            proc.Kill();
+                            trayRunning = true;
+                        }
+                        catch { }
+                    }
+                }
+
+                // on unix we don't have to wait (we can overwrite files which are in use)
+                // On unix we kill the PIDs after the update so e.g. systemd can automatically restart the process
+                KillPids(pids);
+            }
+            Engine.Logger.Info("Finding files in: " + updateLocation);
+            var files = Directory.GetFiles(updateLocation, "*.*", SearchOption.AllDirectories);
+            foreach(var file in files)
+            {
+                var fileName = Path.GetFileName(file).ToLowerInvariant();
+
+                if (fileName.EndsWith(".zip") ||
+                    fileName.EndsWith(".tar") ||
+                    fileName.EndsWith(".gz"))
+                {
+                    continue;
+                }
+                try {
+                    Engine.Logger.Info("Copying " + fileName);
+                    var dest = Path.Combine(options.Path, file.Substring(updateLocation.Length));
+                    var destDir = Path.GetDirectoryName(dest);
+                    if (!Directory.Exists(destDir))
+                    {
+                        Engine.Logger.Info("Creating directory " + destDir);
+                        Directory.CreateDirectory(destDir);
+                    }
+                    File.Copy(file, dest, true);
+                }
+                catch(Exception e)
+                {
+                    Engine.Logger.Error(e);
+                }
+            }
+
+            // delete old dirs
+            string[] oldDirs = new string[] { "Content/logos" };
+
+            foreach (var oldDir in oldDirs)
+            {
+                try
+                {
+                    var deleteDir = Path.Combine(options.Path, oldDir);
+                    if (Directory.Exists(deleteDir))
+                    {
+                        Engine.Logger.Info("Deleting directory " + deleteDir);
+                        Directory.Delete(deleteDir, true);
+                    }
+                }
+                catch (Exception e)
+                {
+                    Engine.Logger.Error(e);
+                }
+            }
+
+
+            // delete old files
+            string[] oldFiles = new string[] {
+                "Content/css/jquery.dataTables.css",
+                "Content/css/jquery.dataTables_themeroller.css",
+                "Definitions/tspate.yml",
+                "Definitions/freakstrackingsystem.yml",
+                "Definitions/rarbg.yml",
+                "Definitions/t411.yml",
+                "Definitions/hdbc.yml", // renamed to hdbitscom
+            };
+
+            foreach (var oldFIle in oldFiles)
+            {
+                try
+                {
+                    var deleteFile = Path.Combine(options.Path, oldFIle);
+                    if (File.Exists(deleteFile))
+                    {
+                        Engine.Logger.Info("Deleting file " + deleteFile);
+                        File.Delete(deleteFile);
+                    }
+                }
+                catch (Exception e)
+                {
+                    Engine.Logger.Error(e);
+                }
+            }
+
+            // kill pids after the update on UNIX
+            if (!isWindows)
+                KillPids(pids);
+
+            if (options.NoRestart == false)
+            {
+                if (trayRunning)
+                {
+                    var startInfo = new ProcessStartInfo()
+                    {
+                        Arguments = options.Args,
+                        FileName = Path.Combine(options.Path, "JackettTray.exe"),
+                        UseShellExecute = true
+                    };
+
+                    Process.Start(startInfo);
+                }
+
+                if(string.Equals(options.Type, "JackettService.exe", StringComparison.InvariantCultureIgnoreCase))
+                {
+                    var serviceHelper = new ServiceConfigService(null, null);
+                    if (serviceHelper.ServiceExists())
+                    {
+                        serviceHelper.Start();
+                    }
+                } else
+                {
+                    var startInfo = new ProcessStartInfo()
+                    {
+                        Arguments = options.Args,
+                        FileName = Path.Combine(options.Path, "JackettConsole.exe"),
+                        UseShellExecute = true
+                    };
+
+                    if (!isWindows)
+                    {
+                        startInfo.Arguments = startInfo.FileName + " " + startInfo.Arguments;
+                        startInfo.FileName = "mono";
+                    }
+
+                    Engine.Logger.Info("Starting Jackett: " + startInfo.FileName + " " + startInfo.Arguments);
+                    Process.Start(startInfo);
+                }
+            }
+        }
+
+        private string GetUpdateLocation()
+        {
+            var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
+            return new FileInfo(HttpUtility.UrlDecode(location.AbsolutePath)).DirectoryName;
+        }
+    }
+}
diff --git a/src/Jackett.Updater/UpdaterConsoleOptions.cs b/src/Jackett.Updater/UpdaterConsoleOptions.cs
index 2466bcb02c56dbdabac0110a5ee7739f292f8567..931de42eef3cbd74ae4b3ac01ebe7feea3a21c5f 100644
--- a/src/Jackett.Updater/UpdaterConsoleOptions.cs
+++ b/src/Jackett.Updater/UpdaterConsoleOptions.cs
@@ -13,8 +13,8 @@ namespace Jackett.Updater
         public string Path { get; set; }
 
         [Option('t', "Type", HelpText = "Install type")]
-        public string Type { get; set; }
-
+        public string Type { get; set; }
+
         [Option('a', "Args", HelpText = "Launch arguments")]
         public string Args { get; set; }
 
diff --git a/src/Jackett/Controllers/AdminController.cs b/src/Jackett/Controllers/AdminController.cs
index e5bf8d89bb596ff88d5623f262970acc76df396b..58d557f1b405077294ee5191d91a144dfdc33d7c 100644
--- a/src/Jackett/Controllers/AdminController.cs
+++ b/src/Jackett/Controllers/AdminController.cs
@@ -1,595 +1,595 @@
-using Autofac;
-using AutoMapper;
-using Jackett.Indexers;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Security.Claims;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.Http;
-using System.Web.Http.Results;
-using System.Web.Security;
-using System.Windows.Forms;
-
-namespace Jackett.Controllers
-{
-    [RoutePrefix("admin")]
-    [JackettAuthorized]
-    [JackettAPINoCache]
-    public class AdminController : ApiController
-    {
-        private IConfigurationService config;
-        private IIndexerManagerService indexerService;
-        private IServerService serverService;
-        private ISecuityService securityService;
-        private IProcessService processService;
-        private ICacheService cacheService;
-        private Logger logger;
-        private ILogCacheService logCache;
-        private IUpdateService updater;
-
-        public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc, IUpdateService u)
-        {
-            this.config = config;
-            indexerService = i;
-            serverService = ss;
-            securityService = s;
-            processService = p;
-            cacheService = c;
-            logger = l;
-            logCache = lc;
-            updater = u;
-        }
-
-        private async Task<JToken> ReadPostDataJson()
-        {
-            var content = await Request.Content.ReadAsStringAsync();
-            return JObject.Parse(content);
-        }
-
-
-        private HttpResponseMessage GetFile(string path)
-        {
-            var result = new HttpResponseMessage(HttpStatusCode.OK);
-            var mappedPath = Path.Combine(config.GetContentFolder(), path);
-            var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read);
-            result.Content = new StreamContent(stream);
-            result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(mappedPath));
-
-            return result;
-        }
-
-        [HttpGet]
-        [AllowAnonymous]
-        public RedirectResult Logout()
-        {
-            var ctx = Request.GetOwinContext();
-            var authManager = ctx.Authentication;
-            authManager.SignOut("ApplicationCookie");
-            return Redirect("Admin/Dashboard");
-        }
-
-        [HttpGet]
-        [HttpPost]
-        [AllowAnonymous]
-        public async Task<HttpResponseMessage> Dashboard()
-        {
-            if (Request.RequestUri.Query != null && Request.RequestUri.Query.Contains("logout"))
-            {
-                var file = GetFile("login.html");
-                securityService.Logout(file);
-                return file;
-            }
-
-
-            if (securityService.CheckAuthorised(Request))
-            {
-                return GetFile("index.html");
-
-            }
-            else
-            {
-                var formData = await Request.Content.ReadAsFormDataAsync();
-
-                if (formData != null && securityService.HashPassword(formData["password"]) == serverService.Config.AdminPassword)
-                {
-                    var file = GetFile("index.html");
-                    securityService.Login(file);
-                    return file;
-                }
-                else
-                {
-                    return GetFile("login.html");
-                }
-            }
-        }
-
-        [Route("set_admin_password")]
-        [HttpPost]
-        public async Task<IHttpActionResult> SetAdminPassword()
-        {
-            var jsonReply = new JObject();
-            try
-            {
-                var postData = await ReadPostDataJson();
-                var password = (string)postData["password"];
-                if (string.IsNullOrEmpty(password))
-                {
-                    serverService.Config.AdminPassword = string.Empty;
-                }
-                else
-                {
-                    serverService.Config.AdminPassword = securityService.HashPassword(password);
-                }
-
-                serverService.SaveConfig();
-                jsonReply["result"] = "success";
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in SetAdminPassword");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("get_config_form")]
-        [HttpPost]
-        public async Task<IHttpActionResult> GetConfigForm()
-        {
-            var jsonReply = new JObject();
-            try
-            {
-                var postData = await ReadPostDataJson();
-                var indexer = indexerService.GetIndexer((string)postData["indexer"]);
-                var config = await indexer.GetConfigurationForSetup();
-                jsonReply["config"] = config.ToJson(null);
-                jsonReply["caps"] = indexer.TorznabCaps.CapsToJson();
-                jsonReply["name"] = indexer.DisplayName;
-                jsonReply["alternativesitelinks"] = JToken.FromObject(indexer.AlternativeSiteLinks);
-                jsonReply["result"] = "success";
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in GetConfigForm");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("configure_indexer")]
-        [HttpPost]
-        public async Task<IHttpActionResult> Configure()
-        {
-            var jsonReply = new JObject();
-            IIndexer indexer = null;
-            try
-            {
-                var postData = await ReadPostDataJson();
-                string indexerString = (string)postData["indexer"];
-                indexer = indexerService.GetIndexer((string)postData["indexer"]);
-                jsonReply["name"] = indexer.DisplayName;
-                var configurationResult = await indexer.ApplyConfiguration(postData["config"]);
-                if (configurationResult == IndexerConfigurationStatus.RequiresTesting)
-                {
-                    await indexerService.TestIndexer((string)postData["indexer"]);
-                }
-                else if (configurationResult == IndexerConfigurationStatus.Failed)
-                {
-                    throw new Exception("Configuration Failed");
-                }
-                jsonReply["result"] = "success";
-            }
-            catch (Exception ex)
-            {
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-                var baseIndexer = indexer as BaseIndexer;
-                if (null != baseIndexer)
-                    baseIndexer.ResetBaseConfig();
-                if (ex is ExceptionWithConfigData)
-                {
-                    jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(null,false);
-                }
-                else
-                {
-                    logger.Error(ex, "Exception in Configure");
-                }
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("get_indexers")]
-        [HttpGet]
-        public IHttpActionResult Indexers()
-        {
-            var jsonReply = new JObject();
-            try
-            {
-                jsonReply["result"] = "success";
-                JArray items = new JArray();
-
-                foreach (var indexer in indexerService.GetAllIndexers())
-                {
-                    var item = new JObject();
-                    item["id"] = indexer.ID;
-                    item["name"] = indexer.DisplayName;
-                    item["description"] = indexer.DisplayDescription;
-                    item["type"] = indexer.Type;
-                    item["configured"] = indexer.IsConfigured;
-                    item["site_link"] = indexer.SiteLink;
-                    item["language"] = indexer.Language;
-                    item["last_error"] = indexer.LastError;
-                    item["potatoenabled"] = indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => PotatoController.MOVIE_CATS.Contains(i));
-
-                    var caps = new JObject();
-                    foreach (var cap in indexer.TorznabCaps.Categories)
-                        caps[cap.ID.ToString()] = cap.Name;
-                    item["caps"] = caps;
-                    items.Add(item);
-                }
-                jsonReply["items"] = items;
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in get_indexers");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("test_indexer")]
-        [HttpPost]
-        public async Task<IHttpActionResult> Test()
-        {
-            JToken jsonReply = new JObject();
-            IIndexer indexer = null;
-            try
-            {
-                var postData = await ReadPostDataJson();
-                string indexerString = (string)postData["indexer"];
-                indexer = indexerService.GetIndexer(indexerString);
-                await indexerService.TestIndexer(indexerString);
-                jsonReply["name"] = indexer.DisplayName;
-                jsonReply["result"] = "success";
-                indexer.LastError = null;
-            }
-            catch (Exception ex)
-            {
-                var msg = ex.Message;
-                if (ex.InnerException != null)
-                    msg += ": " + ex.InnerException.Message;
-                logger.Error(ex, "Exception in test_indexer");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = msg;
-                if (indexer != null)
-                    indexer.LastError = msg;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("delete_indexer")]
-        [HttpPost]
-        public async Task<IHttpActionResult> Delete()
-        {
-            var jsonReply = new JObject();
-            try
-            {
-                var postData = await ReadPostDataJson();
-                string indexerString = (string)postData["indexer"];
-                indexerService.DeleteIndexer(indexerString);
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in delete_indexer");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("trigger_update")]
-        [HttpGet]
-        public IHttpActionResult TriggerUpdates()
-        {
-            var jsonReply = new JObject();
-            updater.CheckForUpdatesNow();
-            return Json(jsonReply);
-        }
-
-        [Route("get_jackett_config")]
-        [HttpGet]
-        public IHttpActionResult GetConfig()
-        {
-            var jsonReply = new JObject();
-            try
-            {
-                var cfg = new JObject();
-                cfg["notices"] = JToken.FromObject(serverService.notices);
-                cfg["port"] = serverService.Config.Port;
-                cfg["external"] = serverService.Config.AllowExternal;
-                cfg["api_key"] = serverService.Config.APIKey;
-                cfg["blackholedir"] = serverService.Config.BlackholeDir;
-                cfg["updatedisabled"] = serverService.Config.UpdateDisabled;
-                cfg["prerelease"] = serverService.Config.UpdatePrerelease;
-                cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
-                cfg["logging"] = Startup.TracingEnabled;
-                cfg["basepathoverride"] = serverService.Config.BasePathOverride;
-               
-
-                jsonReply["config"] = cfg;
-                jsonReply["app_version"] = config.GetVersion();
-                jsonReply["result"] = "success";
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in get_jackett_config");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("set_config")]
-        [HttpPost]
-        public async Task<IHttpActionResult> SetConfig()
-        {
-            var originalPort = Engine.Server.Config.Port;
-            var originalAllowExternal = Engine.Server.Config.AllowExternal;
-            var jsonReply = new JObject();
-            try
-            {
-                var postData = await ReadPostDataJson();
-                int port = (int)postData["port"];
-                bool external = (bool)postData["external"];
-                string saveDir = (string)postData["blackholedir"];
-                bool updateDisabled = (bool)postData["updatedisabled"];
-                bool preRelease = (bool)postData["prerelease"];
-                bool logging = (bool)postData["logging"];
-                string basePathOverride = (string)postData["basepathoverride"];
-
-                Engine.Server.Config.UpdateDisabled = updateDisabled;
-                Engine.Server.Config.UpdatePrerelease = preRelease;
-                Engine.Server.Config.BasePathOverride = basePathOverride;
-                Startup.BasePath = Engine.Server.BasePath();
-                Engine.Server.SaveConfig();
-
-                Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
-                Startup.TracingEnabled = logging;
-
-                if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
-                {
-
-                    if (ServerUtil.RestrictedPorts.Contains(port))
-                    {
-                        jsonReply["result"] = "error";
-                        jsonReply["error"] = "The port you have selected is restricted, try a different one.";
-                        return Json(jsonReply);
-                    }
-
-                    // Save port to the config so it can be picked up by the if needed when running as admin below.
-                    Engine.Server.Config.AllowExternal = external;
-                    Engine.Server.Config.Port = port;
-                    Engine.Server.SaveConfig();
-
-                    // On Windows change the url reservations
-                    if (System.Environment.OSVersion.Platform != PlatformID.Unix)
-                    {
-                        if (!ServerUtil.IsUserAdministrator())
-                        {
-                            try
-                            {
-                                processService.StartProcessAndLog(Application.ExecutablePath, "--ReserveUrls", true);
-                            }
-                            catch
-                            {
-                                Engine.Server.Config.Port = originalPort;
-                                Engine.Server.Config.AllowExternal = originalAllowExternal;
-                                Engine.Server.SaveConfig();
-                                jsonReply["result"] = "error";
-                                jsonReply["error"] = "Failed to acquire admin permissions to reserve the new port.";
-                                return Json(jsonReply);
-                            }
-                        }
-                        else
-                        {
-                            serverService.ReserveUrls(true);
-                        }
-                    }
-
-                (new Thread(() =>
-                {
-                    Thread.Sleep(500);
-                    serverService.Stop();
-                    Engine.BuildContainer();
-                    Engine.Server.Initalize();
-                    Engine.Server.Start();
-                })).Start();
-                }
-                
-                if (saveDir != Engine.Server.Config.BlackholeDir)
-                {
-                    if (!string.IsNullOrEmpty(saveDir))
-                    {
-                        if (!Directory.Exists(saveDir))
-                        {
-                            throw new Exception("Blackhole directory does not exist");
-                        }
-                    }
-
-                    Engine.Server.Config.BlackholeDir = saveDir;
-                    Engine.Server.SaveConfig();
-                }
-
-                jsonReply["result"] = "success";
-                jsonReply["port"] = port;
-                jsonReply["external"] = external;
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Exception in set_port");
-                jsonReply["result"] = "error";
-                jsonReply["error"] = ex.Message;
-            }
-            return Json(jsonReply);
-        }
-
-        [Route("GetCache")]
-        [HttpGet]
-        public List<TrackerCacheResult> GetCache()
-        {
-            var results = cacheService.GetCachedResults();
-            ConfigureCacheResults(results);
-            return results;
-        }
-
-
-        private void ConfigureCacheResults(List<TrackerCacheResult> results)
-        {
-            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
-            foreach (var result in results)
-            {
-                var link = result.Link;
-                result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", result.Title + ".torrent");
-                if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
-                    result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty);
-
-            }
-        }
-
-        [Route("GetLogs")]
-        [HttpGet]
-        public List<CachedLog> GetLogs()
-        {
-            return logCache.Logs;
-        }
-
-        [Route("Search")]
-        [HttpPost]
-        public ManualSearchResult Search([FromBody]AdminSearch value)
-        {
-            var results = new List<TrackerCacheResult>();
-            var stringQuery = new TorznabQuery();
-
-            var queryStr = value.Query;
-            if (queryStr != null)
-            { 
-                var seasonMatch = Regex.Match(queryStr, @"S(\d{2,4})");
-                if (seasonMatch.Success)
-                {
-                    stringQuery.Season = int.Parse(seasonMatch.Groups[1].Value);
-                    queryStr = queryStr.Remove(seasonMatch.Index, seasonMatch.Length);
-                }
-
-                var episodeMatch = Regex.Match(queryStr, @"E(\d{2,4})");
-                if (episodeMatch.Success)
-                {
-                    stringQuery.Episode = episodeMatch.Groups[1].Value;
-                    queryStr = queryStr.Remove(episodeMatch.Index, episodeMatch.Length);
-                }
-                queryStr = queryStr.Trim();
-            }
-        
-
-            stringQuery.SearchTerm = queryStr;
-            stringQuery.Categories = value.Category == 0 ? new int[0] : new int[1] { value.Category };
-            stringQuery.ExpandCatsToSubCats();
-
-            // try to build an IMDB Query
-            var imdbID = ParseUtil.GetFullImdbID(stringQuery.SanitizedSearchTerm);
-            TorznabQuery imdbQuery = null;
-            if (imdbID != null)
-            {
-                imdbQuery = new TorznabQuery()
-                {
-                    ImdbID = imdbID,
-                    Categories = stringQuery.Categories,
-                    Season = stringQuery.Season,
-                    Episode = stringQuery.Episode,
-                };
-                imdbQuery.ExpandCatsToSubCats();
-            }
-
-            var trackers = indexerService.GetAllIndexers().Where(t => t.IsConfigured).ToList();
-            if (!string.IsNullOrWhiteSpace(value.Tracker))
-            {
-                trackers = trackers.Where(t => t.ID == value.Tracker).ToList();
-            }
-
-            if (value.Category != 0)
-            {
-                trackers = trackers.Where(t => t.TorznabCaps.Categories.Select(c => c.ID).Contains(value.Category)).ToList();
-            }
-
-            Parallel.ForEach(trackers.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 1000 }, indexer =>
-            {
-                try
-                {
-                    var query = stringQuery;
-                    // use imdb Query for trackers which support it
-                    if (imdbQuery != null && indexer.TorznabCaps.SupportsImdbSearch)
-                        query = imdbQuery;
-
-                    var searchResults = indexer.PerformQuery(query).Result;
-                    searchResults = indexer.CleanLinks(searchResults);
-                    cacheService.CacheRssResults(indexer, searchResults);
-                    searchResults = indexer.FilterResults(query, searchResults);
-
-                    foreach (var result in searchResults)
-                    {
-                        var item = Mapper.Map<TrackerCacheResult>(result);
-                        item.Tracker = indexer.DisplayName;
-                        item.TrackerId = indexer.ID;
-                        item.Peers = item.Peers - item.Seeders; // Use peers as leechers
-                        lock (results)
-                        {
-                            results.Add(item);
-                        }
-                    }
-                }
-                catch (Exception e)
-                {
-                    logger.Error(e, "An error occured during manual search on " + indexer.DisplayName + ":  " + e.Message);
-                }
-            });
-
-            ConfigureCacheResults(results);
-
-            if (trackers.Count > 1)
-            {
-                results = results.OrderByDescending(d => d.PublishDate).ToList();
-            }
-
-            var manualResult = new ManualSearchResult()
-            {
-                Results = results,
-                Indexers = trackers.Select(t => t.DisplayName).ToList()
-            };
-
-
-            if (manualResult.Indexers.Count == 0)
-                manualResult.Indexers = new List<string>() { "None" };
-
-            logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", stringQuery.GetQueryString(), string.Join(", ", manualResult.Indexers), manualResult.Results.Count));
-            return manualResult;
-        }
-    }
-}
-
+using Autofac;
+using AutoMapper;
+using Jackett.Indexers;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Security.Claims;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Web;
+using System.Web.Http;
+using System.Web.Http.Results;
+using System.Web.Security;
+using System.Windows.Forms;
+
+namespace Jackett.Controllers
+{
+    [RoutePrefix("admin")]
+    [JackettAuthorized]
+    [JackettAPINoCache]
+    public class AdminController : ApiController
+    {
+        private IConfigurationService config;
+        private IIndexerManagerService indexerService;
+        private IServerService serverService;
+        private ISecuityService securityService;
+        private IProcessService processService;
+        private ICacheService cacheService;
+        private Logger logger;
+        private ILogCacheService logCache;
+        private IUpdateService updater;
+
+        public AdminController(IConfigurationService config, IIndexerManagerService i, IServerService ss, ISecuityService s, IProcessService p, ICacheService c, Logger l, ILogCacheService lc, IUpdateService u)
+        {
+            this.config = config;
+            indexerService = i;
+            serverService = ss;
+            securityService = s;
+            processService = p;
+            cacheService = c;
+            logger = l;
+            logCache = lc;
+            updater = u;
+        }
+
+        private async Task<JToken> ReadPostDataJson()
+        {
+            var content = await Request.Content.ReadAsStringAsync();
+            return JObject.Parse(content);
+        }
+
+
+        private HttpResponseMessage GetFile(string path)
+        {
+            var result = new HttpResponseMessage(HttpStatusCode.OK);
+            var mappedPath = Path.Combine(config.GetContentFolder(), path);
+            var stream = new FileStream(mappedPath, FileMode.Open, FileAccess.Read, FileShare.Read);
+            result.Content = new StreamContent(stream);
+            result.Content.Headers.ContentType = new MediaTypeHeaderValue(MimeMapping.GetMimeMapping(mappedPath));
+
+            return result;
+        }
+
+        [HttpGet]
+        [AllowAnonymous]
+        public RedirectResult Logout()
+        {
+            var ctx = Request.GetOwinContext();
+            var authManager = ctx.Authentication;
+            authManager.SignOut("ApplicationCookie");
+            return Redirect("Admin/Dashboard");
+        }
+
+        [HttpGet]
+        [HttpPost]
+        [AllowAnonymous]
+        public async Task<HttpResponseMessage> Dashboard()
+        {
+            if (Request.RequestUri.Query != null && Request.RequestUri.Query.Contains("logout"))
+            {
+                var file = GetFile("login.html");
+                securityService.Logout(file);
+                return file;
+            }
+
+
+            if (securityService.CheckAuthorised(Request))
+            {
+                return GetFile("index.html");
+
+            }
+            else
+            {
+                var formData = await Request.Content.ReadAsFormDataAsync();
+
+                if (formData != null && securityService.HashPassword(formData["password"]) == serverService.Config.AdminPassword)
+                {
+                    var file = GetFile("index.html");
+                    securityService.Login(file);
+                    return file;
+                }
+                else
+                {
+                    return GetFile("login.html");
+                }
+            }
+        }
+
+        [Route("set_admin_password")]
+        [HttpPost]
+        public async Task<IHttpActionResult> SetAdminPassword()
+        {
+            var jsonReply = new JObject();
+            try
+            {
+                var postData = await ReadPostDataJson();
+                var password = (string)postData["password"];
+                if (string.IsNullOrEmpty(password))
+                {
+                    serverService.Config.AdminPassword = string.Empty;
+                }
+                else
+                {
+                    serverService.Config.AdminPassword = securityService.HashPassword(password);
+                }
+
+                serverService.SaveConfig();
+                jsonReply["result"] = "success";
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in SetAdminPassword");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("get_config_form")]
+        [HttpPost]
+        public async Task<IHttpActionResult> GetConfigForm()
+        {
+            var jsonReply = new JObject();
+            try
+            {
+                var postData = await ReadPostDataJson();
+                var indexer = indexerService.GetIndexer((string)postData["indexer"]);
+                var config = await indexer.GetConfigurationForSetup();
+                jsonReply["config"] = config.ToJson(null);
+                jsonReply["caps"] = indexer.TorznabCaps.CapsToJson();
+                jsonReply["name"] = indexer.DisplayName;
+                jsonReply["alternativesitelinks"] = JToken.FromObject(indexer.AlternativeSiteLinks);
+                jsonReply["result"] = "success";
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in GetConfigForm");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("configure_indexer")]
+        [HttpPost]
+        public async Task<IHttpActionResult> Configure()
+        {
+            var jsonReply = new JObject();
+            IIndexer indexer = null;
+            try
+            {
+                var postData = await ReadPostDataJson();
+                string indexerString = (string)postData["indexer"];
+                indexer = indexerService.GetIndexer((string)postData["indexer"]);
+                jsonReply["name"] = indexer.DisplayName;
+                var configurationResult = await indexer.ApplyConfiguration(postData["config"]);
+                if (configurationResult == IndexerConfigurationStatus.RequiresTesting)
+                {
+                    await indexerService.TestIndexer((string)postData["indexer"]);
+                }
+                else if (configurationResult == IndexerConfigurationStatus.Failed)
+                {
+                    throw new Exception("Configuration Failed");
+                }
+                jsonReply["result"] = "success";
+            }
+            catch (Exception ex)
+            {
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+                var baseIndexer = indexer as BaseIndexer;
+                if (null != baseIndexer)
+                    baseIndexer.ResetBaseConfig();
+                if (ex is ExceptionWithConfigData)
+                {
+                    jsonReply["config"] = ((ExceptionWithConfigData)ex).ConfigData.ToJson(null,false);
+                }
+                else
+                {
+                    logger.Error(ex, "Exception in Configure");
+                }
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("get_indexers")]
+        [HttpGet]
+        public IHttpActionResult Indexers()
+        {
+            var jsonReply = new JObject();
+            try
+            {
+                jsonReply["result"] = "success";
+                JArray items = new JArray();
+
+                foreach (var indexer in indexerService.GetAllIndexers())
+                {
+                    var item = new JObject();
+                    item["id"] = indexer.ID;
+                    item["name"] = indexer.DisplayName;
+                    item["description"] = indexer.DisplayDescription;
+                    item["type"] = indexer.Type;
+                    item["configured"] = indexer.IsConfigured;
+                    item["site_link"] = indexer.SiteLink;
+                    item["language"] = indexer.Language;
+                    item["last_error"] = indexer.LastError;
+                    item["potatoenabled"] = indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => PotatoController.MOVIE_CATS.Contains(i));
+
+                    var caps = new JObject();
+                    foreach (var cap in indexer.TorznabCaps.Categories)
+                        caps[cap.ID.ToString()] = cap.Name;
+                    item["caps"] = caps;
+                    items.Add(item);
+                }
+                jsonReply["items"] = items;
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in get_indexers");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("test_indexer")]
+        [HttpPost]
+        public async Task<IHttpActionResult> Test()
+        {
+            JToken jsonReply = new JObject();
+            IIndexer indexer = null;
+            try
+            {
+                var postData = await ReadPostDataJson();
+                string indexerString = (string)postData["indexer"];
+                indexer = indexerService.GetIndexer(indexerString);
+                await indexerService.TestIndexer(indexerString);
+                jsonReply["name"] = indexer.DisplayName;
+                jsonReply["result"] = "success";
+                indexer.LastError = null;
+            }
+            catch (Exception ex)
+            {
+                var msg = ex.Message;
+                if (ex.InnerException != null)
+                    msg += ": " + ex.InnerException.Message;
+                logger.Error(ex, "Exception in test_indexer");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = msg;
+                if (indexer != null)
+                    indexer.LastError = msg;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("delete_indexer")]
+        [HttpPost]
+        public async Task<IHttpActionResult> Delete()
+        {
+            var jsonReply = new JObject();
+            try
+            {
+                var postData = await ReadPostDataJson();
+                string indexerString = (string)postData["indexer"];
+                indexerService.DeleteIndexer(indexerString);
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in delete_indexer");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("trigger_update")]
+        [HttpGet]
+        public IHttpActionResult TriggerUpdates()
+        {
+            var jsonReply = new JObject();
+            updater.CheckForUpdatesNow();
+            return Json(jsonReply);
+        }
+
+        [Route("get_jackett_config")]
+        [HttpGet]
+        public IHttpActionResult GetConfig()
+        {
+            var jsonReply = new JObject();
+            try
+            {
+                var cfg = new JObject();
+                cfg["notices"] = JToken.FromObject(serverService.notices);
+                cfg["port"] = serverService.Config.Port;
+                cfg["external"] = serverService.Config.AllowExternal;
+                cfg["api_key"] = serverService.Config.APIKey;
+                cfg["blackholedir"] = serverService.Config.BlackholeDir;
+                cfg["updatedisabled"] = serverService.Config.UpdateDisabled;
+                cfg["prerelease"] = serverService.Config.UpdatePrerelease;
+                cfg["password"] = string.IsNullOrEmpty(serverService.Config.AdminPassword) ? string.Empty : serverService.Config.AdminPassword.Substring(0, 10);
+                cfg["logging"] = Startup.TracingEnabled;
+                cfg["basepathoverride"] = serverService.Config.BasePathOverride;
+               
+
+                jsonReply["config"] = cfg;
+                jsonReply["app_version"] = config.GetVersion();
+                jsonReply["result"] = "success";
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in get_jackett_config");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("set_config")]
+        [HttpPost]
+        public async Task<IHttpActionResult> SetConfig()
+        {
+            var originalPort = Engine.Server.Config.Port;
+            var originalAllowExternal = Engine.Server.Config.AllowExternal;
+            var jsonReply = new JObject();
+            try
+            {
+                var postData = await ReadPostDataJson();
+                int port = (int)postData["port"];
+                bool external = (bool)postData["external"];
+                string saveDir = (string)postData["blackholedir"];
+                bool updateDisabled = (bool)postData["updatedisabled"];
+                bool preRelease = (bool)postData["prerelease"];
+                bool logging = (bool)postData["logging"];
+                string basePathOverride = (string)postData["basepathoverride"];
+
+                Engine.Server.Config.UpdateDisabled = updateDisabled;
+                Engine.Server.Config.UpdatePrerelease = preRelease;
+                Engine.Server.Config.BasePathOverride = basePathOverride;
+                Startup.BasePath = Engine.Server.BasePath();
+                Engine.Server.SaveConfig();
+
+                Engine.SetLogLevel(logging ? LogLevel.Debug : LogLevel.Info);
+                Startup.TracingEnabled = logging;
+
+                if (port != Engine.Server.Config.Port || external != Engine.Server.Config.AllowExternal)
+                {
+
+                    if (ServerUtil.RestrictedPorts.Contains(port))
+                    {
+                        jsonReply["result"] = "error";
+                        jsonReply["error"] = "The port you have selected is restricted, try a different one.";
+                        return Json(jsonReply);
+                    }
+
+                    // Save port to the config so it can be picked up by the if needed when running as admin below.
+                    Engine.Server.Config.AllowExternal = external;
+                    Engine.Server.Config.Port = port;
+                    Engine.Server.SaveConfig();
+
+                    // On Windows change the url reservations
+                    if (System.Environment.OSVersion.Platform != PlatformID.Unix)
+                    {
+                        if (!ServerUtil.IsUserAdministrator())
+                        {
+                            try
+                            {
+                                processService.StartProcessAndLog(Application.ExecutablePath, "--ReserveUrls", true);
+                            }
+                            catch
+                            {
+                                Engine.Server.Config.Port = originalPort;
+                                Engine.Server.Config.AllowExternal = originalAllowExternal;
+                                Engine.Server.SaveConfig();
+                                jsonReply["result"] = "error";
+                                jsonReply["error"] = "Failed to acquire admin permissions to reserve the new port.";
+                                return Json(jsonReply);
+                            }
+                        }
+                        else
+                        {
+                            serverService.ReserveUrls(true);
+                        }
+                    }
+
+                (new Thread(() =>
+                {
+                    Thread.Sleep(500);
+                    serverService.Stop();
+                    Engine.BuildContainer();
+                    Engine.Server.Initalize();
+                    Engine.Server.Start();
+                })).Start();
+                }
+                
+                if (saveDir != Engine.Server.Config.BlackholeDir)
+                {
+                    if (!string.IsNullOrEmpty(saveDir))
+                    {
+                        if (!Directory.Exists(saveDir))
+                        {
+                            throw new Exception("Blackhole directory does not exist");
+                        }
+                    }
+
+                    Engine.Server.Config.BlackholeDir = saveDir;
+                    Engine.Server.SaveConfig();
+                }
+
+                jsonReply["result"] = "success";
+                jsonReply["port"] = port;
+                jsonReply["external"] = external;
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Exception in set_port");
+                jsonReply["result"] = "error";
+                jsonReply["error"] = ex.Message;
+            }
+            return Json(jsonReply);
+        }
+
+        [Route("GetCache")]
+        [HttpGet]
+        public List<TrackerCacheResult> GetCache()
+        {
+            var results = cacheService.GetCachedResults();
+            ConfigureCacheResults(results);
+            return results;
+        }
+
+
+        private void ConfigureCacheResults(List<TrackerCacheResult> results)
+        {
+            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
+            foreach (var result in results)
+            {
+                var link = result.Link;
+                result.Link = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "dl", result.Title + ".torrent");
+                if (result.Link != null && result.Link.Scheme != "magnet" && !string.IsNullOrWhiteSpace(Engine.Server.Config.BlackholeDir))
+                    result.BlackholeLink = serverService.ConvertToProxyLink(link, serverUrl, result.TrackerId, "bh", string.Empty);
+
+            }
+        }
+
+        [Route("GetLogs")]
+        [HttpGet]
+        public List<CachedLog> GetLogs()
+        {
+            return logCache.Logs;
+        }
+
+        [Route("Search")]
+        [HttpPost]
+        public ManualSearchResult Search([FromBody]AdminSearch value)
+        {
+            var results = new List<TrackerCacheResult>();
+            var stringQuery = new TorznabQuery();
+
+            var queryStr = value.Query;
+            if (queryStr != null)
+            { 
+                var seasonMatch = Regex.Match(queryStr, @"S(\d{2,4})");
+                if (seasonMatch.Success)
+                {
+                    stringQuery.Season = int.Parse(seasonMatch.Groups[1].Value);
+                    queryStr = queryStr.Remove(seasonMatch.Index, seasonMatch.Length);
+                }
+
+                var episodeMatch = Regex.Match(queryStr, @"E(\d{2,4})");
+                if (episodeMatch.Success)
+                {
+                    stringQuery.Episode = episodeMatch.Groups[1].Value;
+                    queryStr = queryStr.Remove(episodeMatch.Index, episodeMatch.Length);
+                }
+                queryStr = queryStr.Trim();
+            }
+        
+
+            stringQuery.SearchTerm = queryStr;
+            stringQuery.Categories = value.Category == 0 ? new int[0] : new int[1] { value.Category };
+            stringQuery.ExpandCatsToSubCats();
+
+            // try to build an IMDB Query
+            var imdbID = ParseUtil.GetFullImdbID(stringQuery.SanitizedSearchTerm);
+            TorznabQuery imdbQuery = null;
+            if (imdbID != null)
+            {
+                imdbQuery = new TorznabQuery()
+                {
+                    ImdbID = imdbID,
+                    Categories = stringQuery.Categories,
+                    Season = stringQuery.Season,
+                    Episode = stringQuery.Episode,
+                };
+                imdbQuery.ExpandCatsToSubCats();
+            }
+
+            var trackers = indexerService.GetAllIndexers().Where(t => t.IsConfigured).ToList();
+            if (!string.IsNullOrWhiteSpace(value.Tracker))
+            {
+                trackers = trackers.Where(t => t.ID == value.Tracker).ToList();
+            }
+
+            if (value.Category != 0)
+            {
+                trackers = trackers.Where(t => t.TorznabCaps.Categories.Select(c => c.ID).Contains(value.Category)).ToList();
+            }
+
+            Parallel.ForEach(trackers.ToList(), new ParallelOptions { MaxDegreeOfParallelism = 1000 }, indexer =>
+            {
+                try
+                {
+                    var query = stringQuery;
+                    // use imdb Query for trackers which support it
+                    if (imdbQuery != null && indexer.TorznabCaps.SupportsImdbSearch)
+                        query = imdbQuery;
+
+                    var searchResults = indexer.PerformQuery(query).Result;
+                    searchResults = indexer.CleanLinks(searchResults);
+                    cacheService.CacheRssResults(indexer, searchResults);
+                    searchResults = indexer.FilterResults(query, searchResults);
+
+                    foreach (var result in searchResults)
+                    {
+                        var item = Mapper.Map<TrackerCacheResult>(result);
+                        item.Tracker = indexer.DisplayName;
+                        item.TrackerId = indexer.ID;
+                        item.Peers = item.Peers - item.Seeders; // Use peers as leechers
+                        lock (results)
+                        {
+                            results.Add(item);
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    logger.Error(e, "An error occured during manual search on " + indexer.DisplayName + ":  " + e.Message);
+                }
+            });
+
+            ConfigureCacheResults(results);
+
+            if (trackers.Count > 1)
+            {
+                results = results.OrderByDescending(d => d.PublishDate).ToList();
+            }
+
+            var manualResult = new ManualSearchResult()
+            {
+                Results = results,
+                Indexers = trackers.Select(t => t.DisplayName).ToList()
+            };
+
+
+            if (manualResult.Indexers.Count == 0)
+                manualResult.Indexers = new List<string>() { "None" };
+
+            logger.Info(string.Format("Manual search for \"{0}\" on {1} with {2} results.", stringQuery.GetQueryString(), string.Join(", ", manualResult.Indexers), manualResult.Results.Count));
+            return manualResult;
+        }
+    }
+}
+
diff --git a/src/Jackett/Controllers/PotatoController.cs b/src/Jackett/Controllers/PotatoController.cs
index f9f97cb0af9c92afcc8781a3006c94766a388d1b..ac266a79550d84d654a2244ecf4246fa6a63c484 100644
--- a/src/Jackett/Controllers/PotatoController.cs
+++ b/src/Jackett/Controllers/PotatoController.cs
@@ -1,173 +1,173 @@
-using AutoMapper;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.Http;
-
-namespace Jackett.Controllers
-{
-    [AllowAnonymous]
-    [JackettAPINoCache]
-    public class PotatoController : ApiController
-    {
-        private IIndexerManagerService indexerService;
-        private Logger logger;
-        private IServerService serverService;
-        private ICacheService cacheService;
-        private IWebClient webClient;
-
-        public static int[] MOVIE_CATS
-        {
-            get
-            {
-                var torznabQuery = new TorznabQuery()
-                {
-                    Categories = new int[1] { TorznabCatType.Movies.ID },
-                };
-
-                torznabQuery.ExpandCatsToSubCats();
-                    return torznabQuery.Categories;
-            }
-        }
-
-        public PotatoController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c, IWebClient w)
-        {
-            indexerService = i;
-            logger = l;
-            serverService = s;
-            cacheService = c;
-            webClient = w;
-        }
-
-        [HttpGet]
-        public async Task<HttpResponseMessage> Call(string indexerID, [FromUri]TorrentPotatoRequest request)
-        {
-            var indexer = indexerService.GetIndexer(indexerID);
-          
-            var allowBadApiDueToDebug = false;
-#if DEBUG
-            allowBadApiDueToDebug = Debugger.IsAttached;
-#endif
-
-            if (!allowBadApiDueToDebug && !string.Equals(request.passkey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase))
-            {
-                logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress));
-                return Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key");
-            }
-
-            if (!indexer.IsConfigured)
-            {
-                logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
-                return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
-            }
-
-            if (!indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => MOVIE_CATS.Contains(i))){
-                logger.Warn(string.Format("Rejected a request to {0} which does not support searching for movies.", indexer.DisplayName));
-                return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer does not support movies.");
-            }
-
-            var year = 0;
-
-            if (string.IsNullOrWhiteSpace(request.search))
-            {
-                // We are searching by IMDB id so look up the name
-                var omdbapiRequest = new Utils.Clients.WebRequest("http://www.omdbapi.com/?type=movie&i=" + request.imdbid);
-                omdbapiRequest.Encoding = Encoding.UTF8;
-                var response = await webClient.GetString(omdbapiRequest);
-                if (response.Status == HttpStatusCode.OK)
-                {
-                    JObject result = JObject.Parse(response.Content);
-                    if (result["Title"] != null)
-                    {
-                        request.search = result["Title"].ToString();
-                        year = ParseUtil.CoerceInt(result["Year"].ToString());
-                    }
-                }
-            }
-
-            var torznabQuery = new TorznabQuery()
-            {
-                ApiKey =  request.passkey,
-                Categories = MOVIE_CATS,
-                SearchTerm = request.search,
-                ImdbID = request.imdbid,
-                QueryType = "TorrentPotato"
-            };
-
-            IEnumerable<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
-            {
-                releases = await indexer.PerformQuery(torznabQuery);
-                releases = indexer.CleanLinks(releases);
-            }
-
-            // Cache non query results
-            if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
-            {
-                cacheService.CacheRssResults(indexer, releases);
-            }
-
-            releases = indexer.FilterResults(torznabQuery, releases);
-            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
-            var potatoResponse = new TorrentPotatoResponse();
-
-            releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);
-            releases = TorznabUtil.FilterResultsToImdb(releases, request.imdbid);
-
-            foreach (var r in releases)
-            {
-                var release = Mapper.Map<ReleaseInfo>(r);
-                release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, indexerID, "dl", release.Title + ".torrent");
-
-                // Only accept torrent links, magnet is not supported
-                // This seems to be no longer the case, allowing magnet URIs for now
-                if (release.Link != null || release.MagnetUri != null)
-                {
-                    potatoResponse.results.Add(new TorrentPotatoResponseItem()
-                    {
-                        release_name = release.Title + "[" + indexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
-                        torrent_id = release.Guid.ToString(),
-                        details_url = release.Comments.ToString(),
-                        download_url = (release.Link != null ? release.Link.ToString() : release.MagnetUri.ToString()),
-                        imdb_id = release.Imdb.HasValue ? "tt" + release.Imdb : null,
-                        freeleech = (release.DownloadVolumeFactor == 0 ? true : false),
-                        type = "movie",
-                        size = (long)release.Size / (1024 * 1024), // This is in MB
-                        leechers = (int)release.Peers - (int)release.Seeders,
-                        seeders = (int)release.Seeders,
-                        publish_date = r.PublishDate == DateTime.MinValue ? null : release.PublishDate.ToUniversalTime().ToString("s")
-                    });
-                }
-            }
-
-            // Log info
-            if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
-            {
-                logger.Info(string.Format("Found {0} torrentpotato releases from {1}", releases.Count(), indexer.DisplayName));
-            }
-            else
-            {
-                logger.Info(string.Format("Found {0} torrentpotato releases from {1} for: {2}", releases.Count(), indexer.DisplayName, torznabQuery.GetQueryString()));
-            }
-
-            // Force the return as Json
-            return new HttpResponseMessage()
-            {
-                Content = new JsonContent(potatoResponse)
-            };
-        }
-    }
-}
+using AutoMapper;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using System.Web.Http;
+
+namespace Jackett.Controllers
+{
+    [AllowAnonymous]
+    [JackettAPINoCache]
+    public class PotatoController : ApiController
+    {
+        private IIndexerManagerService indexerService;
+        private Logger logger;
+        private IServerService serverService;
+        private ICacheService cacheService;
+        private IWebClient webClient;
+
+        public static int[] MOVIE_CATS
+        {
+            get
+            {
+                var torznabQuery = new TorznabQuery()
+                {
+                    Categories = new int[1] { TorznabCatType.Movies.ID },
+                };
+
+                torznabQuery.ExpandCatsToSubCats();
+                    return torznabQuery.Categories;
+            }
+        }
+
+        public PotatoController(IIndexerManagerService i, Logger l, IServerService s, ICacheService c, IWebClient w)
+        {
+            indexerService = i;
+            logger = l;
+            serverService = s;
+            cacheService = c;
+            webClient = w;
+        }
+
+        [HttpGet]
+        public async Task<HttpResponseMessage> Call(string indexerID, [FromUri]TorrentPotatoRequest request)
+        {
+            var indexer = indexerService.GetIndexer(indexerID);
+          
+            var allowBadApiDueToDebug = false;
+#if DEBUG
+            allowBadApiDueToDebug = Debugger.IsAttached;
+#endif
+
+            if (!allowBadApiDueToDebug && !string.Equals(request.passkey, serverService.Config.APIKey, StringComparison.InvariantCultureIgnoreCase))
+            {
+                logger.Warn(string.Format("A request from {0} was made with an incorrect API key.", Request.GetOwinContext().Request.RemoteIpAddress));
+                return Request.CreateResponse(HttpStatusCode.Forbidden, "Incorrect API key");
+            }
+
+            if (!indexer.IsConfigured)
+            {
+                logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
+                return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
+            }
+
+            if (!indexer.TorznabCaps.Categories.Select(c => c.ID).Any(i => MOVIE_CATS.Contains(i))){
+                logger.Warn(string.Format("Rejected a request to {0} which does not support searching for movies.", indexer.DisplayName));
+                return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer does not support movies.");
+            }
+
+            var year = 0;
+
+            if (string.IsNullOrWhiteSpace(request.search))
+            {
+                // We are searching by IMDB id so look up the name
+                var omdbapiRequest = new Utils.Clients.WebRequest("http://www.omdbapi.com/?type=movie&i=" + request.imdbid);
+                omdbapiRequest.Encoding = Encoding.UTF8;
+                var response = await webClient.GetString(omdbapiRequest);
+                if (response.Status == HttpStatusCode.OK)
+                {
+                    JObject result = JObject.Parse(response.Content);
+                    if (result["Title"] != null)
+                    {
+                        request.search = result["Title"].ToString();
+                        year = ParseUtil.CoerceInt(result["Year"].ToString());
+                    }
+                }
+            }
+
+            var torznabQuery = new TorznabQuery()
+            {
+                ApiKey =  request.passkey,
+                Categories = MOVIE_CATS,
+                SearchTerm = request.search,
+                ImdbID = request.imdbid,
+                QueryType = "TorrentPotato"
+            };
+
+            IEnumerable<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            if (!string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
+            {
+                releases = await indexer.PerformQuery(torznabQuery);
+                releases = indexer.CleanLinks(releases);
+            }
+
+            // Cache non query results
+            if (string.IsNullOrEmpty(torznabQuery.SanitizedSearchTerm))
+            {
+                cacheService.CacheRssResults(indexer, releases);
+            }
+
+            releases = indexer.FilterResults(torznabQuery, releases);
+            var serverUrl = string.Format("{0}://{1}:{2}{3}", Request.RequestUri.Scheme, Request.RequestUri.Host, Request.RequestUri.Port, serverService.BasePath());
+            var potatoResponse = new TorrentPotatoResponse();
+
+            releases = TorznabUtil.FilterResultsToTitle(releases, torznabQuery.SanitizedSearchTerm, year);
+            releases = TorznabUtil.FilterResultsToImdb(releases, request.imdbid);
+
+            foreach (var r in releases)
+            {
+                var release = Mapper.Map<ReleaseInfo>(r);
+                release.Link = serverService.ConvertToProxyLink(release.Link, serverUrl, indexerID, "dl", release.Title + ".torrent");
+
+                // Only accept torrent links, magnet is not supported
+                // This seems to be no longer the case, allowing magnet URIs for now
+                if (release.Link != null || release.MagnetUri != null)
+                {
+                    potatoResponse.results.Add(new TorrentPotatoResponseItem()
+                    {
+                        release_name = release.Title + "[" + indexer.DisplayName + "]", // Suffix the indexer so we can see which tracker we are using in CPS as it just says torrentpotato >.>
+                        torrent_id = release.Guid.ToString(),
+                        details_url = release.Comments.ToString(),
+                        download_url = (release.Link != null ? release.Link.ToString() : release.MagnetUri.ToString()),
+                        imdb_id = release.Imdb.HasValue ? "tt" + release.Imdb : null,
+                        freeleech = (release.DownloadVolumeFactor == 0 ? true : false),
+                        type = "movie",
+                        size = (long)release.Size / (1024 * 1024), // This is in MB
+                        leechers = (int)release.Peers - (int)release.Seeders,
+                        seeders = (int)release.Seeders,
+                        publish_date = r.PublishDate == DateTime.MinValue ? null : release.PublishDate.ToUniversalTime().ToString("s")
+                    });
+                }
+            }
+
+            // Log info
+            if (string.IsNullOrWhiteSpace(torznabQuery.SanitizedSearchTerm))
+            {
+                logger.Info(string.Format("Found {0} torrentpotato releases from {1}", releases.Count(), indexer.DisplayName));
+            }
+            else
+            {
+                logger.Info(string.Format("Found {0} torrentpotato releases from {1} for: {2}", releases.Count(), indexer.DisplayName, torznabQuery.GetQueryString()));
+            }
+
+            // Force the return as Json
+            return new HttpResponseMessage()
+            {
+                Content = new JsonContent(potatoResponse)
+            };
+        }
+    }
+}
diff --git a/src/Jackett/Controllers/TorznabController.cs b/src/Jackett/Controllers/TorznabController.cs
index f309c60776c7639382e40e741ff12b2a656f4c82..ef299138e74a91cd2f8d200ac81ba6fb65fa2b9d 100644
--- a/src/Jackett/Controllers/TorznabController.cs
+++ b/src/Jackett/Controllers/TorznabController.cs
@@ -1,7 +1,7 @@
 using AutoMapper;
 using Jackett.Models;
 using Jackett.Services;
-using Jackett.Utils;
+using Jackett.Utils;
 using NLog;
 using System;
 using System.Collections.Generic;
@@ -13,8 +13,8 @@ using System.Text;
 using System.Threading.Tasks;
 using System.Web;
 using System.Web.Http;
-using System.Xml.Linq;
-
+using System.Xml.Linq;
+
 namespace Jackett.Controllers
 {
     [AllowAnonymous]
@@ -34,8 +34,8 @@ namespace Jackett.Controllers
             cacheService = c;
         }
 
-        public HttpResponseMessage GetErrorXML(int code, string description)
-        {
+        public HttpResponseMessage GetErrorXML(int code, string description)
+        {
             var xdoc = new XDocument(
                 new XDeclaration("1.0", "UTF-8", null),
                 new XElement("error",
@@ -46,10 +46,10 @@ namespace Jackett.Controllers
 
             var xml = xdoc.Declaration.ToString() + Environment.NewLine + xdoc.ToString();
 
-            return new HttpResponseMessage()
-            {
+            return new HttpResponseMessage()
+            {
                 Content = new StringContent(xml, Encoding.UTF8, "application/xml")
-            };
+            };
         }
 
         [HttpGet]
@@ -82,33 +82,33 @@ namespace Jackett.Controllers
             {
                 logger.Warn(string.Format("Rejected a request to {0} which is unconfigured.", indexer.DisplayName));
                 return Request.CreateResponse(HttpStatusCode.Forbidden, "This indexer is not configured.");
-            }
-
+            }
+
             if (torznabQuery.ImdbID != null)
             {
-                if (torznabQuery.QueryType != "movie")
-                {
-                    logger.Warn(string.Format("A non movie request with an imdbid was made from {0}.", Request.GetOwinContext().Request.RemoteIpAddress));
-                    return GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter");
+                if (torznabQuery.QueryType != "movie")
+                {
+                    logger.Warn(string.Format("A non movie request with an imdbid was made from {0}.", Request.GetOwinContext().Request.RemoteIpAddress));
+                    return GetErrorXML(201, "Incorrect parameter: only movie-search supports the imdbid parameter");
                 }
 
-                if (!string.IsNullOrEmpty(torznabQuery.SearchTerm))
-                {
-                    logger.Warn(string.Format("A movie-search request from {0} was made contining q and imdbid.", Request.GetOwinContext().Request.RemoteIpAddress));
-                    return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
+                if (!string.IsNullOrEmpty(torznabQuery.SearchTerm))
+                {
+                    logger.Warn(string.Format("A movie-search request from {0} was made contining q and imdbid.", Request.GetOwinContext().Request.RemoteIpAddress));
+                    return GetErrorXML(201, "Incorrect parameter: please specify either imdbid or q");
                 }
 
                 torznabQuery.ImdbID = ParseUtil.GetFullImdbID(torznabQuery.ImdbID); // normalize ImdbID
-                if (torznabQuery.ImdbID == null)
+                if (torznabQuery.ImdbID == null)
                 {
                     logger.Warn(string.Format("A movie-search request from {0} was made with an invalid imdbid.", Request.GetOwinContext().Request.RemoteIpAddress));
-                    return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
+                    return GetErrorXML(201, "Incorrect parameter: invalid imdbid format");
                 }
 
-                if (!indexer.TorznabCaps.SupportsImdbSearch)
+                if (!indexer.TorznabCaps.SupportsImdbSearch)
                 {
                     logger.Warn(string.Format("A movie-search request with imdbid from {0} was made but the indexer {1} doesn't support it.", Request.GetOwinContext().Request.RemoteIpAddress, indexer.DisplayName));
-                    return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
+                    return GetErrorXML(203, "Function Not Available: imdbid is not supported by this indexer");
                 }
             }
 
diff --git a/src/Jackett/CurlHelper.cs b/src/Jackett/CurlHelper.cs
index a5d1f4a5fb9fc6f3cc4e787f7f13782148c5afc8..327eb52281d6d3682ceeb0eab2a2f1d982970f5d 100644
--- a/src/Jackett/CurlHelper.cs
+++ b/src/Jackett/CurlHelper.cs
@@ -92,16 +92,16 @@ namespace Jackett
                     easy.BufferSize = 64 * 1024;
                     easy.UserAgent = BrowserUtil.ChromeUserAgent;
                     easy.FollowLocation = false;
-                    easy.ConnectTimeout = 20;
-                    if(curlRequest.Headers != null)
-                    {
-                        CurlSlist curlHeaders = new CurlSlist();
-                        foreach (var header in curlRequest.Headers)
-                        {
-                            curlHeaders.Append(header.Key + ": " + header.Value);
-                        }
-                        easy.SetOpt(CurlOption.HttpHeader, curlHeaders);
-                    }
+                    easy.ConnectTimeout = 20;
+                    if(curlRequest.Headers != null)
+                    {
+                        CurlSlist curlHeaders = new CurlSlist();
+                        foreach (var header in curlRequest.Headers)
+                        {
+                            curlHeaders.Append(header.Key + ": " + header.Value);
+                        }
+                        easy.SetOpt(CurlOption.HttpHeader, curlHeaders);
+                    }
 
                     easy.WriteFunction = (byte[] buf, int size, int nmemb, object data) =>
                     {
@@ -151,8 +151,8 @@ namespace Jackett
                     {
                         easy.SetOpt(CurlOption.SslVerifyhost, false);
                         easy.SetOpt(CurlOption.SslVerifyPeer, false);
-                    }
-
+                    }
+
                     if (Startup.ProxyConnection != null)
                     {
                         easy.SetOpt(CurlOption.HttpProxyTunnel, 1);
@@ -173,14 +173,14 @@ namespace Jackett
 
                 var headerBytes = Combine(headerBuffers.ToArray());
                 var headerString = Encoding.UTF8.GetString(headerBytes);
-                if (Startup.ProxyConnection != null)
-                {
-                    var firstcrlf = headerString.IndexOf("\r\n\r\n");
-                    var secondcrlf = headerString.IndexOf("\r\n\r\n", firstcrlf + 1);
-                    if (secondcrlf > 0)
-                    {
-                        headerString = headerString.Substring(firstcrlf + 4, secondcrlf - (firstcrlf));
-                    }
+                if (Startup.ProxyConnection != null)
+                {
+                    var firstcrlf = headerString.IndexOf("\r\n\r\n");
+                    var secondcrlf = headerString.IndexOf("\r\n\r\n", firstcrlf + 1);
+                    if (secondcrlf > 0)
+                    {
+                        headerString = headerString.Substring(firstcrlf + 4, secondcrlf - (firstcrlf));
+                    }
                 }
                 var headerParts = headerString.Split(new char[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
                 var headers = new List<string[]>();
@@ -231,28 +231,28 @@ namespace Jackett
                 }
 
                 // add some debug output to track down the problem causing people getting InternalServerError results
-                if (status == HttpStatusCode.NotImplemented || status == HttpStatusCode.InternalServerError)
-                {
-                    try
-                    {
-                        OnErrorMessage("got NotImplemented/InternalServerError");
-                        OnErrorMessage("request.Method: " + curlRequest.Method);
-                        OnErrorMessage("request.Url: " + curlRequest.Url);
-                        OnErrorMessage("request.Cookies: " + curlRequest.Cookies);
-                        OnErrorMessage("request.Referer: " + curlRequest.Referer);
-                        OnErrorMessage("request.RawPOSTDdata: " + curlRequest.RawPOSTDdata);
-                        OnErrorMessage("cookies: "+ cookieBuilder.ToString().Trim());
-                        OnErrorMessage("headerString:\n" + headerString);
-                    
-                        foreach (var headerPart in headerParts)
-                        {
-                            OnErrorMessage("headerParts: "+headerPart);
-                        }
+                if (status == HttpStatusCode.NotImplemented || status == HttpStatusCode.InternalServerError)
+                {
+                    try
+                    {
+                        OnErrorMessage("got NotImplemented/InternalServerError");
+                        OnErrorMessage("request.Method: " + curlRequest.Method);
+                        OnErrorMessage("request.Url: " + curlRequest.Url);
+                        OnErrorMessage("request.Cookies: " + curlRequest.Cookies);
+                        OnErrorMessage("request.Referer: " + curlRequest.Referer);
+                        OnErrorMessage("request.RawPOSTDdata: " + curlRequest.RawPOSTDdata);
+                        OnErrorMessage("cookies: "+ cookieBuilder.ToString().Trim());
+                        OnErrorMessage("headerString:\n" + headerString);
+                    
+                        foreach (var headerPart in headerParts)
+                        {
+                            OnErrorMessage("headerParts: "+headerPart);
+                        }
+                    }
+                    catch (Exception ex)
+                    {
+                        OnErrorMessage(string.Format("CurlHelper: error while handling NotImplemented/InternalServerError:\n{0}", ex));
                     }
-                    catch (Exception ex)
-                    {
-                        OnErrorMessage(string.Format("CurlHelper: error while handling NotImplemented/InternalServerError:\n{0}", ex));
-                    }
                 }
                 
                 var contentBytes = Combine(contentBuffers.ToArray());
diff --git a/src/Jackett/Definitions/2fast4you.yml b/src/Jackett/Definitions/2fast4you.yml
index e75af4d8b3d249237f97e12b7f5206a690cee0ca..4625d1df6f0865025518cf3bafbd5132b8aab654 100644
--- a/src/Jackett/Definitions/2fast4you.yml
+++ b/src/Jackett/Definitions/2fast4you.yml
@@ -1,139 +1,139 @@
----
-  site: 2fast4you
-  name: 2 Fast 4 You
-  language: fr-fr
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.2f4y.me/
-
-  caps:
-    categorymappings:
-      - {id: 10, cat: TV/Anime, desc: "Animation: HD720P"}
-      - {id: 11, cat: TV/Anime, desc: "Animation: HD1080P"}
-      - {id: 56, cat: TV/Anime, desc: "Animation: DVDRip"}
-      - {id: 13, cat: TV/Anime, desc: "Animation: DVD"}
-      - {id: 18, cat: PC/0day, desc: "Applications: PC"}
-      - {id: 16, cat: PC/Games, desc: "Applications: Jeux"}
-      - {id: 19, cat: PC/Phone-Android, desc: "Applications: Android"}
-      - {id: 38, cat: PC/Phone-IOS, desc: "Applications: Mobile Phone"}
-      - {id: 17, cat: PC/0day, desc: "Applications: Autres"}
-      - {id: 67, cat: TV, desc: "Autres: Emission TV"}
-      - {id: 68, cat: TV/Sport, desc: "Autres: Sport"}
-      - {id: 40, cat: Other, desc: "Autres: Autres"}
-      - {id: 14, cat: TV/Documentary, desc: "Documentaires: DivX"}
-      - {id: 15, cat: TV/Documentary, desc: "Documentaires: HD"}
-      - {id: 76, cat: TV/Documentary, desc: "Documentaires: TVRip"}
-      - {id: 62, cat: Audio/Audiobook, desc: "E-Books: E-Books Audio"}
-      - {id: 50, cat: Books, desc: "E-Books: Manuel Français"}
-      - {id: 49, cat: Books, desc: "E-Books: Manuel Anglais"}
-      - {id: 36, cat: Books, desc: "E-Books: Livres Français"}
-      - {id: 53, cat: Books, desc: "E-Books: Livre Anglais"}
-      - {id: 52, cat: Books, desc: "E-Books: Revue - Journaux"}
-      - {id: 51, cat: Books, desc: "E-Books: BD"}
-      - {id: 66, cat: Movies, desc: "Films: VOSTFR"}
-      - {id: 71, cat: Movies/WEBDL, desc: "Films: WEB-DL"}
-      - {id: 65, cat: Movies, desc: "Films: VO"}
-      - {id: 72, cat: Movies/SD, desc: "Films: TVRip/HDTV"}
-      - {id: 70, cat: Movies/HD, desc: "Films: MHD X265"}
-      - {id: 57, cat: Movies/SD, desc: "Films: TS/CAM"}
-      - {id: 59, cat: Movies, desc: "Films: Spectacle"}
-      - {id: 55, cat: Movies/HD, desc: "Films: MHD 720P"}
-      - {id: 54, cat: Movies/HD, desc: "Films: MHD 1080P"}
-      - {id: 1, cat: Movies/HD, desc: "Films: HD720P"}
-      - {id: 2, cat: Movies/HD, desc: "Films: HD1080P"}
-      - {id: 90, cat: Movies/HD, desc: "Films: HD X265"}
-      - {id: 92, cat: Movies/HD, desc: "Films: 4K"}
-      - {id: 69, cat: Movies/3D, desc: "Films: Film 3D"}
-      - {id: 3, cat: Movies/DVD, desc: "Films: DVDRIP"}
-      - {id: 4, cat: Movies/DVD, desc: "Films: DVD5"}
-      - {id: 5, cat: Movies/DVD, desc: "Films: DVD9"}
-      - {id: 91, cat: Movies/HD, desc: "Films: RemuX"}
-      - {id: 89, cat: Movies/HD, desc: "Films: BD/BR Rip"}
-      - {id: 88, cat: Movies/BluRay, desc: "Films: Full BD/BR"}
-      - {id: 77, cat: Other, desc: "GPS: Cartes"}
-      - {id: 78, cat: Other, desc: "GPS: Radars"}
-      - {id: 79, cat: TV/Anime, desc: "Mangas: HD"}
-      - {id: 80, cat: TV/Anime, desc: "Mangas: HD VO"}
-      - {id: 81, cat: TV/Anime, desc: "Mangas: HD VOSTFR"}
-      - {id: 82, cat: TV/Anime, desc: "Mangas: DVDRIP"}
-      - {id: 83, cat: TV/Anime, desc: "Mangas: DVDRIP VO"}
-      - {id: 84, cat: TV/Anime, desc: "Mangas: DVDRIP VOSTFR"}
-      - {id: 85, cat: TV/Anime, desc: "Mangas: Web-DL"}
-      - {id: 86, cat: TV/Anime, desc: "Mangas: TV-RIP"}
-      - {id: 75, cat: Audio, desc: "Musique: Concert TVRip"}
-      - {id: 25, cat: Audio/MP3, desc: "Musique: Single MP3"}
-      - {id: 24, cat: Audio/Lossless, desc: "Musique: Single Flac"}
-      - {id: 22, cat: Audio/MP3, desc: "Musique: Album MP3"}
-      - {id: 23, cat: Audio/Lossless, desc: "Musique: Album Flac"}
-      - {id: 64, cat: Audio, desc: "Musique: Mégamix Maison"}
-      - {id: 58, cat: Audio, desc: "Musique: Concert"}
-      - {id: 61, cat: TV, desc: "Serie TV: Episode VOSTFR"}
-      - {id: 63, cat: TV, desc: "Serie TV: Episode VO"}
-      - {id: 12, cat: TV/Anime, desc: "Serie TV: Animation"}
-      - {id: 74, cat: TV, desc: "Serie TV: TVRip"}
-      - {id: 73, cat: TV/WEB-DL, desc: "Serie TV: WEB-DL"}
-      - {id: 7, cat: TV, desc: "Serie TV: Episode FR"}
-      - {id: 6, cat: TV, desc: "Serie TV: Saison FR"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: account-login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: form:contains("Erreur")
-        message:
-          selector: form
-          remove: table
-    test:
-      path: torrents-search.php
-
-  search:
-    path: torrents-search.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-
-    rows:
-      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
-    fields:
-      download:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["torrents-details.php", "download.php"]
-      title:
-        selector: a[href^="torrents-details.php?id="]
-      category:
-        selector: a[href^="torrents.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-      banner:
-        selector: img.rounded-img
-        attribute: src
-      size:
-        selector: td:nth-child(5)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      downloadvolumefactor:
-        case:
-          img[title="freeleech"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: 2fast4you
+  name: 2 Fast 4 You
+  language: fr-fr
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.2f4y.me/
+
+  caps:
+    categorymappings:
+      - {id: 10, cat: TV/Anime, desc: "Animation: HD720P"}
+      - {id: 11, cat: TV/Anime, desc: "Animation: HD1080P"}
+      - {id: 56, cat: TV/Anime, desc: "Animation: DVDRip"}
+      - {id: 13, cat: TV/Anime, desc: "Animation: DVD"}
+      - {id: 18, cat: PC/0day, desc: "Applications: PC"}
+      - {id: 16, cat: PC/Games, desc: "Applications: Jeux"}
+      - {id: 19, cat: PC/Phone-Android, desc: "Applications: Android"}
+      - {id: 38, cat: PC/Phone-IOS, desc: "Applications: Mobile Phone"}
+      - {id: 17, cat: PC/0day, desc: "Applications: Autres"}
+      - {id: 67, cat: TV, desc: "Autres: Emission TV"}
+      - {id: 68, cat: TV/Sport, desc: "Autres: Sport"}
+      - {id: 40, cat: Other, desc: "Autres: Autres"}
+      - {id: 14, cat: TV/Documentary, desc: "Documentaires: DivX"}
+      - {id: 15, cat: TV/Documentary, desc: "Documentaires: HD"}
+      - {id: 76, cat: TV/Documentary, desc: "Documentaires: TVRip"}
+      - {id: 62, cat: Audio/Audiobook, desc: "E-Books: E-Books Audio"}
+      - {id: 50, cat: Books, desc: "E-Books: Manuel Français"}
+      - {id: 49, cat: Books, desc: "E-Books: Manuel Anglais"}
+      - {id: 36, cat: Books, desc: "E-Books: Livres Français"}
+      - {id: 53, cat: Books, desc: "E-Books: Livre Anglais"}
+      - {id: 52, cat: Books, desc: "E-Books: Revue - Journaux"}
+      - {id: 51, cat: Books, desc: "E-Books: BD"}
+      - {id: 66, cat: Movies, desc: "Films: VOSTFR"}
+      - {id: 71, cat: Movies/WEBDL, desc: "Films: WEB-DL"}
+      - {id: 65, cat: Movies, desc: "Films: VO"}
+      - {id: 72, cat: Movies/SD, desc: "Films: TVRip/HDTV"}
+      - {id: 70, cat: Movies/HD, desc: "Films: MHD X265"}
+      - {id: 57, cat: Movies/SD, desc: "Films: TS/CAM"}
+      - {id: 59, cat: Movies, desc: "Films: Spectacle"}
+      - {id: 55, cat: Movies/HD, desc: "Films: MHD 720P"}
+      - {id: 54, cat: Movies/HD, desc: "Films: MHD 1080P"}
+      - {id: 1, cat: Movies/HD, desc: "Films: HD720P"}
+      - {id: 2, cat: Movies/HD, desc: "Films: HD1080P"}
+      - {id: 90, cat: Movies/HD, desc: "Films: HD X265"}
+      - {id: 92, cat: Movies/HD, desc: "Films: 4K"}
+      - {id: 69, cat: Movies/3D, desc: "Films: Film 3D"}
+      - {id: 3, cat: Movies/DVD, desc: "Films: DVDRIP"}
+      - {id: 4, cat: Movies/DVD, desc: "Films: DVD5"}
+      - {id: 5, cat: Movies/DVD, desc: "Films: DVD9"}
+      - {id: 91, cat: Movies/HD, desc: "Films: RemuX"}
+      - {id: 89, cat: Movies/HD, desc: "Films: BD/BR Rip"}
+      - {id: 88, cat: Movies/BluRay, desc: "Films: Full BD/BR"}
+      - {id: 77, cat: Other, desc: "GPS: Cartes"}
+      - {id: 78, cat: Other, desc: "GPS: Radars"}
+      - {id: 79, cat: TV/Anime, desc: "Mangas: HD"}
+      - {id: 80, cat: TV/Anime, desc: "Mangas: HD VO"}
+      - {id: 81, cat: TV/Anime, desc: "Mangas: HD VOSTFR"}
+      - {id: 82, cat: TV/Anime, desc: "Mangas: DVDRIP"}
+      - {id: 83, cat: TV/Anime, desc: "Mangas: DVDRIP VO"}
+      - {id: 84, cat: TV/Anime, desc: "Mangas: DVDRIP VOSTFR"}
+      - {id: 85, cat: TV/Anime, desc: "Mangas: Web-DL"}
+      - {id: 86, cat: TV/Anime, desc: "Mangas: TV-RIP"}
+      - {id: 75, cat: Audio, desc: "Musique: Concert TVRip"}
+      - {id: 25, cat: Audio/MP3, desc: "Musique: Single MP3"}
+      - {id: 24, cat: Audio/Lossless, desc: "Musique: Single Flac"}
+      - {id: 22, cat: Audio/MP3, desc: "Musique: Album MP3"}
+      - {id: 23, cat: Audio/Lossless, desc: "Musique: Album Flac"}
+      - {id: 64, cat: Audio, desc: "Musique: Mégamix Maison"}
+      - {id: 58, cat: Audio, desc: "Musique: Concert"}
+      - {id: 61, cat: TV, desc: "Serie TV: Episode VOSTFR"}
+      - {id: 63, cat: TV, desc: "Serie TV: Episode VO"}
+      - {id: 12, cat: TV/Anime, desc: "Serie TV: Animation"}
+      - {id: 74, cat: TV, desc: "Serie TV: TVRip"}
+      - {id: 73, cat: TV/WEB-DL, desc: "Serie TV: WEB-DL"}
+      - {id: 7, cat: TV, desc: "Serie TV: Episode FR"}
+      - {id: 6, cat: TV, desc: "Serie TV: Saison FR"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: account-login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: form:contains("Erreur")
+        message:
+          selector: form
+          remove: table
+    test:
+      path: torrents-search.php
+
+  search:
+    path: torrents-search.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+
+    rows:
+      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
+    fields:
+      download:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["torrents-details.php", "download.php"]
+      title:
+        selector: a[href^="torrents-details.php?id="]
+      category:
+        selector: a[href^="torrents.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+      banner:
+        selector: img.rounded-img
+        attribute: src
+      size:
+        selector: td:nth-child(5)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      downloadvolumefactor:
+        case:
+          img[title="freeleech"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/3dtorrents.yml b/src/Jackett/Definitions/3dtorrents.yml
index f5ccb4e0a68d3f194c274e15c53e97eb6f82f86c..c381652defd1d5e1025cfecdd809cb404a1ec6d7 100644
--- a/src/Jackett/Definitions/3dtorrents.yml
+++ b/src/Jackett/Definitions/3dtorrents.yml
@@ -1,102 +1,102 @@
----
-  site: 3dtorrents
-  name: 3D Torrents
-  description: "3D Movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.3dtorrents.org/
-
-  caps:
-    categorymappings:
-      - {id: 14, cat: Movies, desc: "Movies XviD"}
-      - {id: 34, cat: Movies, desc: "Movies UltraHD"}
-      - {id: 15, cat: Movies, desc: "Movies DVD-R"}
-      - {id: 11, cat: Movies, desc: "Movies 720p"}
-      - {id: 13, cat: Movies, desc: "Movies 1080p"}
-      - {id: 16, cat: Movies, desc: "Movies 3DTV"}
-      - {id: 17, cat: Movies, desc: "Movies Blu-ray"}
-      - {id: 27, cat: Movies, desc: "Movies BD25 Encode"}
-      - {id: 33, cat: Movies, desc: "Movies BD9 AVCHD"}
-      - {id: 22, cat: Movies, desc: "Movies 2D to 3D Conv"}
-      - {id: 32, cat: Movies, desc: "Bluray MKV Remux"}
-      - {id: 23, cat: Movies, desc: "Movies Evo 3D"}
-      - {id: 21, cat: PC, desc: "3D Software"}
-      - {id: 2, cat: Audio, desc: "Music"}
-      - {id: 28, cat: XXX, desc: "Adult 720p"}
-      - {id: 29, cat: XXX, desc: "Adult 1080p"}
-      - {id: 30, cat: XXX, desc: "Adult Blu-ray"}
-      - {id: 31, cat: Other, desc: "Misc"}
-      - {id: 19, cat: Audio, desc: "Audio Packs"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: index.php?page=login&amp;returnto=index.php
-    method: form
-    form: form
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    captcha:
-      type: image
-      image: img.captcha
-      input: private_key
-    error:
-      - selector: span.errormsg
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: index.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      page: torrents
-      category: 0
-      3dformat: 0
-      active: 1
-    rows:
-      selector: table[cellspacing!="1"].lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
-    fields:
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      title:
-        remove: span
-        selector: td:nth-child(2)
-      download:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["index.php?page=torrent-details&id=", "download.php?id="]
-      details:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: td:nth-last-child(4)
-      seeders:
-        selector: td:nth-last-child(3)
-      # leechers:
-      #   selector: td:nth-last-child(2)
-      date:
-        selector: td:nth-last-child(5)
-        filters:
-          - name: dateparse
-            args: "02/01/2006"
-      downloadvolumefactor:
-        case:
-          img[title^="You get 50% off download count on this torrent"]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: 3dtorrents
+  name: 3D Torrents
+  description: "3D Movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.3dtorrents.org/
+
+  caps:
+    categorymappings:
+      - {id: 14, cat: Movies, desc: "Movies XviD"}
+      - {id: 34, cat: Movies, desc: "Movies UltraHD"}
+      - {id: 15, cat: Movies, desc: "Movies DVD-R"}
+      - {id: 11, cat: Movies, desc: "Movies 720p"}
+      - {id: 13, cat: Movies, desc: "Movies 1080p"}
+      - {id: 16, cat: Movies, desc: "Movies 3DTV"}
+      - {id: 17, cat: Movies, desc: "Movies Blu-ray"}
+      - {id: 27, cat: Movies, desc: "Movies BD25 Encode"}
+      - {id: 33, cat: Movies, desc: "Movies BD9 AVCHD"}
+      - {id: 22, cat: Movies, desc: "Movies 2D to 3D Conv"}
+      - {id: 32, cat: Movies, desc: "Bluray MKV Remux"}
+      - {id: 23, cat: Movies, desc: "Movies Evo 3D"}
+      - {id: 21, cat: PC, desc: "3D Software"}
+      - {id: 2, cat: Audio, desc: "Music"}
+      - {id: 28, cat: XXX, desc: "Adult 720p"}
+      - {id: 29, cat: XXX, desc: "Adult 1080p"}
+      - {id: 30, cat: XXX, desc: "Adult Blu-ray"}
+      - {id: 31, cat: Other, desc: "Misc"}
+      - {id: 19, cat: Audio, desc: "Audio Packs"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: index.php?page=login&amp;returnto=index.php
+    method: form
+    form: form
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    captcha:
+      type: image
+      image: img.captcha
+      input: private_key
+    error:
+      - selector: span.errormsg
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: index.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      page: torrents
+      category: 0
+      3dformat: 0
+      active: 1
+    rows:
+      selector: table[cellspacing!="1"].lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
+    fields:
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      title:
+        remove: span
+        selector: td:nth-child(2)
+      download:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["index.php?page=torrent-details&id=", "download.php?id="]
+      details:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: td:nth-last-child(4)
+      seeders:
+        selector: td:nth-last-child(3)
+      # leechers:
+      #   selector: td:nth-last-child(2)
+      date:
+        selector: td:nth-last-child(5)
+        filters:
+          - name: dateparse
+            args: "02/01/2006"
+      downloadvolumefactor:
+        case:
+          img[title^="You get 50% off download count on this torrent"]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/aox.yml b/src/Jackett/Definitions/aox.yml
index 56c87954e8f6ba21f40f2bf00196cf29888bbf80..149ca5f1e109fe652f187963dac9f87b3675e1c7 100644
--- a/src/Jackett/Definitions/aox.yml
+++ b/src/Jackett/Definitions/aox.yml
@@ -1,124 +1,124 @@
----
-  site: aox
-  name: AOX
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://aox.to/
-
-  caps:
-    categorymappings:
-      # Japanese
-      - {id: 1, cat: Movies, desc: "jMovies"}
-      - {id: 2, cat: TV, desc: "TV Shows"}
-      - {id: 3, cat: TV/Other, desc: "Variety Shows"}
-
-      # Korean
-      - {id: 6, cat: Movies, desc: "kMovies"}
-      - {id: 4, cat: TV, desc: "TV Shows"}
-      - {id: 14, cat: TV/Other, desc: "Variety Shows"}
-
-      # Chinese
-      - {id: 8, cat: Movies, desc: "cMovies"}
-      - {id: 9, cat: TV, desc: "TV Shows"}
-      - {id: 13, cat: TV/Other, desc: "Variety Shows"}
-      
-      # Adult
-      - {id: 13, cat: XXX, desc: "Adult"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: index.php?page=login
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    error:
-      - selector: body[onLoad^="makeAlert('"]
-        message:
-          selector: body[onLoad^="makeAlert('"]
-          attribute: onLoad
-          filters:
-            - name: replace
-              args: ["makeAlert('Error' , '", ""]
-            - name: replace
-              args: ["');", ""]
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-
-  search:
-    path: index.php
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      page: "torrents"
-      category: "{{range .Categories}}{{.}};{{end}}"
-      options: "0"
-      active: "0"
-    rows:
-      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
-    fields:
-      download:
-        selector: a[href^="index.php?page=downloadcheck&id="]
-        attribute: href
-      title:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-      banner:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "src=(.*?) "
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: td:nth-child(12)
-      date:
-        selector: td:nth-child(7)
-        filters:
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02/01/2006 -07:00"
-      grabs:
-        selector: td:nth-child(10)
-        filters:
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      downloadvolumefactor:
-        case:
-          img[alt="Full Star 100% Free"]: "0"
-          img[alt="Half Star 50% Free"]: "0.5"
-          img[alt="Empty Star 25% Free"]: "0.75"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a
-      description|append:
-        selector: td:nth-child(3) > img
-        attribute: title
-        filters:
-          - name: prepend
-            args: "<br>Language: "
-        
+---
+  site: aox
+  name: AOX
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://aox.to/
+
+  caps:
+    categorymappings:
+      # Japanese
+      - {id: 1, cat: Movies, desc: "jMovies"}
+      - {id: 2, cat: TV, desc: "TV Shows"}
+      - {id: 3, cat: TV/Other, desc: "Variety Shows"}
+
+      # Korean
+      - {id: 6, cat: Movies, desc: "kMovies"}
+      - {id: 4, cat: TV, desc: "TV Shows"}
+      - {id: 14, cat: TV/Other, desc: "Variety Shows"}
+
+      # Chinese
+      - {id: 8, cat: Movies, desc: "cMovies"}
+      - {id: 9, cat: TV, desc: "TV Shows"}
+      - {id: 13, cat: TV/Other, desc: "Variety Shows"}
+      
+      # Adult
+      - {id: 13, cat: XXX, desc: "Adult"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: index.php?page=login
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    error:
+      - selector: body[onLoad^="makeAlert('"]
+        message:
+          selector: body[onLoad^="makeAlert('"]
+          attribute: onLoad
+          filters:
+            - name: replace
+              args: ["makeAlert('Error' , '", ""]
+            - name: replace
+              args: ["');", ""]
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+
+  search:
+    path: index.php
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      page: "torrents"
+      category: "{{range .Categories}}{{.}};{{end}}"
+      options: "0"
+      active: "0"
+    rows:
+      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
+    fields:
+      download:
+        selector: a[href^="index.php?page=downloadcheck&id="]
+        attribute: href
+      title:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+      banner:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "src=(.*?) "
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: td:nth-child(12)
+      date:
+        selector: td:nth-child(7)
+        filters:
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02/01/2006 -07:00"
+      grabs:
+        selector: td:nth-child(10)
+        filters:
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      downloadvolumefactor:
+        case:
+          img[alt="Full Star 100% Free"]: "0"
+          img[alt="Half Star 50% Free"]: "0.5"
+          img[alt="Empty Star 25% Free"]: "0.75"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a
+      description|append:
+        selector: td:nth-child(3) > img
+        attribute: title
+        filters:
+          - name: prepend
+            args: "<br>Language: "
+        
         
\ No newline at end of file
diff --git a/src/Jackett/Definitions/apollo.yml b/src/Jackett/Definitions/apollo.yml
index 88bf3a4cbee4381ba8e16ff2c3ce6ec9c3a8cf15..80a76cf4a9e9ac003e2515ead36d1fd2257fd5e7 100644
--- a/src/Jackett/Definitions/apollo.yml
+++ b/src/Jackett/Definitions/apollo.yml
@@ -1,95 +1,95 @@
----
-  site: apollo
-  name: Apollo
-  description: "A music tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://apollo.rip
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Audio, desc: "Music"}
-      - {id: 2, cat: PC, desc: "Applications"}
-      - {id: 3, cat: Books, desc: "E-Books"}
-      - {id: 4, cat: Audio/Audiobook, desc: "Audiobooks"}
-      - {id: 5, cat: Movies, desc: "E-Learning Videos"}
-      - {id: 6, cat: TV, desc: "Comedy"}
-      - {id: 7, cat: Books/Comics, desc: "Comics"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: 1
-      login: "Log in"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: torrents.php
-
-  ratio:
-    path: torrents.php
-    selector: li#stats_ratio > span
-
-  search:
-    path: torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: time
-      order_way: desc
-      action: basic
-      searchsubmit: 1
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      description:
-        selector: div.group_info
-        remove: span
-      title:
-        selector: div.group_info
-        remove: span, div.tags
-      category:
-        selector: td.cats_col
-        case:
-          div.cats_music: 1
-          div.cats_applications: 2
-          div.cats_ebooks: 3
-          div.cats_audiobooks: 4
-          div.cats_elearningvideos: 5
-          div.cats_comedy: 6
-          div.cats_comics: 7
-      comments:
-        selector: a[href^="torrents.php?id="]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          ":root div.alertbar:contains(\"freeleech\")": "0"
-          ":root div.alertbar:contains(\"FREELEECH\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: apollo
+  name: Apollo
+  description: "A music tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://apollo.rip
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Audio, desc: "Music"}
+      - {id: 2, cat: PC, desc: "Applications"}
+      - {id: 3, cat: Books, desc: "E-Books"}
+      - {id: 4, cat: Audio/Audiobook, desc: "Audiobooks"}
+      - {id: 5, cat: Movies, desc: "E-Learning Videos"}
+      - {id: 6, cat: TV, desc: "Comedy"}
+      - {id: 7, cat: Books/Comics, desc: "Comics"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: 1
+      login: "Log in"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: torrents.php
+
+  ratio:
+    path: torrents.php
+    selector: li#stats_ratio > span
+
+  search:
+    path: torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: time
+      order_way: desc
+      action: basic
+      searchsubmit: 1
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      description:
+        selector: div.group_info
+        remove: span
+      title:
+        selector: div.group_info
+        remove: span, div.tags
+      category:
+        selector: td.cats_col
+        case:
+          div.cats_music: 1
+          div.cats_applications: 2
+          div.cats_ebooks: 3
+          div.cats_audiobooks: 4
+          div.cats_elearningvideos: 5
+          div.cats_comedy: 6
+          div.cats_comics: 7
+      comments:
+        selector: a[href^="torrents.php?id="]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          ":root div.alertbar:contains(\"freeleech\")": "0"
+          ":root div.alertbar:contains(\"FREELEECH\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/arabafenice.yml b/src/Jackett/Definitions/arabafenice.yml
index 75a532d59e38cbd13ecd17adae4083460e217842..5f9e7e880e9fe47c78ecdf7d1e3f404bbf64e304 100644
--- a/src/Jackett/Definitions/arabafenice.yml
+++ b/src/Jackett/Definitions/arabafenice.yml
@@ -1,164 +1,164 @@
----
-  site: arabafenice
-  name: ArabaFenice
-  language: it-it
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.arabafenice.me/
-
-  caps:
-    categorymappings:
-      # HRS
-      - {id: 34, cat: Movies/HD, desc: "1080p HRS x264"}
-      - {id: 47, cat: Movies/HD, desc: "2160p 4k UltraHD HRS"}
-      - {id: 35, cat: TV, desc: "Serie TV HRS"}
-      - {id: 36, cat: Movies/SD, desc: "DVDRip HRS"}
-      - {id: 41, cat: Movies/SD, desc: "BDRip 576p HRS"}
-      - {id: 39, cat: Movies/HD, desc: "1080p HRS x265 HEVC"}
-
-      # VIDEO
-      - {id: 1, cat: Movies, desc: "News Cinema"}
-      - {id: 2, cat: Movies/SD, desc: "BD-DVDRip"}
-      - {id: 3, cat: Movies/DVD, desc: "DVD 5"}
-      - {id: 5, cat: Movies/DVD, desc: "DVD 9"}
-      - {id: 6, cat: Movies/BluRay, desc: "BluRay Full"}
-      - {id: 4, cat: Movies/HD, desc: "1080p 3D x264"}
-      - {id: 7, cat: Movies/HD, desc: "1080p x264"}
-      - {id: 46, cat: Movies/HD, desc: "1080p Video Untouch"}
-      - {id: 44, cat: Movies/HD, desc: "1080p x265"}
-      - {id: 9, cat: TV/Anime, desc: "Cartoons"}
-      - {id: 8, cat: TV/Anime, desc: "720p x264"}
-      - {id: 12, cat: TV, desc: "He concluded seasons"}
-      - {id: 13, cat: TV, desc: "Seasons in Onda"}
-      - {id: 14, cat: TV, desc: "TV Show"}
-      - {id: 42, cat: TV, desc: "Serie Tv Sub Ita"}
-      - {id: 15, cat: TV/Documentary, desc: "documentaries"}
-      - {id: 33, cat: TV, desc: "mp4"}
-      - {id: 40, cat: TV/HD, desc: "2160p 4K UltraHD"}
-      - {id: 38, cat: XXX, desc: "xXx"}
-      - {id: 43, cat: Other, desc: "Arabic for social"}
-
-      # MUSICA
-      - {id: 17, cat: Audio, desc: "Italian music"}
-      - {id: 45, cat: Audio, desc: "Discography"}
-      - {id: 18, cat: Audio, desc: "MusicaInternazionale"}
-      - {id: 19, cat: Audio, desc: "Compilation"}
-
-      # PDF
-      - {id: 21, cat: Books, desc: "Ebook"}
-      - {id: 22, cat: Books/Comics, desc: "Comics"}
-      - {id: 23, cat: Books, desc: "Newsstand"}
-
-      # GAMES
-      - {id: 25, cat: Console/PS4, desc: "Sony Games"}
-      - {id: 26, cat: Console/Xbox, desc: "XboX Games"}
-      - {id: 27, cat: Console/Other, desc: "Nintendo Games"}
-      - {id: 28, cat: PC/Games, desc: "PC Games"}
-
-      # SOFTWARE
-      - {id: 30, cat: PC/ISO, desc: "Windows APP"}
-      - {id: 31, cat: PC/Phone-IOS, desc: "Apple APP"}
-      - {id: 32, cat: PC/Phone-Android, desc: "Android APP"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: index.php?page=login
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    error:
-      - selector: body[onLoad^="makeAlert('"]
-        message:
-          selector: body[onLoad^="makeAlert('"]
-          attribute: onLoad
-          filters:
-            - name: replace
-              args: ["makeAlert('Error' , '", ""]
-            - name: replace
-              args: ["');", ""]
-    test:
-      path: index.php
-
-  download:
-    before:
-      path: "thanks.php"
-      method: "post"
-      inputs:
-        infohash: "{{ .DownloadUri.Query.id }}"
-        thanks: "1"
-        rndval: "1487013827343"
-    selector: a[href^="download.php?id="]
-
-  search:
-    path: index.php
-    inputs:
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
-      page: "torrents"
-      category: "{{range .Categories}}{{.}};{{end}}"
-      options: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      active: "0"
-    rows:
-      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
-    fields:
-      download:
-        selector: a[href^="index.php?page=downloadcheck&id="]
-        attribute: href
-      title:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-      banner:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "src=(.*?) "
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: td:nth-last-child(4)
-      date:
-        selector: td:nth-last-child(9)
-        filters:
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02/01/2006 -07:00"
-      grabs:
-        selector: td:nth-last-child(6)
-        filters:
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: td:nth-last-child(8)
-      leechers:
-        selector: td:nth-last-child(7)
-      downloadvolumefactor:
-        case:
-          img[alt="Gold 100% Free"]: "0"
-          img[alt="Silver 50% Free"]: "0.5"
-          img[alt="Bronze 25% Free"]: "0.75"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt="2x Upload Multiplier"]: "2"
-          img[alt="3x Upload Multiplier"]: "3"
-          img[alt="4x Upload Multiplier"]: "4"
-          img[alt="5x Upload Multiplier"]: "5"
-          img[alt="6x Upload Multiplier"]: "6"
-          img[alt="7x Upload Multiplier"]: "7"
-          img[alt="8x Upload Multiplier"]: "8"
-          img[alt="9x Upload Multiplier"]: "9"
-          img[alt="10x Upload Multiplier"]: "10"
-          "*": "1"
+---
+  site: arabafenice
+  name: ArabaFenice
+  language: it-it
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.arabafenice.me/
+
+  caps:
+    categorymappings:
+      # HRS
+      - {id: 34, cat: Movies/HD, desc: "1080p HRS x264"}
+      - {id: 47, cat: Movies/HD, desc: "2160p 4k UltraHD HRS"}
+      - {id: 35, cat: TV, desc: "Serie TV HRS"}
+      - {id: 36, cat: Movies/SD, desc: "DVDRip HRS"}
+      - {id: 41, cat: Movies/SD, desc: "BDRip 576p HRS"}
+      - {id: 39, cat: Movies/HD, desc: "1080p HRS x265 HEVC"}
+
+      # VIDEO
+      - {id: 1, cat: Movies, desc: "News Cinema"}
+      - {id: 2, cat: Movies/SD, desc: "BD-DVDRip"}
+      - {id: 3, cat: Movies/DVD, desc: "DVD 5"}
+      - {id: 5, cat: Movies/DVD, desc: "DVD 9"}
+      - {id: 6, cat: Movies/BluRay, desc: "BluRay Full"}
+      - {id: 4, cat: Movies/HD, desc: "1080p 3D x264"}
+      - {id: 7, cat: Movies/HD, desc: "1080p x264"}
+      - {id: 46, cat: Movies/HD, desc: "1080p Video Untouch"}
+      - {id: 44, cat: Movies/HD, desc: "1080p x265"}
+      - {id: 9, cat: TV/Anime, desc: "Cartoons"}
+      - {id: 8, cat: TV/Anime, desc: "720p x264"}
+      - {id: 12, cat: TV, desc: "He concluded seasons"}
+      - {id: 13, cat: TV, desc: "Seasons in Onda"}
+      - {id: 14, cat: TV, desc: "TV Show"}
+      - {id: 42, cat: TV, desc: "Serie Tv Sub Ita"}
+      - {id: 15, cat: TV/Documentary, desc: "documentaries"}
+      - {id: 33, cat: TV, desc: "mp4"}
+      - {id: 40, cat: TV/HD, desc: "2160p 4K UltraHD"}
+      - {id: 38, cat: XXX, desc: "xXx"}
+      - {id: 43, cat: Other, desc: "Arabic for social"}
+
+      # MUSICA
+      - {id: 17, cat: Audio, desc: "Italian music"}
+      - {id: 45, cat: Audio, desc: "Discography"}
+      - {id: 18, cat: Audio, desc: "MusicaInternazionale"}
+      - {id: 19, cat: Audio, desc: "Compilation"}
+
+      # PDF
+      - {id: 21, cat: Books, desc: "Ebook"}
+      - {id: 22, cat: Books/Comics, desc: "Comics"}
+      - {id: 23, cat: Books, desc: "Newsstand"}
+
+      # GAMES
+      - {id: 25, cat: Console/PS4, desc: "Sony Games"}
+      - {id: 26, cat: Console/Xbox, desc: "XboX Games"}
+      - {id: 27, cat: Console/Other, desc: "Nintendo Games"}
+      - {id: 28, cat: PC/Games, desc: "PC Games"}
+
+      # SOFTWARE
+      - {id: 30, cat: PC/ISO, desc: "Windows APP"}
+      - {id: 31, cat: PC/Phone-IOS, desc: "Apple APP"}
+      - {id: 32, cat: PC/Phone-Android, desc: "Android APP"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: index.php?page=login
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    error:
+      - selector: body[onLoad^="makeAlert('"]
+        message:
+          selector: body[onLoad^="makeAlert('"]
+          attribute: onLoad
+          filters:
+            - name: replace
+              args: ["makeAlert('Error' , '", ""]
+            - name: replace
+              args: ["');", ""]
+    test:
+      path: index.php
+
+  download:
+    before:
+      path: "thanks.php"
+      method: "post"
+      inputs:
+        infohash: "{{ .DownloadUri.Query.id }}"
+        thanks: "1"
+        rndval: "1487013827343"
+    selector: a[href^="download.php?id="]
+
+  search:
+    path: index.php
+    inputs:
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
+      page: "torrents"
+      category: "{{range .Categories}}{{.}};{{end}}"
+      options: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      active: "0"
+    rows:
+      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
+    fields:
+      download:
+        selector: a[href^="index.php?page=downloadcheck&id="]
+        attribute: href
+      title:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+      banner:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "src=(.*?) "
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: td:nth-last-child(4)
+      date:
+        selector: td:nth-last-child(9)
+        filters:
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02/01/2006 -07:00"
+      grabs:
+        selector: td:nth-last-child(6)
+        filters:
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: td:nth-last-child(8)
+      leechers:
+        selector: td:nth-last-child(7)
+      downloadvolumefactor:
+        case:
+          img[alt="Gold 100% Free"]: "0"
+          img[alt="Silver 50% Free"]: "0.5"
+          img[alt="Bronze 25% Free"]: "0.75"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt="2x Upload Multiplier"]: "2"
+          img[alt="3x Upload Multiplier"]: "3"
+          img[alt="4x Upload Multiplier"]: "4"
+          img[alt="5x Upload Multiplier"]: "5"
+          img[alt="6x Upload Multiplier"]: "6"
+          img[alt="7x Upload Multiplier"]: "7"
+          img[alt="8x Upload Multiplier"]: "8"
+          img[alt="9x Upload Multiplier"]: "9"
+          img[alt="10x Upload Multiplier"]: "10"
+          "*": "1"
diff --git a/src/Jackett/Definitions/audiobooktorrents.yml b/src/Jackett/Definitions/audiobooktorrents.yml
index 5f9f8f78d8d44825c7290be10bf842a066791126..b7d1d28f74e2c09160b8a929d4b320110a675821 100644
--- a/src/Jackett/Definitions/audiobooktorrents.yml
+++ b/src/Jackett/Definitions/audiobooktorrents.yml
@@ -1,136 +1,136 @@
----
-  site: audiobooktorrents
-  name: Audiobook Torrents
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://abtorrents.me
-
-  caps:
-    categorymappings:
-      - {id: 10, cat: Audio/Audiobook, desc: "Adventure"}
-      - {id: 20, cat: Audio/Audiobook, desc: "Biographies & Memoirs"}
-      - {id: 30, cat: Audio/Audiobook, desc: "Business "}
-      - {id: 40, cat: Audio/Audiobook, desc: "Childrens"}
-      - {id: 50, cat: Audio/Audiobook, desc: "Comedy"}
-      - {id: 60, cat: Audio/Audiobook, desc: "Comics"}
-      - {id: 70, cat: Audio/Audiobook, desc: "Computers "}
-      - {id: 80, cat: Audio/Audiobook, desc: "Erotica"}
-      - {id: 90, cat: Audio/Audiobook, desc: "Fantasy-General"}
-      - {id: 100, cat: Audio/Audiobook, desc: "Fantasy-Youth"}
-      - {id: 110, cat: Audio/Audiobook, desc: "Files"}
-      - {id: 120, cat: Audio/Audiobook, desc: "Foreign Language"}
-      - {id: 130, cat: Audio/Audiobook, desc: "General Fiction"}
-      - {id: 140, cat: Audio/Audiobook, desc: "Historical Fiction"}
-      - {id: 150, cat: Audio/Audiobook, desc: "History"}
-      - {id: 160, cat: Audio/Audiobook, desc: "Horror"}
-      - {id: 170, cat: Audio/Audiobook, desc: "Literature "}
-      - {id: 180, cat: Audio/Audiobook, desc: "Mystery "}
-      - {id: 190, cat: Audio/Audiobook, desc: "Non-Fiction"}
-      - {id: 200, cat: Audio/Audiobook, desc: "Radio Drama"}
-      - {id: 210, cat: Audio/Audiobook, desc: "Romance"}
-      - {id: 235, cat: Audio/Audiobook, desc: "Sci-Fi Apocalypse"}
-      - {id: 220, cat: Audio/Audiobook, desc: "Science"}
-      - {id: 230, cat: Audio/Audiobook, desc: "Science Fiction "}
-      - {id: 240, cat: Audio/Audiobook, desc: "Self Improvement"}
-      - {id: 250, cat: Audio/Audiobook, desc: "Suspense"}
-      - {id: 260, cat: Audio/Audiobook, desc: "Talk Radio"}
-      - {id: 245, cat: Audio/Audiobook, desc: "Thriller"}
-      - {id: 270, cat: Audio/Audiobook, desc: "Urban Fantasy"}
-      - {id: 280, cat: Audio/Audiobook, desc: "Western"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      use_ssl: "1"
-      perm_ssl: "1"
-      submitme: "X"
-    error:
-      - selector: td.embedded:has(h2:contains("Oops"))
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /browse.php
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Keywords }}"
-      searchin: "title"
-      incldead: "1"
-    rows:
-      selector: tr.browse_color, tr.freeleech_color, tr[id^="kdescr"]
-      after: 1
-    fields:
-      banner:
-        selector: a[href^="details.php?id="][onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=\'(.*?)\'
-      title:
-        selector: a[href^="details.php?id="][onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: Tip\('<b>(.*?)</b>
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="][onmouseover]
-        attribute: href
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(7)
-      grabs:
-        selector: td:nth-child(8)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      date:
-        selector: td:nth-child(6)
-      downloadvolumefactor:
-        case:
-          "a.info > b:contains(\"[FREE]\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: a[href^="details.php?id="][onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: <br /><b>(.*?)</b><br />
-      description:
-        selector: td:nth-child(2) > i
-        optional: true
-        filters:
-          - name: prepend
-            args: "{{ .Result.description }}<br>\n"
-      description:
-        selector: td[colspan=13]
-        filters:
-          - name: prepend
+---
+  site: audiobooktorrents
+  name: Audiobook Torrents
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://abtorrents.me
+
+  caps:
+    categorymappings:
+      - {id: 10, cat: Audio/Audiobook, desc: "Adventure"}
+      - {id: 20, cat: Audio/Audiobook, desc: "Biographies & Memoirs"}
+      - {id: 30, cat: Audio/Audiobook, desc: "Business "}
+      - {id: 40, cat: Audio/Audiobook, desc: "Childrens"}
+      - {id: 50, cat: Audio/Audiobook, desc: "Comedy"}
+      - {id: 60, cat: Audio/Audiobook, desc: "Comics"}
+      - {id: 70, cat: Audio/Audiobook, desc: "Computers "}
+      - {id: 80, cat: Audio/Audiobook, desc: "Erotica"}
+      - {id: 90, cat: Audio/Audiobook, desc: "Fantasy-General"}
+      - {id: 100, cat: Audio/Audiobook, desc: "Fantasy-Youth"}
+      - {id: 110, cat: Audio/Audiobook, desc: "Files"}
+      - {id: 120, cat: Audio/Audiobook, desc: "Foreign Language"}
+      - {id: 130, cat: Audio/Audiobook, desc: "General Fiction"}
+      - {id: 140, cat: Audio/Audiobook, desc: "Historical Fiction"}
+      - {id: 150, cat: Audio/Audiobook, desc: "History"}
+      - {id: 160, cat: Audio/Audiobook, desc: "Horror"}
+      - {id: 170, cat: Audio/Audiobook, desc: "Literature "}
+      - {id: 180, cat: Audio/Audiobook, desc: "Mystery "}
+      - {id: 190, cat: Audio/Audiobook, desc: "Non-Fiction"}
+      - {id: 200, cat: Audio/Audiobook, desc: "Radio Drama"}
+      - {id: 210, cat: Audio/Audiobook, desc: "Romance"}
+      - {id: 235, cat: Audio/Audiobook, desc: "Sci-Fi Apocalypse"}
+      - {id: 220, cat: Audio/Audiobook, desc: "Science"}
+      - {id: 230, cat: Audio/Audiobook, desc: "Science Fiction "}
+      - {id: 240, cat: Audio/Audiobook, desc: "Self Improvement"}
+      - {id: 250, cat: Audio/Audiobook, desc: "Suspense"}
+      - {id: 260, cat: Audio/Audiobook, desc: "Talk Radio"}
+      - {id: 245, cat: Audio/Audiobook, desc: "Thriller"}
+      - {id: 270, cat: Audio/Audiobook, desc: "Urban Fantasy"}
+      - {id: 280, cat: Audio/Audiobook, desc: "Western"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      use_ssl: "1"
+      perm_ssl: "1"
+      submitme: "X"
+    error:
+      - selector: td.embedded:has(h2:contains("Oops"))
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /browse.php
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Keywords }}"
+      searchin: "title"
+      incldead: "1"
+    rows:
+      selector: tr.browse_color, tr.freeleech_color, tr[id^="kdescr"]
+      after: 1
+    fields:
+      banner:
+        selector: a[href^="details.php?id="][onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=\'(.*?)\'
+      title:
+        selector: a[href^="details.php?id="][onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: Tip\('<b>(.*?)</b>
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="][onmouseover]
+        attribute: href
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(7)
+      grabs:
+        selector: td:nth-child(8)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      date:
+        selector: td:nth-child(6)
+      downloadvolumefactor:
+        case:
+          "a.info > b:contains(\"[FREE]\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: a[href^="details.php?id="][onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: <br /><b>(.*?)</b><br />
+      description:
+        selector: td:nth-child(2) > i
+        optional: true
+        filters:
+          - name: prepend
+            args: "{{ .Result.description }}<br>\n"
+      description:
+        selector: td[colspan=13]
+        filters:
+          - name: prepend
             args: "{{ .Result.description }}<br>\n"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/bigtorrent.yml b/src/Jackett/Definitions/bigtorrent.yml
index 9072de84989caa231da0ac05e2581eae092fa4e4..c6a463b45839f92c7d75d63b8298ea34939d9ce7 100644
--- a/src/Jackett/Definitions/bigtorrent.yml
+++ b/src/Jackett/Definitions/bigtorrent.yml
@@ -1,97 +1,97 @@
----
-  site: bigtorrent
-  name: BIGTorrent
-  description: "ratio-free Hungarian tracker"
-  language: hu
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.bigtorrent.eu/
-
-  caps:
-    categorymappings:
-      - {id: 24533, cat: Movies/3D, desc: "3D"}
-      - {id: 47, cat: Other, desc: "Other"}
-      - {id: 24541, cat: Movies/DVD, desc: "Film DVD English"}
-      - {id: 24540, cat: Movies/DVD, desc: "Film DVD Hungarian"}
-      - {id: 24539, cat: Movies/HD, desc: "Film HD English"}
-      - {id: 24538, cat: Movies/HD, desc: "Film HD Hungarian"}
-      - {id: 24537, cat: Movies/SD, desc: "Film SD English"}
-      - {id: 24536, cat: Movies/SD, desc: "Film SD Hungarian"}
-      - {id: 69, cat: PC/Games, desc: "Games ISO"}
-      - {id: 67, cat: PC/Games, desc: "Games Rip"}
-      - {id: 24534, cat: Audio/Audiobook, desc: "Audiobooks"}
-      - {id: 65, cat: Other, desc: "Picture"}
-      - {id: 64, cat: Other, desc: "Video"}
-      - {id: 68, cat: Console/Xbox360, desc: "Video Game Console"}
-      - {id: 63, cat: Books, desc: "English Books"}
-      - {id: 62, cat: Books, desc: "Hungarian Books"}
-      - {id: 74, cat: Audio/Lossless, desc: "Lossless"}
-      - {id: 56, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 57, cat: PC, desc: "Programs"}
-      - {id: 24545, cat: TV/HD, desc: "English HD Series"}
-      - {id: 24544, cat: TV/HD, desc: "Hungarian HD Series"}
-      - {id: 24543, cat: TV/SD, desc: "English SD Series"}
-      - {id: 24542, cat: TV/SD, desc: "Hungarian SD Series"}
-      - {id: 24535, cat: XXX, desc: "XXX"}
-      - {id: 59, cat: Audio, desc: "Music"}
-      - {id: 58, cat: Audio, desc: "Hungarian Music"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: /login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      sent: "yes"
-      returnto: "/"
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table#torrent_table > tbody > tr:has(a[href^="browse.php?cat="])
-    fields:
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      title:
-        selector: td:nth-child(2) a
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      size:
-        selector: td:nth-child(7)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      date:
-        selector: td:nth-child(4)
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: bigtorrent
+  name: BIGTorrent
+  description: "ratio-free Hungarian tracker"
+  language: hu
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.bigtorrent.eu/
+
+  caps:
+    categorymappings:
+      - {id: 24533, cat: Movies/3D, desc: "3D"}
+      - {id: 47, cat: Other, desc: "Other"}
+      - {id: 24541, cat: Movies/DVD, desc: "Film DVD English"}
+      - {id: 24540, cat: Movies/DVD, desc: "Film DVD Hungarian"}
+      - {id: 24539, cat: Movies/HD, desc: "Film HD English"}
+      - {id: 24538, cat: Movies/HD, desc: "Film HD Hungarian"}
+      - {id: 24537, cat: Movies/SD, desc: "Film SD English"}
+      - {id: 24536, cat: Movies/SD, desc: "Film SD Hungarian"}
+      - {id: 69, cat: PC/Games, desc: "Games ISO"}
+      - {id: 67, cat: PC/Games, desc: "Games Rip"}
+      - {id: 24534, cat: Audio/Audiobook, desc: "Audiobooks"}
+      - {id: 65, cat: Other, desc: "Picture"}
+      - {id: 64, cat: Other, desc: "Video"}
+      - {id: 68, cat: Console/Xbox360, desc: "Video Game Console"}
+      - {id: 63, cat: Books, desc: "English Books"}
+      - {id: 62, cat: Books, desc: "Hungarian Books"}
+      - {id: 74, cat: Audio/Lossless, desc: "Lossless"}
+      - {id: 56, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 57, cat: PC, desc: "Programs"}
+      - {id: 24545, cat: TV/HD, desc: "English HD Series"}
+      - {id: 24544, cat: TV/HD, desc: "Hungarian HD Series"}
+      - {id: 24543, cat: TV/SD, desc: "English SD Series"}
+      - {id: 24542, cat: TV/SD, desc: "Hungarian SD Series"}
+      - {id: 24535, cat: XXX, desc: "XXX"}
+      - {id: 59, cat: Audio, desc: "Music"}
+      - {id: 58, cat: Audio, desc: "Hungarian Music"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: /login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      sent: "yes"
+      returnto: "/"
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table#torrent_table > tbody > tr:has(a[href^="browse.php?cat="])
+    fields:
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      title:
+        selector: td:nth-child(2) a
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      size:
+        selector: td:nth-child(7)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      date:
+        selector: td:nth-child(4)
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/bitspyder.yml b/src/Jackett/Definitions/bitspyder.yml
index 4594b9a5d88b00b44322604496cbbba6963514e0..4dd210d681ddf5ac5ab2e6cd7e77b9abae54f247 100755
--- a/src/Jackett/Definitions/bitspyder.yml
+++ b/src/Jackett/Definitions/bitspyder.yml
@@ -1,133 +1,133 @@
----
-  site: bitspyder
-  name: Bitspyder
-  language: en-us
-  type: private
-  encoding: windows-1252
-  links:
-    - http://bitspyder.net/
-
-  caps:
-    categorymappings:
-      - {id: 61, cat: Books, desc: "3D"}
-      - {id: 69, cat: Books, desc: "Anim|GFX"}
-      - {id: 56, cat: Books, desc: "Art"}
-      - {id: 40, cat: Audio/Audiobook, desc: "Audio Books"}
-      - {id: 55, cat: Books, desc: "Business"}
-      - {id: 46, cat: Books, desc: "Career"}
-      - {id: 2, cat: Books, desc: "CBTs"}
-      - {id: 39, cat: Books, desc: "Cert QA"}
-      - {id: 63, cat: Books, desc: "College"}
-      - {id: 53, cat: Books, desc: "Cooking"}
-      - {id: 42, cat: Books, desc: "Documentary"}
-      - {id: 37, cat: Books, desc: "e-Books"}
-      - {id: 65, cat: Books, desc: "Engineering"}
-      - {id: 54, cat: Books, desc: "Health-Fitness"}
-      - {id: 64, cat: Books, desc: "Kids"}
-      - {id: 47, cat: Books, desc: "Languages"}
-      - {id: 49, cat: Books, desc: "Linux CBTs"}
-      - {id: 43, cat: Books, desc: "Lynda.com"}
-      - {id: 57, cat: Books/Magazines, desc: "Magazines"}
-      - {id: 71, cat: Books, desc: "Magic"}
-      - {id: 60, cat: Books, desc: "Medical"}
-      - {id: 44, cat: Books, desc: "Misc Learning"}
-      - {id: 51, cat: Books, desc: "Music Learning"}
-      - {id: 41, cat: Books, desc: "Others"}
-      - {id: 52, cat: Books, desc: "Photography"}
-      - {id: 35, cat: Books, desc: "PPT 'n Docs"}
-      - {id: 38, cat: Books, desc: "Religion"}
-      - {id: 68, cat: Books, desc: "Self Growth"}
-      - {id: 72, cat: Books, desc: "Templates"}
-      - {id: 58, cat: Books, desc: "Total Training"}
-      - {id: 45, cat: Books, desc: "Trainsignal"}
-      - {id: 59, cat: Books, desc: "VTC"}
-
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: processid.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.msg_info > font > b
-    test:
-      path: /browse.php
-
-  search:
-    path: /browse.php
-    method: post
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-    rows:
-      selector: table > tbody > tr[class]
-      filters:
-        - name: andmatch
-    fields:
-      # there are two styles, we support both
-      title:
-        selector: a[href^="details.php?id="]
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php/"]
-          - name: replace
-            args: ["&hit=1", "/dummy.torrent"]
-      size:
-        selector: td.rowcol:nth-child(6):has(br), font:contains("Size:") + font
-      files:
-        selector: a[href*="&filelist=1"]
-      grabs:
-        selector: td.rowcol:nth-child(7):has(br)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      seeders:
-        selector: td.rowcol:nth-last-child(3)
-      leechers:
-        selector: td.rowcol:nth-last-child(2)
-      date|optional|1:
-        selector: font[color="5F5F5F"]
-        filters:
-          - name: split
-            args: [" (", 0]
-          - name: replace
-            args: ["\xA0", " "]
-          - name: append
-            args: " +00:00"
-          - name: dateparse 
-            args: "2006-01-02 15:04:05 -07:00"
-      date|optional|2:
-        selector: a[title^="Upploaded at"]
-        attribute: title
-        filters:
-          - name: replace
-            args: ["Upploaded at - ", ""]
-          - name: append
-            args: " +00:00"
-          - name: dateparse 
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description|optional:
-        selector: font[color="#990000"]
+---
+  site: bitspyder
+  name: Bitspyder
+  language: en-us
+  type: private
+  encoding: windows-1252
+  links:
+    - http://bitspyder.net/
+
+  caps:
+    categorymappings:
+      - {id: 61, cat: Books, desc: "3D"}
+      - {id: 69, cat: Books, desc: "Anim|GFX"}
+      - {id: 56, cat: Books, desc: "Art"}
+      - {id: 40, cat: Audio/Audiobook, desc: "Audio Books"}
+      - {id: 55, cat: Books, desc: "Business"}
+      - {id: 46, cat: Books, desc: "Career"}
+      - {id: 2, cat: Books, desc: "CBTs"}
+      - {id: 39, cat: Books, desc: "Cert QA"}
+      - {id: 63, cat: Books, desc: "College"}
+      - {id: 53, cat: Books, desc: "Cooking"}
+      - {id: 42, cat: Books, desc: "Documentary"}
+      - {id: 37, cat: Books, desc: "e-Books"}
+      - {id: 65, cat: Books, desc: "Engineering"}
+      - {id: 54, cat: Books, desc: "Health-Fitness"}
+      - {id: 64, cat: Books, desc: "Kids"}
+      - {id: 47, cat: Books, desc: "Languages"}
+      - {id: 49, cat: Books, desc: "Linux CBTs"}
+      - {id: 43, cat: Books, desc: "Lynda.com"}
+      - {id: 57, cat: Books/Magazines, desc: "Magazines"}
+      - {id: 71, cat: Books, desc: "Magic"}
+      - {id: 60, cat: Books, desc: "Medical"}
+      - {id: 44, cat: Books, desc: "Misc Learning"}
+      - {id: 51, cat: Books, desc: "Music Learning"}
+      - {id: 41, cat: Books, desc: "Others"}
+      - {id: 52, cat: Books, desc: "Photography"}
+      - {id: 35, cat: Books, desc: "PPT 'n Docs"}
+      - {id: 38, cat: Books, desc: "Religion"}
+      - {id: 68, cat: Books, desc: "Self Growth"}
+      - {id: 72, cat: Books, desc: "Templates"}
+      - {id: 58, cat: Books, desc: "Total Training"}
+      - {id: 45, cat: Books, desc: "Trainsignal"}
+      - {id: 59, cat: Books, desc: "VTC"}
+
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: processid.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.msg_info > font > b
+    test:
+      path: /browse.php
+
+  search:
+    path: /browse.php
+    method: post
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+    rows:
+      selector: table > tbody > tr[class]
+      filters:
+        - name: andmatch
+    fields:
+      # there are two styles, we support both
+      title:
+        selector: a[href^="details.php?id="]
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php/"]
+          - name: replace
+            args: ["&hit=1", "/dummy.torrent"]
+      size:
+        selector: td.rowcol:nth-child(6):has(br), font:contains("Size:") + font
+      files:
+        selector: a[href*="&filelist=1"]
+      grabs:
+        selector: td.rowcol:nth-child(7):has(br)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      seeders:
+        selector: td.rowcol:nth-last-child(3)
+      leechers:
+        selector: td.rowcol:nth-last-child(2)
+      date|optional|1:
+        selector: font[color="5F5F5F"]
+        filters:
+          - name: split
+            args: [" (", 0]
+          - name: replace
+            args: ["\xA0", " "]
+          - name: append
+            args: " +00:00"
+          - name: dateparse 
+            args: "2006-01-02 15:04:05 -07:00"
+      date|optional|2:
+        selector: a[title^="Upploaded at"]
+        attribute: title
+        filters:
+          - name: replace
+            args: ["Upploaded at - ", ""]
+          - name: append
+            args: " +00:00"
+          - name: dateparse 
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description|optional:
+        selector: font[color="#990000"]
diff --git a/src/Jackett/Definitions/blubits.yml b/src/Jackett/Definitions/blubits.yml
index 98ae2ec981836f8a9bb22e49105e104c36986a2d..92802625f7e8a1a70d7c2cb67cbee6a994761e6d 100644
--- a/src/Jackett/Definitions/blubits.yml
+++ b/src/Jackett/Definitions/blubits.yml
@@ -1,148 +1,148 @@
----
-  site: blubits
-  name: Blu-bits
-  description: "A HD tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://blu-bits.com/
-
-  caps:
-    categorymappings:
-      # Movies
-      - {id: 14, cat: Movies/BluRay, desc: "Full Blu-ray"}
-      - {id: 54, cat: Movies/HD, desc: "HD-DVD"}
-      - {id: 16, cat: Movies/HD, desc: "Remux"}
-      - {id: 55, cat: Movies/HD, desc: "2160p"}
-      - {id: 15, cat: Movies/HD, desc: "1080p"}
-      - {id: 19, cat: Movies/HD, desc: "1080i"}
-      - {id: 18, cat: Movies/HD, desc: "720p"}
-
-      # Documentaries
-      - {id: 21, cat: Movies/BluRay, desc: "Full Blu-ray"}
-      - {id: 39, cat: Movies/HD, desc: "Remux"}
-      - {id: 56, cat: Movies/HD, desc: "2160p"}
-      - {id: 23, cat: Movies/HD, desc: "1080p"}
-      - {id: 24, cat: Movies/HD, desc: "1080i"}
-      - {id: 25, cat: Movies/HD, desc: "720p"}
-
-      # TV Series
-      - {id: 27, cat: TV/HD, desc: "Full Blu-ray"}
-      - {id: 40, cat: TV/HD, desc: "Remux"}
-      - {id: 28, cat: TV/HD, desc: "1080p"}
-      - {id: 29, cat: TV/HD, desc: "1080i"}
-      - {id: 30, cat: TV/HD, desc: "720p"}
-
-      # HDTV
-      - {id: 35, cat: TV/HD, desc: "1080i"}
-      - {id: 36, cat: TV/HD, desc: "720p"}
-
-      # XXX
-      - {id: 59, cat: XXX, desc: "Full Blu-ray"}
-      - {id: 46, cat: XXX, desc: "1080p"}
-      - {id: 51, cat: XXX, desc: "720p"}
-
-      # Music
-      - {id: 53, cat: Audio/Video, desc: "Full Blu-ray"}
-      - {id: 57, cat: Audio/Video, desc: "Remux"}
-      - {id: 45, cat: Audio/Video, desc: "1080p"}
-      - {id: 58, cat: Audio/Video, desc: "720p"}
-      - {id: 38, cat: Audio/Lossless, desc: "Flac"}
-
-      - {id: 41, cat: TV/Sport, desc: "Sports"}
-      - {id: 42, cat: TV/Anime, desc: "Anime"}
-      - {id: 44, cat: PC, desc: "Windows Apps"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: index.php?page=login
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    error:
-      - selector: table.lista > tbody > tr > td.lista > span[style="color:#FF0000;"]
-    test:
-      path: index.php
-      selector: ul#navlist
-
-  ratio:
-    path: index.php
-    selector: "ul#navlist > li:contains(\"Ratio: \")"
-    filters:
-      - name: split
-        args: ["\u00a0", 1]
-      - name: replace
-        args: ["---", "0"]
-
-  search:
-    path: index.php
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      page: torrents
-      options: 0
-      active: 0
-    rows:
-      selector: div.b-content > table.lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: title
-        filters:
-          - name: replace
-            args: ["View details: ", ""]
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      comments:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: p
-        filters:
-          - name: replace
-            args: ["\u00a0", ""]
-          - name: regexp
-            args: "\\|\\s+Size:\\s+([\\w\\d\\.,]+ \\w\\w)\\s+\\|"
-      date:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "<center>Added:(.*?)</center>"
-      grabs:
-        selector: a[href^="index.php?page=torrent_history&id="]
-        filters:
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: a[title="Click here to view peers details"]:nth-child(1)
-      leechers:
-        selector: a[title="Click here to view peers details"]:nth-child(2)
-      downloadvolumefactor:
-        case:
-          img[alt="gold"]: "0"
-          img[alt="silver"]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt="2x Upload Multiplier"]: "2"
-          img[alt="3x Upload Multiplier"]: "3"
-          img[alt="4x Upload Multiplier"]: "4"
-          img[alt="5x Upload Multiplier"]: "5"
-          img[alt="6x Upload Multiplier"]: "6"
-          img[alt="7x Upload Multiplier"]: "7"
-          img[alt="8x Upload Multiplier"]: "8"
-          img[alt="9x Upload Multiplier"]: "9"
-          img[alt="10x Upload Multiplier"]: "10"
+---
+  site: blubits
+  name: Blu-bits
+  description: "A HD tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://blu-bits.com/
+
+  caps:
+    categorymappings:
+      # Movies
+      - {id: 14, cat: Movies/BluRay, desc: "Full Blu-ray"}
+      - {id: 54, cat: Movies/HD, desc: "HD-DVD"}
+      - {id: 16, cat: Movies/HD, desc: "Remux"}
+      - {id: 55, cat: Movies/HD, desc: "2160p"}
+      - {id: 15, cat: Movies/HD, desc: "1080p"}
+      - {id: 19, cat: Movies/HD, desc: "1080i"}
+      - {id: 18, cat: Movies/HD, desc: "720p"}
+
+      # Documentaries
+      - {id: 21, cat: Movies/BluRay, desc: "Full Blu-ray"}
+      - {id: 39, cat: Movies/HD, desc: "Remux"}
+      - {id: 56, cat: Movies/HD, desc: "2160p"}
+      - {id: 23, cat: Movies/HD, desc: "1080p"}
+      - {id: 24, cat: Movies/HD, desc: "1080i"}
+      - {id: 25, cat: Movies/HD, desc: "720p"}
+
+      # TV Series
+      - {id: 27, cat: TV/HD, desc: "Full Blu-ray"}
+      - {id: 40, cat: TV/HD, desc: "Remux"}
+      - {id: 28, cat: TV/HD, desc: "1080p"}
+      - {id: 29, cat: TV/HD, desc: "1080i"}
+      - {id: 30, cat: TV/HD, desc: "720p"}
+
+      # HDTV
+      - {id: 35, cat: TV/HD, desc: "1080i"}
+      - {id: 36, cat: TV/HD, desc: "720p"}
+
+      # XXX
+      - {id: 59, cat: XXX, desc: "Full Blu-ray"}
+      - {id: 46, cat: XXX, desc: "1080p"}
+      - {id: 51, cat: XXX, desc: "720p"}
+
+      # Music
+      - {id: 53, cat: Audio/Video, desc: "Full Blu-ray"}
+      - {id: 57, cat: Audio/Video, desc: "Remux"}
+      - {id: 45, cat: Audio/Video, desc: "1080p"}
+      - {id: 58, cat: Audio/Video, desc: "720p"}
+      - {id: 38, cat: Audio/Lossless, desc: "Flac"}
+
+      - {id: 41, cat: TV/Sport, desc: "Sports"}
+      - {id: 42, cat: TV/Anime, desc: "Anime"}
+      - {id: 44, cat: PC, desc: "Windows Apps"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: index.php?page=login
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    error:
+      - selector: table.lista > tbody > tr > td.lista > span[style="color:#FF0000;"]
+    test:
+      path: index.php
+      selector: ul#navlist
+
+  ratio:
+    path: index.php
+    selector: "ul#navlist > li:contains(\"Ratio: \")"
+    filters:
+      - name: split
+        args: ["\u00a0", 1]
+      - name: replace
+        args: ["---", "0"]
+
+  search:
+    path: index.php
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      page: torrents
+      options: 0
+      active: 0
+    rows:
+      selector: div.b-content > table.lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: title
+        filters:
+          - name: replace
+            args: ["View details: ", ""]
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      comments:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: p
+        filters:
+          - name: replace
+            args: ["\u00a0", ""]
+          - name: regexp
+            args: "\\|\\s+Size:\\s+([\\w\\d\\.,]+ \\w\\w)\\s+\\|"
+      date:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "<center>Added:(.*?)</center>"
+      grabs:
+        selector: a[href^="index.php?page=torrent_history&id="]
+        filters:
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: a[title="Click here to view peers details"]:nth-child(1)
+      leechers:
+        selector: a[title="Click here to view peers details"]:nth-child(2)
+      downloadvolumefactor:
+        case:
+          img[alt="gold"]: "0"
+          img[alt="silver"]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt="2x Upload Multiplier"]: "2"
+          img[alt="3x Upload Multiplier"]: "3"
+          img[alt="4x Upload Multiplier"]: "4"
+          img[alt="5x Upload Multiplier"]: "5"
+          img[alt="6x Upload Multiplier"]: "6"
+          img[alt="7x Upload Multiplier"]: "7"
+          img[alt="8x Upload Multiplier"]: "8"
+          img[alt="9x Upload Multiplier"]: "9"
+          img[alt="10x Upload Multiplier"]: "10"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/bluebird.yml b/src/Jackett/Definitions/bluebird.yml
index e9c56829a2b197dbef26a218b83ceeb760f9f6ad..a7b1f4597bc1daf9deb76451bd743ef755de6ca6 100644
--- a/src/Jackett/Definitions/bluebird.yml
+++ b/src/Jackett/Definitions/bluebird.yml
@@ -1,89 +1,89 @@
----
-  site: bluebirdhd
-  name: BlueBird
-  language: ru-ru
-  type: private
-  encoding: windows-1251
-  links:
-    - https://bluebird-hd.org/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Films"}
-      - {id: 2, cat: TV/Anime, desc: "Cartoons"}
-      - {id: 3, cat: TV/Documentary, desc: "documentary"}
-      - {id: 4, cat: Audio, desc: "Show / Music"}
-      - {id: 5, cat: TV/Sport, desc: "Sport"}
-      - {id: 6, cat: TV, desc: "TV series"}
-      - {id: 7, cat: XXX, desc: "erotica"}
-      - {id: 8, cat: Other, desc: "Demo / Misc"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.error
-    test:
-      path: /browse.php
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-    rows:
-      selector: table > tbody > tr:has(a[href^="details.php?id="])
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      grabs:
-        selector: a[href*="&snatched=1#snatched"]
-        filters:
-          - name: regexp
-            args: (\d+)
-      size:
-        selector: td:nth-child(7)
-        remove: a
-      date:
-        selector: div#cleft > font
-      seeders:
-        selector: td:nth-child(5)
-      leechers:
-        selector: td:nth-child(6)
-      banner:
-        selector: a.tname
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=([^\s]+)
-      downloadvolumefactor:
-        case:
-          img[src="pic/diamond.png"]: "0"
-          img[src="pic/freedownload.gif"]: "0"
-          img[src="pic/silver.gif"]: "0.5"
-          img[src="pic/bronze.gif"]: "0.75"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[src="pic/diamond.png"]: "2"
-          "*": "1"
+---
+  site: bluebirdhd
+  name: BlueBird
+  language: ru-ru
+  type: private
+  encoding: windows-1251
+  links:
+    - https://bluebird-hd.org/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Films"}
+      - {id: 2, cat: TV/Anime, desc: "Cartoons"}
+      - {id: 3, cat: TV/Documentary, desc: "documentary"}
+      - {id: 4, cat: Audio, desc: "Show / Music"}
+      - {id: 5, cat: TV/Sport, desc: "Sport"}
+      - {id: 6, cat: TV, desc: "TV series"}
+      - {id: 7, cat: XXX, desc: "erotica"}
+      - {id: 8, cat: Other, desc: "Demo / Misc"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.error
+    test:
+      path: /browse.php
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+    rows:
+      selector: table > tbody > tr:has(a[href^="details.php?id="])
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      grabs:
+        selector: a[href*="&snatched=1#snatched"]
+        filters:
+          - name: regexp
+            args: (\d+)
+      size:
+        selector: td:nth-child(7)
+        remove: a
+      date:
+        selector: div#cleft > font
+      seeders:
+        selector: td:nth-child(5)
+      leechers:
+        selector: td:nth-child(6)
+      banner:
+        selector: a.tname
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=([^\s]+)
+      downloadvolumefactor:
+        case:
+          img[src="pic/diamond.png"]: "0"
+          img[src="pic/freedownload.gif"]: "0"
+          img[src="pic/silver.gif"]: "0.5"
+          img[src="pic/bronze.gif"]: "0.75"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[src="pic/diamond.png"]: "2"
+          "*": "1"
diff --git a/src/Jackett/Definitions/chdbits.yml b/src/Jackett/Definitions/chdbits.yml
index 6d8267b94bbb3844eb0ddd198eecb18a1e93ea7e..98944a5a27ce063035393f937cb76d51f64be425 100644
--- a/src/Jackett/Definitions/chdbits.yml
+++ b/src/Jackett/Definitions/chdbits.yml
@@ -1,104 +1,104 @@
----
-  site: chdbits
-  name: CHDBits
-  description: "A general tracker"
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://chdbits.co
-
-  caps:
-    categorymappings:
-      - {id: 401, cat: Movies, desc: "Movies"}
-      - {id: 404, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 405, cat: TV/Anime, desc: "Animations"}
-      - {id: 402, cat: TV, desc: "TV Series"}
-      - {id: 403, cat: TV, desc: "TV Shows"}
-      - {id: 406, cat: Audio/Video, desc: "Music Videos"}
-      - {id: 407, cat: TV/Sport, desc: "Sports"}
-      - {id: 409, cat: Other, desc: "Misc"}
-      - {id: 408, cat: Audio, desc: "HQ Audio"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-
-  ratio:
-    path: /torrents.php
-    selector: table#info_block
-    filters:
-      - name: regexp
-        args: "Ratio:\\s(.*?)\\s\\s"
-
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      title|optional:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      date:
-        selector: td:nth-child(4) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a, img
+---
+  site: chdbits
+  name: CHDBits
+  description: "A general tracker"
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://chdbits.co
+
+  caps:
+    categorymappings:
+      - {id: 401, cat: Movies, desc: "Movies"}
+      - {id: 404, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 405, cat: TV/Anime, desc: "Animations"}
+      - {id: 402, cat: TV, desc: "TV Series"}
+      - {id: 403, cat: TV, desc: "TV Shows"}
+      - {id: 406, cat: Audio/Video, desc: "Music Videos"}
+      - {id: 407, cat: TV/Sport, desc: "Sports"}
+      - {id: 409, cat: Other, desc: "Misc"}
+      - {id: 408, cat: Audio, desc: "HQ Audio"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+
+  ratio:
+    path: /torrents.php
+    selector: table#info_block
+    filters:
+      - name: regexp
+        args: "Ratio:\\s(.*?)\\s\\s"
+
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      title|optional:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      date:
+        selector: td:nth-child(4) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a, img
diff --git a/src/Jackett/Definitions/cinemageddon.yml b/src/Jackett/Definitions/cinemageddon.yml
index 5a314d967ba44625380b4a1b218a91c539c8ba7a..596e730135c6e4fed25e6f688a0e6d5f4a6368f6 100644
--- a/src/Jackett/Definitions/cinemageddon.yml
+++ b/src/Jackett/Definitions/cinemageddon.yml
@@ -1,99 +1,99 @@
----
-  site: cinemageddon
-  name: Cinemageddon
-  description: "B-movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://cinemageddon.net/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Action"}
-      - {id: 2, cat: Movies, desc: "Horror"}
-      - {id: 3, cat: Movies, desc: "Martial Arts"}
-      - {id: 4, cat: Movies, desc: "Comedy"}
-      - {id: 5, cat: Movies, desc: "Other"}
-      - {id: 6, cat: Movies, desc: "Hidden Gems"}
-      - {id: 7, cat: Movies, desc: "Sci-Fi"}
-      - {id: 8, cat: Movies, desc: "Gore"}
-      - {id: 9, cat: Movies, desc: "Exploitation"}
-      - {id: 11, cat: Movies, desc: "OST"}
-      - {id: 12, cat: Movies, desc: "XXX"}
-      - {id: 13, cat: Movies, desc: "Thriller"}
-      - {id: 14, cat: Movies, desc: "Adventure"}
-      - {id: 15, cat: Movies, desc: "Documentary"}
-      - {id: 16, cat: Movies, desc: "Western"}
-      - {id: 17, cat: Movies, desc: "Family"}
-      - {id: 18, cat: Movies, desc: "Drama"}
-      - {id: 19, cat: Movies, desc: "Ebooks"}
-      - {id: 20, cat: Movies, desc: "Softcore"}
-      - {id: 21, cat: Movies, desc: "Tinfoil Hat"}
-      - {id: 22, cat: Movies, desc: "Trailers"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table.torrenttable > tbody > tr:has(a[href^="browse.php?cat="])
-    fields:
-      category:
-        text: 1
-      title:
-        selector: td:nth-child(2)
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(6)
-      files:
-        selector: td:nth-child(5)
-        filters:
-          - name: regexp
-            args: (\d+)\s+file
-      size:
-        selector: td:nth-child(5)
-        filters:
-          - name: regexp
-            args: (\d+.*(MB|GB)+)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: regexp
-            args: (\d{4}-\d{2}-\d{2})
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: cinemageddon
+  name: Cinemageddon
+  description: "B-movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://cinemageddon.net/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Action"}
+      - {id: 2, cat: Movies, desc: "Horror"}
+      - {id: 3, cat: Movies, desc: "Martial Arts"}
+      - {id: 4, cat: Movies, desc: "Comedy"}
+      - {id: 5, cat: Movies, desc: "Other"}
+      - {id: 6, cat: Movies, desc: "Hidden Gems"}
+      - {id: 7, cat: Movies, desc: "Sci-Fi"}
+      - {id: 8, cat: Movies, desc: "Gore"}
+      - {id: 9, cat: Movies, desc: "Exploitation"}
+      - {id: 11, cat: Movies, desc: "OST"}
+      - {id: 12, cat: Movies, desc: "XXX"}
+      - {id: 13, cat: Movies, desc: "Thriller"}
+      - {id: 14, cat: Movies, desc: "Adventure"}
+      - {id: 15, cat: Movies, desc: "Documentary"}
+      - {id: 16, cat: Movies, desc: "Western"}
+      - {id: 17, cat: Movies, desc: "Family"}
+      - {id: 18, cat: Movies, desc: "Drama"}
+      - {id: 19, cat: Movies, desc: "Ebooks"}
+      - {id: 20, cat: Movies, desc: "Softcore"}
+      - {id: 21, cat: Movies, desc: "Tinfoil Hat"}
+      - {id: 22, cat: Movies, desc: "Trailers"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table.torrenttable > tbody > tr:has(a[href^="browse.php?cat="])
+    fields:
+      category:
+        text: 1
+      title:
+        selector: td:nth-child(2)
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(6)
+      files:
+        selector: td:nth-child(5)
+        filters:
+          - name: regexp
+            args: (\d+)\s+file
+      size:
+        selector: td:nth-child(5)
+        filters:
+          - name: regexp
+            args: (\d+.*(MB|GB)+)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: regexp
+            args: (\d{4}-\d{2}-\d{2})
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/cinematik.yml b/src/Jackett/Definitions/cinematik.yml
index d0e31d6b86a7f6771eb66fd2f87aa910387baaf4..1a581b3d9f3ad50042c8e35f6e196d15c4e99aa2 100644
--- a/src/Jackett/Definitions/cinematik.yml
+++ b/src/Jackett/Definitions/cinematik.yml
@@ -1,94 +1,94 @@
----
-  site: cinematik
-  name: Cinematik
-  description: "Non-Hollywood movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://www.cinematik.net
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Comedy"}
-      - {id: 4, cat: Movies, desc: "Action"}
-      - {id: 6, cat: Movies, desc: "Drama"}
-      - {id: 7, cat: Movies, desc: "Documentary"}
-      - {id: 9, cat: Movies, desc: "Crime"}
-      - {id: 12, cat: Movies, desc: "Sci-Fi"}
-      - {id: 17, cat: Movies, desc: "War"}
-      - {id: 21, cat: Movies, desc: "Silent Films"}
-      - {id: 23, cat: Movies, desc: "TV-Series"}
-      - {id: 24, cat: Movies, desc: "Animation"}
-      - {id: 25, cat: Movies, desc: "Exploitation"}
-      - {id: 26, cat: Movies, desc: "Experimental"}
-      - {id: 27, cat: Movies, desc: "Fantasy"}
-      - {id: 29, cat: Movies, desc: "Short"}
-      - {id: 30, cat: Movies, desc: "Western"}
-      - {id: 32, cat: Movies, desc: "Foreign Languages"}
-      - {id: 33, cat: Movies, desc: "Thriller"}
-      - {id: 34, cat: Movies, desc: "Opera and Musical"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: my.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table[border="1"] tr:not(:first-child)
-    fields:
-      category:
-        text: 1
-      title:
-        selector: td:nth-child(2) a
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(8)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      files:
-        selector: td:nth-child(5)
-      size:
-        selector: td:nth-child(7)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      date:
-        selector: td:nth-child(11) div.addedtor
-      downloadvolumefactor:
-        case:
-          "img[title=\"Golden Torrent: No Download Stats are Recorded\"]": "0"
-          "img[title=\"Silver Torrent: Download Stats are 25% Recorded\"]": "0.25"
-          "img[title=\"Platinum Torrent: No Download Stats are Recorded, Upload Stats are Doubled!\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "img[title=\"Platinum Torrent: No Download Stats are Recorded, Upload Stats are Doubled!\"]": "2"
+---
+  site: cinematik
+  name: Cinematik
+  description: "Non-Hollywood movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://www.cinematik.net
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Comedy"}
+      - {id: 4, cat: Movies, desc: "Action"}
+      - {id: 6, cat: Movies, desc: "Drama"}
+      - {id: 7, cat: Movies, desc: "Documentary"}
+      - {id: 9, cat: Movies, desc: "Crime"}
+      - {id: 12, cat: Movies, desc: "Sci-Fi"}
+      - {id: 17, cat: Movies, desc: "War"}
+      - {id: 21, cat: Movies, desc: "Silent Films"}
+      - {id: 23, cat: Movies, desc: "TV-Series"}
+      - {id: 24, cat: Movies, desc: "Animation"}
+      - {id: 25, cat: Movies, desc: "Exploitation"}
+      - {id: 26, cat: Movies, desc: "Experimental"}
+      - {id: 27, cat: Movies, desc: "Fantasy"}
+      - {id: 29, cat: Movies, desc: "Short"}
+      - {id: 30, cat: Movies, desc: "Western"}
+      - {id: 32, cat: Movies, desc: "Foreign Languages"}
+      - {id: 33, cat: Movies, desc: "Thriller"}
+      - {id: 34, cat: Movies, desc: "Opera and Musical"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: my.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table[border="1"] tr:not(:first-child)
+    fields:
+      category:
+        text: 1
+      title:
+        selector: td:nth-child(2) a
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(8)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      files:
+        selector: td:nth-child(5)
+      size:
+        selector: td:nth-child(7)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      date:
+        selector: td:nth-child(11) div.addedtor
+      downloadvolumefactor:
+        case:
+          "img[title=\"Golden Torrent: No Download Stats are Recorded\"]": "0"
+          "img[title=\"Silver Torrent: Download Stats are 25% Recorded\"]": "0.25"
+          "img[title=\"Platinum Torrent: No Download Stats are Recorded, Upload Stats are Doubled!\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "img[title=\"Platinum Torrent: No Download Stats are Recorded, Upload Stats are Doubled!\"]": "2"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/classix.yml b/src/Jackett/Definitions/classix.yml
index 2d22f93302535f9a54d9553d90071ae884a630bc..8f5d9689d5cc92c81149cb061378bd754abe6a34 100644
--- a/src/Jackett/Definitions/classix.yml
+++ b/src/Jackett/Definitions/classix.yml
@@ -1,64 +1,64 @@
----
-  site: classix
-  name: Classix
-  description: "Classic movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://classix-unlimited.co.uk/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Movies"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: account-login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.myContent:contains("Access Denied")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: torrents-search.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table > tbody > tr:has(a[href^="torrents.php?cat="])
-    fields:
-      category:
-        text: 1
-      title:
-        selector: td:nth-child(3)
-      download:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["torrents-details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-      size:
-        selector: td:nth-child(7)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: classix
+  name: Classix
+  description: "Classic movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://classix-unlimited.co.uk/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Movies"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: account-login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.myContent:contains("Access Denied")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: torrents-search.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table > tbody > tr:has(a[href^="torrents.php?cat="])
+    fields:
+      category:
+        text: 1
+      title:
+        selector: td:nth-child(3)
+      download:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["torrents-details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+      size:
+        selector: td:nth-child(7)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/czteam.yml b/src/Jackett/Definitions/czteam.yml
index fa44756dccbf29bfa4f57a32676966d58c2a2e79..7b1341f5760cb6b07b19426a23bf68964a18a1d3 100644
--- a/src/Jackett/Definitions/czteam.yml
+++ b/src/Jackett/Definitions/czteam.yml
@@ -1,94 +1,94 @@
----
-  site: czteam
-  name: CZTeam
-  language: cs-cz
-  type: private
-  encoding: UTF-8
-  links:
-    - https://czteam.club/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Movies"}
-      - {id: 2, cat: TV, desc: "TV-Eps"}
-      - {id: 3, cat: Audio, desc: "Music"}
-      - {id: 4, cat: PC/Games, desc: "Games"}
-      - {id: 5, cat: PC/ISO, desc: "Software"}
-      - {id: 6, cat: XXX, desc: "XxX"}
-      - {id: 7, cat: Other, desc: "Other"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: 1
-      login: "Log in"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: torrents.php
-
-  search:
-    path: torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: time
-      order_way: desc
-      action: basic
-      searchsubmit: 1
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      title:
-        selector: a.torrent_name
-      category:
-        selector: td.cats_col
-        case:
-          div.cats_movies: 1
-          div.cats_tveps: 2
-          div.cats_music: 3
-          div.cats_games: 4
-          div.cats_software: 5
-          div.cats_xxx: 6
-          div.cats_other: 7
-      details:
-        selector: a.torrent_name
-        attribute: href
-      banner:
-        selector: a.torrent_name
-        optional: true
-        attribute: cover
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          "strong.tl_free": "0"
-          "strong.tl_neutral": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "strong.tl_neutral": "0"
-          "*": "1"
-      description:
-        selector: div.torrent_info
+---
+  site: czteam
+  name: CZTeam
+  language: cs-cz
+  type: private
+  encoding: UTF-8
+  links:
+    - https://czteam.club/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Movies"}
+      - {id: 2, cat: TV, desc: "TV-Eps"}
+      - {id: 3, cat: Audio, desc: "Music"}
+      - {id: 4, cat: PC/Games, desc: "Games"}
+      - {id: 5, cat: PC/ISO, desc: "Software"}
+      - {id: 6, cat: XXX, desc: "XxX"}
+      - {id: 7, cat: Other, desc: "Other"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: 1
+      login: "Log in"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: torrents.php
+
+  search:
+    path: torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: time
+      order_way: desc
+      action: basic
+      searchsubmit: 1
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      title:
+        selector: a.torrent_name
+      category:
+        selector: td.cats_col
+        case:
+          div.cats_movies: 1
+          div.cats_tveps: 2
+          div.cats_music: 3
+          div.cats_games: 4
+          div.cats_software: 5
+          div.cats_xxx: 6
+          div.cats_other: 7
+      details:
+        selector: a.torrent_name
+        attribute: href
+      banner:
+        selector: a.torrent_name
+        optional: true
+        attribute: cover
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          "strong.tl_free": "0"
+          "strong.tl_neutral": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "strong.tl_neutral": "0"
+          "*": "1"
+      description:
+        selector: div.torrent_info
         remove: strong
\ No newline at end of file
diff --git a/src/Jackett/Definitions/datascene.yml b/src/Jackett/Definitions/datascene.yml
index 02e4a8056161c46bf1712d3f6354f6bc55406889..b08c10c054508ce65ce9fe4b48d4596f47f87cbe 100644
--- a/src/Jackett/Definitions/datascene.yml
+++ b/src/Jackett/Definitions/datascene.yml
@@ -1,119 +1,119 @@
----
-  site: datascene
-  name: DataScene
-  language: ro-ro
-  type: private
-  encoding: windows-1252
-  links:
-    - http://datascene.net/
-
-  caps:
-    categorymappings:
-      - {id: 3, cat: TV/Anime, desc: "Anime | Cartoon"}
-      - {id: 15, cat: PC/0day, desc: "Appz | Win"}
-      - {id: 4, cat: PC/0day, desc: "Appz | Linux"}
-      - {id: 6, cat: Books, desc: "E-Book"}
-      - {id: 10, cat: PC/Games, desc: "Games | PC Iso"}
-      - {id: 9, cat: PC/Games, desc: "Games | PC Rips"}
-      - {id: 11, cat: Console, desc: "Games | Pack"}
-      - {id: 43, cat: Console, desc: "Games | Console"}
-      - {id: 29, cat: Other, desc: "Images"}
-      - {id: 2, cat: Other, desc: "MiSC"}
-      - {id: 5, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 27, cat: Movies, desc: "Movies | Pack"}
-      - {id: 46, cat: Movies/3D, desc: "Movies | 3D"}
-      - {id: 26, cat: Movies/SD, desc: "Movies | Cam"}
-      - {id: 25, cat: Movies, desc: "Movies | Documentary"}
-      - {id: 24, cat: Movies/DVD, desc: "Movies | DVD-R"}
-      - {id: 32, cat: Movies/DVD, desc: "Movies | DVD-RO"}
-      - {id: 23, cat: Movies/HD, desc: "Movies | HD"}
-      - {id: 31, cat: Movies/HD, desc: "Movies | HD-Ro"}
-      - {id: 34, cat: Movies/Foreign, desc: "Movies | Hindi"}
-      - {id: 30, cat: Movies/SD, desc: "Movies | Xvid"}
-      - {id: 36, cat: Movies/SD, desc: "Movies | Xvid-Ro"}
-      - {id: 21, cat: Audio/Video, desc: "Music | Video"}
-      - {id: 19, cat: Audio , desc: "Music | Mp3/Flac"}
-      - {id: 18, cat: Other, desc: "Other"}
-      - {id: 42, cat: Other, desc: "Premiera | DsT"}
-      - {id: 14, cat: TV/Sport, desc: "Sport"}
-      - {id: 47, cat: TV/SD, desc: "Tv | Episodes"}
-      - {id: 28, cat: TV/HD, desc: "Tv-HD | Episodes"}
-      - {id: 13, cat: Other, desc: "Tutoriale"}
-      - {id: 12, cat: XXX, desc: "XxX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /browse.php
-      
-  ratio:
-    path: /browse.php
-    selector: font:contains("Ratio:") > span
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: tr:has(a.tname)
-    fields:
-      title:
-        selector: a.tname
-        attribute: title
-      details:
-        selector: a.tname
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="/download.php/"]
-        attribute: href
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: (\d+)
-      size:
-        selector: td:nth-child(6)
-      date:
-        selector: td:nth-child(2) > right > div:has(font:contains("Uploaded"))
-        remove: div > font
-        filters:
-          - name: trim
-            args: ":"
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      banner:
-        selector: a.tname
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=([^\s]+)
-      downloadvolumefactor:
-        case:
-          "img[src=\"pic/free.gif\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(2) > right
+---
+  site: datascene
+  name: DataScene
+  language: ro-ro
+  type: private
+  encoding: windows-1252
+  links:
+    - http://datascene.net/
+
+  caps:
+    categorymappings:
+      - {id: 3, cat: TV/Anime, desc: "Anime | Cartoon"}
+      - {id: 15, cat: PC/0day, desc: "Appz | Win"}
+      - {id: 4, cat: PC/0day, desc: "Appz | Linux"}
+      - {id: 6, cat: Books, desc: "E-Book"}
+      - {id: 10, cat: PC/Games, desc: "Games | PC Iso"}
+      - {id: 9, cat: PC/Games, desc: "Games | PC Rips"}
+      - {id: 11, cat: Console, desc: "Games | Pack"}
+      - {id: 43, cat: Console, desc: "Games | Console"}
+      - {id: 29, cat: Other, desc: "Images"}
+      - {id: 2, cat: Other, desc: "MiSC"}
+      - {id: 5, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 27, cat: Movies, desc: "Movies | Pack"}
+      - {id: 46, cat: Movies/3D, desc: "Movies | 3D"}
+      - {id: 26, cat: Movies/SD, desc: "Movies | Cam"}
+      - {id: 25, cat: Movies, desc: "Movies | Documentary"}
+      - {id: 24, cat: Movies/DVD, desc: "Movies | DVD-R"}
+      - {id: 32, cat: Movies/DVD, desc: "Movies | DVD-RO"}
+      - {id: 23, cat: Movies/HD, desc: "Movies | HD"}
+      - {id: 31, cat: Movies/HD, desc: "Movies | HD-Ro"}
+      - {id: 34, cat: Movies/Foreign, desc: "Movies | Hindi"}
+      - {id: 30, cat: Movies/SD, desc: "Movies | Xvid"}
+      - {id: 36, cat: Movies/SD, desc: "Movies | Xvid-Ro"}
+      - {id: 21, cat: Audio/Video, desc: "Music | Video"}
+      - {id: 19, cat: Audio , desc: "Music | Mp3/Flac"}
+      - {id: 18, cat: Other, desc: "Other"}
+      - {id: 42, cat: Other, desc: "Premiera | DsT"}
+      - {id: 14, cat: TV/Sport, desc: "Sport"}
+      - {id: 47, cat: TV/SD, desc: "Tv | Episodes"}
+      - {id: 28, cat: TV/HD, desc: "Tv-HD | Episodes"}
+      - {id: 13, cat: Other, desc: "Tutoriale"}
+      - {id: 12, cat: XXX, desc: "XxX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /browse.php
+      
+  ratio:
+    path: /browse.php
+    selector: font:contains("Ratio:") > span
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: tr:has(a.tname)
+    fields:
+      title:
+        selector: a.tname
+        attribute: title
+      details:
+        selector: a.tname
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="/download.php/"]
+        attribute: href
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: (\d+)
+      size:
+        selector: td:nth-child(6)
+      date:
+        selector: td:nth-child(2) > right > div:has(font:contains("Uploaded"))
+        remove: div > font
+        filters:
+          - name: trim
+            args: ":"
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      banner:
+        selector: a.tname
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=([^\s]+)
+      downloadvolumefactor:
+        case:
+          "img[src=\"pic/free.gif\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(2) > right
         remove: div
\ No newline at end of file
diff --git a/src/Jackett/Definitions/dragonworld.yml b/src/Jackett/Definitions/dragonworld.yml
index 3d716cd5a9fe43549bddfd2df56a74c6b07b25ea..317f3728b8d4a46a59e56c13a4f3e774b41d30ce 100644
--- a/src/Jackett/Definitions/dragonworld.yml
+++ b/src/Jackett/Definitions/dragonworld.yml
@@ -1,154 +1,154 @@
----
-  site: dragonworld
-  name: Dragon World (DTW)
-  language: de-de
-  type: private
-  encoding: UTF-8
-  links:
-    - http://dtw.sytes.net/
-
-  caps:
-    categorymappings:
-      # Dokumentation
-      - {id: 46, cat: TV/Documentary, desc: "Dokumentation"}
-      - {id: 55, cat: TV/Documentary, desc: "Dokumentation/HD"}
-      - {id: 56, cat: TV/Documentary, desc: "Dokumentation/SD"}
-      # Ebooks
-      - {id: 36, cat: Books, desc: "Ebooks"}
-      - {id: 37, cat: Books, desc: "Ebooks"}
-      - {id: 38, cat: Books, desc: "Ebooks/Hoerspiele/Hoerbuecher"}
-      # Games
-      - {id: 21, cat: Console, desc: "Games"}
-      - {id: 24, cat: Console/Other, desc: "Games/Nintendo"}
-      - {id: 22, cat: PC/Games, desc: "Games/PC"}
-      - {id: 23, cat: Console/PS4, desc: "Games/Playstation"}
-      - {id: 25, cat: Console/Xbox, desc: "Games/Xbox"}
-      # Kinder
-      - {id: 10, cat: Other, desc: "Kinder"}
-      - {id: 14, cat: Other, desc: "Kinder/Diverses"}
-      - {id: 12, cat: Movies, desc: "Kinder/Filme"}
-      - {id: 11, cat: PC/Games, desc: "Kinder/Games"}
-      - {id: 13, cat: Audio, desc: "Kinder/Musik"}
-      # Movies
-      - {id: 15, cat: Movies, desc: "Movies"}
-      - {id: 50, cat: Movies/3D, desc: "Movies/3D"}
-      - {id: 48, cat: Movies/HD, desc: "Movies/HD"}
-      - {id: 53, cat: Movies/HD, desc: "Movies/HD Pack"}
-      - {id: 45, cat: Movies/HD, desc: "Movies/Remuxe"}
-      - {id: 17, cat: Movies/SD, desc: "Movies/SD"}
-      - {id: 54, cat: Movies/SD, desc: "Movies/SD Pack"}
-      # Musik
-      - {id: 4, cat: Audio, desc: "Musik"}
-      - {id: 57, cat: Audio, desc: "Musik/Album"}
-      - {id: 8, cat: Audio/Lossless, desc: "Musik/Flac"}
-      - {id: 7, cat: Audio/MP3, desc: "Musik/Mp3"}
-      - {id: 9, cat: Audio/Video, desc: "Musik/Video"}
-      # Serien
-      - {id: 26, cat: TV, desc: "Serien"}
-      - {id: 27, cat: TV/HD, desc: "Serien/HD"}
-      - {id: 28, cat: TV/SD, desc: "Serien/SD"}
-      # Software
-      - {id: 29, cat: PC/0day, desc: "Software"}
-      - {id: 32, cat: PC/0day, desc: "Software/Diverses"}
-      - {id: 31, cat: PC/Mac, desc: "Software/Mac"}
-      - {id: 30, cat: PC/0day, desc: "Software/Windows"}
-      # Sport
-      - {id: 39, cat: TV/Sport, desc: "Sport"}
-      - {id: 40, cat: TV/Sport, desc: "Sport HD"}
-      - {id: 58, cat: TV/Sport, desc: "Sport SD"}
-      # XXX
-      - {id: 33, cat: XXX, desc: "XXX"}
-      - {id: 34, cat: XXX, desc: "XXX/HD"}
-      - {id: 35, cat: XXX, desc: "XXX/SD"}
-
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-  
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table:has(td:contains("Ein Fehler ist aufgetreten"))
-    test:
-      path: browse.php
-      selector: a[href*="/logout.php"]
-
-  download:
-    before:
-      path: "takethanks.php"
-      method: "post"
-      inputs:
-        torrentid: "{{ .DownloadUri.Query.id }}"
-      
-  search:
-    path: browse.php
-    keywordsfilters:
-      - name: re_replace
-        args: ["[^a-zA-Z0-9]+", "%"]
-    inputs:
-      do: "search"
-      keywords: "{{ .Keywords }}"
-      search_type: "t_name"
-      category: "0" # multi cat search not supported
-      include_dead_torrents: "yes"
-    rows:
-      selector: table#sortabletable > tbody > tr:has(a[href*="/details.php?id="])
-      filters:
-        - name: andmatch
-          args: 66
-    fields:
-      download:
-        selector: a[href*="/download.php?id="]
-        attribute: href
-      magnet:
-        selector: a[href^="magnet:"]
-        attribute: href
-      title:
-        selector: a[href*="/details.php?id="]
-      title:
-        selector: div.tooltip-content > div
-        optional: true
-      details:
-        selector: a[href*="/details.php?id="]
-        attribute: href
-      category:
-        selector: a[href*="/browse.php?category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      banner:
-        selector: div.tooltip-content > img
-        attribute: src
-        optional: true
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          img[alt^="OnlyUp Torrent"]: "0"
-          img[alt^="50% "]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt^="multi2 Torrent"]: "2"
-          "*": "1"
-      date:
-        selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
-        remove: span
-        filters:
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02-01-2006 15:04 -07:00"
+---
+  site: dragonworld
+  name: Dragon World (DTW)
+  language: de-de
+  type: private
+  encoding: UTF-8
+  links:
+    - http://dtw.sytes.net/
+
+  caps:
+    categorymappings:
+      # Dokumentation
+      - {id: 46, cat: TV/Documentary, desc: "Dokumentation"}
+      - {id: 55, cat: TV/Documentary, desc: "Dokumentation/HD"}
+      - {id: 56, cat: TV/Documentary, desc: "Dokumentation/SD"}
+      # Ebooks
+      - {id: 36, cat: Books, desc: "Ebooks"}
+      - {id: 37, cat: Books, desc: "Ebooks"}
+      - {id: 38, cat: Books, desc: "Ebooks/Hoerspiele/Hoerbuecher"}
+      # Games
+      - {id: 21, cat: Console, desc: "Games"}
+      - {id: 24, cat: Console/Other, desc: "Games/Nintendo"}
+      - {id: 22, cat: PC/Games, desc: "Games/PC"}
+      - {id: 23, cat: Console/PS4, desc: "Games/Playstation"}
+      - {id: 25, cat: Console/Xbox, desc: "Games/Xbox"}
+      # Kinder
+      - {id: 10, cat: Other, desc: "Kinder"}
+      - {id: 14, cat: Other, desc: "Kinder/Diverses"}
+      - {id: 12, cat: Movies, desc: "Kinder/Filme"}
+      - {id: 11, cat: PC/Games, desc: "Kinder/Games"}
+      - {id: 13, cat: Audio, desc: "Kinder/Musik"}
+      # Movies
+      - {id: 15, cat: Movies, desc: "Movies"}
+      - {id: 50, cat: Movies/3D, desc: "Movies/3D"}
+      - {id: 48, cat: Movies/HD, desc: "Movies/HD"}
+      - {id: 53, cat: Movies/HD, desc: "Movies/HD Pack"}
+      - {id: 45, cat: Movies/HD, desc: "Movies/Remuxe"}
+      - {id: 17, cat: Movies/SD, desc: "Movies/SD"}
+      - {id: 54, cat: Movies/SD, desc: "Movies/SD Pack"}
+      # Musik
+      - {id: 4, cat: Audio, desc: "Musik"}
+      - {id: 57, cat: Audio, desc: "Musik/Album"}
+      - {id: 8, cat: Audio/Lossless, desc: "Musik/Flac"}
+      - {id: 7, cat: Audio/MP3, desc: "Musik/Mp3"}
+      - {id: 9, cat: Audio/Video, desc: "Musik/Video"}
+      # Serien
+      - {id: 26, cat: TV, desc: "Serien"}
+      - {id: 27, cat: TV/HD, desc: "Serien/HD"}
+      - {id: 28, cat: TV/SD, desc: "Serien/SD"}
+      # Software
+      - {id: 29, cat: PC/0day, desc: "Software"}
+      - {id: 32, cat: PC/0day, desc: "Software/Diverses"}
+      - {id: 31, cat: PC/Mac, desc: "Software/Mac"}
+      - {id: 30, cat: PC/0day, desc: "Software/Windows"}
+      # Sport
+      - {id: 39, cat: TV/Sport, desc: "Sport"}
+      - {id: 40, cat: TV/Sport, desc: "Sport HD"}
+      - {id: 58, cat: TV/Sport, desc: "Sport SD"}
+      # XXX
+      - {id: 33, cat: XXX, desc: "XXX"}
+      - {id: 34, cat: XXX, desc: "XXX/HD"}
+      - {id: 35, cat: XXX, desc: "XXX/SD"}
+
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+  
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table:has(td:contains("Ein Fehler ist aufgetreten"))
+    test:
+      path: browse.php
+      selector: a[href*="/logout.php"]
+
+  download:
+    before:
+      path: "takethanks.php"
+      method: "post"
+      inputs:
+        torrentid: "{{ .DownloadUri.Query.id }}"
+      
+  search:
+    path: browse.php
+    keywordsfilters:
+      - name: re_replace
+        args: ["[^a-zA-Z0-9]+", "%"]
+    inputs:
+      do: "search"
+      keywords: "{{ .Keywords }}"
+      search_type: "t_name"
+      category: "0" # multi cat search not supported
+      include_dead_torrents: "yes"
+    rows:
+      selector: table#sortabletable > tbody > tr:has(a[href*="/details.php?id="])
+      filters:
+        - name: andmatch
+          args: 66
+    fields:
+      download:
+        selector: a[href*="/download.php?id="]
+        attribute: href
+      magnet:
+        selector: a[href^="magnet:"]
+        attribute: href
+      title:
+        selector: a[href*="/details.php?id="]
+      title:
+        selector: div.tooltip-content > div
+        optional: true
+      details:
+        selector: a[href*="/details.php?id="]
+        attribute: href
+      category:
+        selector: a[href*="/browse.php?category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      banner:
+        selector: div.tooltip-content > img
+        attribute: src
+        optional: true
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          img[alt^="OnlyUp Torrent"]: "0"
+          img[alt^="50% "]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt^="multi2 Torrent"]: "2"
+          "*": "1"
+      date:
+        selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
+        remove: span
+        filters:
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02-01-2006 15:04 -07:00"
diff --git a/src/Jackett/Definitions/dragonworldreloaded.yml b/src/Jackett/Definitions/dragonworldreloaded.yml
index 0c3f8ccff8690e40762b3b06005d324f1c7b0a92..ee44a4d31c7111b9aa35ef9c173bad999f6bc1e0 100644
--- a/src/Jackett/Definitions/dragonworldreloaded.yml
+++ b/src/Jackett/Definitions/dragonworldreloaded.yml
@@ -1,238 +1,238 @@
----
-  site: dragonworldreloaded
-  name: Dragonworld Reloaded
-  language: de-de
-  type: private
-  encoding: UTF-8
-  links:
-    - https://dragonworld-reloaded.net/
-
-  caps:
-    categorymappings:
-      # Kino
-      - {id: 118, cat: Movies/HD, desc: "Kino - HD"}
-      - {id: 4, cat: Movies/SD, desc: "Kino - SD"}
-      # Movies
-      - {id: 18, cat: Movies/SD, desc: "Movies - x264/XviD"}
-      - {id: 2, cat: Movies, desc: "Movies - Pack SD/HD"}
-      - {id: 22, cat: Movies/DVD, desc: "Movies - DVD/HD2"}
-      - {id: 52, cat: Movies, desc: "Movies - Kids"}
-      - {id: 19, cat: Movies/HD, desc: "Movies - HD"}
-      - {id: 25, cat: Movies/3D, desc: "Movies - 3D"}
-      - {id: 26, cat: Movies/BluRay, desc: "Movies - Blu-Ray"}
-      # Serien
-      - {id: 40, cat: TV/SD, desc: "Serien - SD"}
-      - {id: 41, cat: TV/HD, desc: "Serien - HD"}
-      - {id: 42, cat: TV/SD, desc: "Serien - Pack SD"}
-      - {id: 80, cat: TV/HD, desc: "Serien - Pack HD"}
-      # Musik
-      - {id: 119, cat: Audio, desc: "Musik - ALBEN"}
-      - {id: 5, cat: Audio/MP3, desc: "Musik - Mp3"}
-      - {id: 6, cat: Audio, desc: "Musik - Mixe"}
-      - {id: 92, cat: Audio, desc: "Musik - Discography"}
-      - {id: 114, cat: Audio, desc: "Musik - Musik Pack"}
-      - {id: 48, cat: Audio/Video, desc: "Musik - Video"}
-      # Doku
-      - {id: 37, cat: TV/Documentary, desc: "Doku - SD"}
-      - {id: 38, cat: TV/Documentary, desc: "Doku - HD"}
-      - {id: 81, cat: TV/Documentary, desc: "Doku - Pack "}
-      # Anime
-      - {id: 73, cat: TV/Anime, desc: "Anime - Movies"}
-      - {id: 74, cat: TV/Anime, desc: "Anime - Serien"}
-      # Games
-      - {id: 16, cat: PC/Games, desc: "Games - PC"}
-      - {id: 14, cat: Console/Other, desc: "Games - Wimmelbild"}
-      - {id: 7, cat: Console/PSP, desc: "Games - PSP"}
-      - {id: 17, cat: Console/PS3, desc: "Games - PS2/PS3"}
-      - {id: 29, cat: Console/NDS, desc: "Games - NDS/3DS"}
-      - {id: 15, cat: Console/Wii, desc: "Games - Wii"}
-      - {id: 8, cat: Console/Xbox, desc: "Games - XboX "}
-      # Appz
-      - {id: 30, cat: PC/0day, desc: "Appz - Windows"}
-      - {id: 31, cat: PC/0day, desc: "Appz - Linux"}
-      - {id: 32, cat: PC/Mac, desc: "Appz - Mac"}
-      - {id: 106, cat: PC/Phone-Android, desc: "Appz - Android"}
-      # Sport
-      - {id: 43, cat: TV/Sport, desc: "Sport - SD"}
-      - {id: 50, cat: TV/Sport, desc: "Sport - HD"}
-      # Sonstiges
-      - {id: 34, cat: Books, desc: "Sonstiges - E-Books"}
-      - {id: 35, cat: Audio/Audiobook, desc: "Sonstiges - Audiobook"}
-      - {id: 36, cat: Other, desc: "Sonstiges - Diverses"}
-      # XXX
-      - {id: 46, cat: XXX, desc: "XXX - SD"}
-      - {id: 47, cat: XXX, desc: "XXX - HD"}
-      - {id: 45, cat: XXX, desc: "XXX - Pack"}
-      - {id: 49, cat: XXX, desc: "XXX - Sonstiges"}
-      - {id: 110, cat: XXX, desc: "XXX - Hentai Serie"}
-      - {id: 111, cat: XXX, desc: "XXX - Hentai Movie"}
-      - {id: 116, cat: XXX, desc: "XXX - SexBooks"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-  
-  login:
-    path: /login.php
-    method: form
-    form: form[action="/login.php"]
-    cookies: ["JAVA=OK"] # avoid jscheck redirect
-    captcha:
-      type: image
-      image: img[src^="cap/captcha_math.php"]
-      input: stringCaptcha
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      loggiin: "einloggen"
-    error:
-      - selector: div#login_error
-    test:
-      path: selection.php
-
-  download:
-    before:
-      path: "ajax_det_poll.php"
-      method: "post"
-      inputs:
-        set_thanks: "thanks"
-        det_id: "{{ .DownloadUri.Query.torrent }}"
-        ajax: "yes"
-
-  search:
-    path: selection.php
-    inputs:
-      search: "{{ .Keywords }}"
-      blah: "0"
-      orderby: "added"
-      sort: "desc"
-    rows:
-      selector: div.selection_wrap
-    fields:
-      download:
-        selector: a.selection_a
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?torrent="]
-      title:
-        selector: a.selection_a
-      details:
-        selector: a.selection_a
-        attribute: href
-      category:
-        selector: div.kat_cat_pic
-        case:
-          # Kino
-          ":has(div.kat_cat_pic_name:contains(\"Kino\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "118"
-          ":has(div.kat_cat_pic_name:contains(\"Kino\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "4"
-          # Movies
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"x264/XviD\"))": "18"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Pack SD/HD\"))": "2"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"DVD/HD2\"))": "22"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Kids\"))": "52"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "19"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"3D\"))": "25"
-          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Blu-Ray\"))": "26"
-          # Serien
-          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "40"
-          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "41"
-          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Pack SD\"))": "42"
-          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Pack HD\"))": "80"
-          # Musik
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"ALBEN\"))": "119"
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Mp3\"))": "5"
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Mixe\"))": "6"
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Discography\"))": "92"
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Musik Pack\"))": "114"
-          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Video\"))": "48"
-          # Doku
-          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "37"
-          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "38"
-          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"Pack \"))": "81"
-          # Anime
-          ":has(div.kat_cat_pic_name:contains(\"Anime\")):has(div.kat_cat_pic_name_b:contains(\"Movies\"))": "73"
-          ":has(div.kat_cat_pic_name:contains(\"Anime\")):has(div.kat_cat_pic_name_b:contains(\"Serien\"))": "74"
-          # Games
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PC\"))": "16"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"Wimmelbild\"))": "14"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PSP\"))": "7"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PS2/PS3\"))": "17"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"NDS/3DS\"))": "29"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"Wii\"))": "15"
-          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"XboX \"))": "8"
-          # Appz
-          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Windows\"))": "30"
-          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Linux\"))": "31"
-          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Mac\"))": "32"
-          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Android\"))": "106"
-          # Sport
-          ":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "43"
-          ":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "50"
-          # Sonstiges
-          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"E-Books\"))": "34"
-          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Audiobook\"))": "35"
-          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Diverses\"))": "36"
-          # XXX
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "46"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "47"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Pack\"))": "45"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Sonstiges\"))": "49"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Hentai Serie\"))": "110"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Hentai Movie\"))": "111"
-          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"SexBooks\"))": "116"
-      banner:
-        selector: div[id^="details"] img
-        attribute: src
-      size:
-        selector: div.selection_unter_ad
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      grabs:
-        selector: div.selection_unter_ae
-        filters:
-          - name: trim
-            args: "x"
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      seeders:
-        selector: div.selection_unter_aa
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      leechers:
-        selector: div.selection_unter_aaa
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      downloadvolumefactor:
-        case:
-          ":root:has(div.onlyup)": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      date:
-        selector: div.selection_unter_ab
-        filters:
-          - name: replace
-            args: ["Heute", "Today"]
-          - name: replace
-            args: ["Gestern", "Yesterday"]
-          - name: replace
-            args: [" um", ""]
-          - name: dateparse
-            args: "02.01.2006 15:04:05"
-      description:
-        selector: selection_unter_af
-        optional: true
+---
+  site: dragonworldreloaded
+  name: Dragonworld Reloaded
+  language: de-de
+  type: private
+  encoding: UTF-8
+  links:
+    - https://dragonworld-reloaded.net/
+
+  caps:
+    categorymappings:
+      # Kino
+      - {id: 118, cat: Movies/HD, desc: "Kino - HD"}
+      - {id: 4, cat: Movies/SD, desc: "Kino - SD"}
+      # Movies
+      - {id: 18, cat: Movies/SD, desc: "Movies - x264/XviD"}
+      - {id: 2, cat: Movies, desc: "Movies - Pack SD/HD"}
+      - {id: 22, cat: Movies/DVD, desc: "Movies - DVD/HD2"}
+      - {id: 52, cat: Movies, desc: "Movies - Kids"}
+      - {id: 19, cat: Movies/HD, desc: "Movies - HD"}
+      - {id: 25, cat: Movies/3D, desc: "Movies - 3D"}
+      - {id: 26, cat: Movies/BluRay, desc: "Movies - Blu-Ray"}
+      # Serien
+      - {id: 40, cat: TV/SD, desc: "Serien - SD"}
+      - {id: 41, cat: TV/HD, desc: "Serien - HD"}
+      - {id: 42, cat: TV/SD, desc: "Serien - Pack SD"}
+      - {id: 80, cat: TV/HD, desc: "Serien - Pack HD"}
+      # Musik
+      - {id: 119, cat: Audio, desc: "Musik - ALBEN"}
+      - {id: 5, cat: Audio/MP3, desc: "Musik - Mp3"}
+      - {id: 6, cat: Audio, desc: "Musik - Mixe"}
+      - {id: 92, cat: Audio, desc: "Musik - Discography"}
+      - {id: 114, cat: Audio, desc: "Musik - Musik Pack"}
+      - {id: 48, cat: Audio/Video, desc: "Musik - Video"}
+      # Doku
+      - {id: 37, cat: TV/Documentary, desc: "Doku - SD"}
+      - {id: 38, cat: TV/Documentary, desc: "Doku - HD"}
+      - {id: 81, cat: TV/Documentary, desc: "Doku - Pack "}
+      # Anime
+      - {id: 73, cat: TV/Anime, desc: "Anime - Movies"}
+      - {id: 74, cat: TV/Anime, desc: "Anime - Serien"}
+      # Games
+      - {id: 16, cat: PC/Games, desc: "Games - PC"}
+      - {id: 14, cat: Console/Other, desc: "Games - Wimmelbild"}
+      - {id: 7, cat: Console/PSP, desc: "Games - PSP"}
+      - {id: 17, cat: Console/PS3, desc: "Games - PS2/PS3"}
+      - {id: 29, cat: Console/NDS, desc: "Games - NDS/3DS"}
+      - {id: 15, cat: Console/Wii, desc: "Games - Wii"}
+      - {id: 8, cat: Console/Xbox, desc: "Games - XboX "}
+      # Appz
+      - {id: 30, cat: PC/0day, desc: "Appz - Windows"}
+      - {id: 31, cat: PC/0day, desc: "Appz - Linux"}
+      - {id: 32, cat: PC/Mac, desc: "Appz - Mac"}
+      - {id: 106, cat: PC/Phone-Android, desc: "Appz - Android"}
+      # Sport
+      - {id: 43, cat: TV/Sport, desc: "Sport - SD"}
+      - {id: 50, cat: TV/Sport, desc: "Sport - HD"}
+      # Sonstiges
+      - {id: 34, cat: Books, desc: "Sonstiges - E-Books"}
+      - {id: 35, cat: Audio/Audiobook, desc: "Sonstiges - Audiobook"}
+      - {id: 36, cat: Other, desc: "Sonstiges - Diverses"}
+      # XXX
+      - {id: 46, cat: XXX, desc: "XXX - SD"}
+      - {id: 47, cat: XXX, desc: "XXX - HD"}
+      - {id: 45, cat: XXX, desc: "XXX - Pack"}
+      - {id: 49, cat: XXX, desc: "XXX - Sonstiges"}
+      - {id: 110, cat: XXX, desc: "XXX - Hentai Serie"}
+      - {id: 111, cat: XXX, desc: "XXX - Hentai Movie"}
+      - {id: 116, cat: XXX, desc: "XXX - SexBooks"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+  
+  login:
+    path: /login.php
+    method: form
+    form: form[action="/login.php"]
+    cookies: ["JAVA=OK"] # avoid jscheck redirect
+    captcha:
+      type: image
+      image: img[src^="cap/captcha_math.php"]
+      input: stringCaptcha
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      loggiin: "einloggen"
+    error:
+      - selector: div#login_error
+    test:
+      path: selection.php
+
+  download:
+    before:
+      path: "ajax_det_poll.php"
+      method: "post"
+      inputs:
+        set_thanks: "thanks"
+        det_id: "{{ .DownloadUri.Query.torrent }}"
+        ajax: "yes"
+
+  search:
+    path: selection.php
+    inputs:
+      search: "{{ .Keywords }}"
+      blah: "0"
+      orderby: "added"
+      sort: "desc"
+    rows:
+      selector: div.selection_wrap
+    fields:
+      download:
+        selector: a.selection_a
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?torrent="]
+      title:
+        selector: a.selection_a
+      details:
+        selector: a.selection_a
+        attribute: href
+      category:
+        selector: div.kat_cat_pic
+        case:
+          # Kino
+          ":has(div.kat_cat_pic_name:contains(\"Kino\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "118"
+          ":has(div.kat_cat_pic_name:contains(\"Kino\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "4"
+          # Movies
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"x264/XviD\"))": "18"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Pack SD/HD\"))": "2"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"DVD/HD2\"))": "22"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Kids\"))": "52"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "19"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"3D\"))": "25"
+          ":has(div.kat_cat_pic_name:contains(\"Movies\")):has(div.kat_cat_pic_name_b:contains(\"Blu-Ray\"))": "26"
+          # Serien
+          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "40"
+          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "41"
+          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Pack SD\"))": "42"
+          ":has(div.kat_cat_pic_name:contains(\"Serien\")):has(div.kat_cat_pic_name_b:contains(\"Pack HD\"))": "80"
+          # Musik
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"ALBEN\"))": "119"
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Mp3\"))": "5"
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Mixe\"))": "6"
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Discography\"))": "92"
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Musik Pack\"))": "114"
+          ":has(div.kat_cat_pic_name:contains(\"Musik\")):has(div.kat_cat_pic_name_b:contains(\"Video\"))": "48"
+          # Doku
+          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "37"
+          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "38"
+          ":has(div.kat_cat_pic_name:contains(\"Doku\")):has(div.kat_cat_pic_name_b:contains(\"Pack \"))": "81"
+          # Anime
+          ":has(div.kat_cat_pic_name:contains(\"Anime\")):has(div.kat_cat_pic_name_b:contains(\"Movies\"))": "73"
+          ":has(div.kat_cat_pic_name:contains(\"Anime\")):has(div.kat_cat_pic_name_b:contains(\"Serien\"))": "74"
+          # Games
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PC\"))": "16"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"Wimmelbild\"))": "14"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PSP\"))": "7"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"PS2/PS3\"))": "17"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"NDS/3DS\"))": "29"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"Wii\"))": "15"
+          ":has(div.kat_cat_pic_name:contains(\"Games\")):has(div.kat_cat_pic_name_b:contains(\"XboX \"))": "8"
+          # Appz
+          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Windows\"))": "30"
+          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Linux\"))": "31"
+          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Mac\"))": "32"
+          ":has(div.kat_cat_pic_name:contains(\"Appz\")):has(div.kat_cat_pic_name_b:contains(\"Android\"))": "106"
+          # Sport
+          ":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "43"
+          ":has(div.kat_cat_pic_name:contains(\"Sport\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "50"
+          # Sonstiges
+          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"E-Books\"))": "34"
+          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Audiobook\"))": "35"
+          ":has(div.kat_cat_pic_name:contains(\"Sonstiges\")):has(div.kat_cat_pic_name_b:contains(\"Diverses\"))": "36"
+          # XXX
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"SD\"))": "46"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"HD\"))": "47"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Pack\"))": "45"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Sonstiges\"))": "49"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Hentai Serie\"))": "110"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"Hentai Movie\"))": "111"
+          ":has(div.kat_cat_pic_name:contains(\"XXX\")):has(div.kat_cat_pic_name_b:contains(\"SexBooks\"))": "116"
+      banner:
+        selector: div[id^="details"] img
+        attribute: src
+      size:
+        selector: div.selection_unter_ad
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      grabs:
+        selector: div.selection_unter_ae
+        filters:
+          - name: trim
+            args: "x"
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      seeders:
+        selector: div.selection_unter_aa
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      leechers:
+        selector: div.selection_unter_aaa
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      downloadvolumefactor:
+        case:
+          ":root:has(div.onlyup)": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      date:
+        selector: div.selection_unter_ab
+        filters:
+          - name: replace
+            args: ["Heute", "Today"]
+          - name: replace
+            args: ["Gestern", "Yesterday"]
+          - name: replace
+            args: [" um", ""]
+          - name: dateparse
+            args: "02.01.2006 15:04:05"
+      description:
+        selector: selection_unter_af
+        optional: true
diff --git a/src/Jackett/Definitions/dreamteam.yml b/src/Jackett/Definitions/dreamteam.yml
index c1c12f72215c3aee68bb73c0d0da982a1463bc0c..96fdbe3afa0b1bad2618aa6fc58355a05fc4f367 100644
--- a/src/Jackett/Definitions/dreamteam.yml
+++ b/src/Jackett/Definitions/dreamteam.yml
@@ -1,320 +1,320 @@
----
-  site: dreamteam
-  name: Dream Team
-  language: el-gr
-  type: private
-  encoding: UTF-8
-  links:
-    - http://dream-team.ml/
-
-  caps:
-    categorymappings:
-#      - {id: 115, cat: , desc: ""}
-      - {id: 115, cat: Movies, desc: "One foreign films external subtitles"}
-      - {id: 130, cat: Movies, desc: "CAM / TS / TC"}
-      - {id: 131, cat: Movies, desc: "DVDSCR / PPVRiP / WebRip / R5"}
-      - {id: 132, cat: Movies, desc: "DVDRrip"}
-      - {id: 133, cat: Movies, desc: "BDRip / BRRip / HDRip"}
-      - {id: 134, cat: Movies, desc: "MicroHD"}
-      - {id: 135, cat: Movies, desc: "HD - WEB-DL"}
-      - {id: 136, cat: Movies, desc: "HD - 480p"}
-      - {id: 137, cat: Movies, desc: "HD - 720p"}
-      - {id: 138, cat: Movies, desc: "HD - 1080p"}
-      - {id: 139, cat: Movies, desc: "9.01 3D HD 720p Half SBS & OU"}
-      - {id: 140, cat: Movies, desc: "9.2 3D HD 1080p Half SBS & OU"}
-      - {id: 141, cat: Movies, desc: "9.3 3D Bluray Disc HD 720p / 1080p"}
-      - {id: 142, cat: Movies, desc: "9.4 3D MicroHD 720p / 1080p"}
-      - {id: 144, cat: Movies, desc: "9.5 packages"}
-      - {id: 145, cat: Movies, desc: "9.6 filmography"}
-      - {id: 143, cat: Movies, desc: "9.7 Tv Movies"}
-#      - {id: 130, cat: , desc: ""}
-#      - {id: 131, cat: , desc: ""}
-#      - {id: 132, cat: , desc: ""}
-#      - {id: 133, cat: , desc: ""}
-#      - {id: 134, cat: , desc: ""}
-#      - {id: 135, cat: , desc: ""}
-#      - {id: 136, cat: , desc: ""}
-#      - {id: 137, cat: , desc: ""}
-#      - {id: 138, cat: , desc: ""}
-#      - {id: 139, cat: , desc: ""}
-#      - {id: 140, cat: , desc: ""}
-#      - {id: 141, cat: , desc: ""}
-#      - {id: 142, cat: , desc: ""}
-#      - {id: 144, cat: , desc: ""}
-#      - {id: 145, cat: , desc: ""}
-#      - {id: 143, cat: , desc: ""}
-#      - {id: 116, cat: , desc: ""}
-      - {id: 116, cat: Movies, desc: "Two foreign films integrated subtitles"}
-      - {id: 146, cat: Movies, desc: "CAM / TS / TC"}
-      - {id: 147, cat: Movies, desc: "DVDSCR / PPVRiP / WebRip / R5"}
-      - {id: 148, cat: Movies, desc: "DVDRrip"}
-      - {id: 149, cat: Movies, desc: "BDRip / BRRip / HDRip"}
-      - {id: 150, cat: Movies, desc: "MicroHD"}
-      - {id: 151, cat: Movies, desc: "HD - WEB-DL"}
-      - {id: 152, cat: Movies, desc: "Tv Movies"}
-#      - {id: 242, cat: , desc: ""}
-      - {id: 153, cat: Movies, desc: "Packages"}
-      - {id: 154, cat: Movies, desc: "filmography"}
-      - {id: 243, cat: Movies, desc: "HD 1080p"}
-      - {id: 244, cat: Movies, desc: "HD 480p"}
-#      - {id: 146, cat: , desc: ""}
-#      - {id: 147, cat: , desc: ""}
-#      - {id: 148, cat: , desc: ""}
-#      - {id: 149, cat: , desc: ""}
-#      - {id: 150, cat: , desc: ""}
-#      - {id: 151, cat: , desc: ""}
-#      - {id: 152, cat: , desc: ""}
-#      - {id: 242, cat: , desc: ""}
-#      - {id: 153, cat: , desc: ""}
-#      - {id: 154, cat: , desc: ""}
-#      - {id: 243, cat: , desc: ""}
-#      - {id: 244, cat: , desc: ""}
-#      - {id: 117, cat: , desc: ""}
-      - {id: 117, cat: Movies, desc: "???????e? ?a???e?"}
-      - {id: 155, cat: Movies, desc: "CAM / TS / TC"}
-      - {id: 156, cat: Movies, desc: "SCR / PPVRiP / Webrip / R5"}
-      - {id: 157, cat: Movies, desc: "DVDRrip 3"}
-      - {id: 158, cat: Movies, desc: "BDRip / BRRip / HDRip"}
-      - {id: 159, cat: Movies, desc: "MicroHD 5"}
-      - {id: 160, cat: Movies, desc: "HD - 480p"}
-      - {id: 161, cat: Movies, desc: "6.1 HD - 720p"}
-      - {id: 162, cat: Movies, desc: "HD 6.2 - 1080"}
-      - {id: 163, cat: Movies, desc: "TV Movies"}
-      - {id: 164, cat: Movies, desc: "?a?eta 8"}
-      - {id: 165, cat: Movies, desc: "F??µ???af?e?"}
-#      - {id: 155, cat: , desc: ""}
-#      - {id: 156, cat: , desc: ""}
-#      - {id: 157, cat: , desc: ""}
-#      - {id: 158, cat: , desc: ""}
-#      - {id: 159, cat: , desc: ""}
-#      - {id: 160, cat: , desc: ""}
-#      - {id: 161, cat: , desc: ""}
-#      - {id: 162, cat: , desc: ""}
-#      - {id: 163, cat: , desc: ""}
-#      - {id: 164, cat: , desc: ""}
-#      - {id: 165, cat: , desc: ""}
-#      - {id: 118, cat: , desc: ""}
-      - {id: 118, cat: TV, desc: "Foreign Television external subtitles"}
-      - {id: 166, cat: TV, desc: "SD"}
-      - {id: 167, cat: TV, desc: "720p"}
-      - {id: 168, cat: TV, desc: "1080p"}
-      - {id: 169, cat: TV, desc: "Sport"}
-      - {id: 170, cat: TV, desc: "documentaries"}
-      - {id: 171, cat: TV, desc: "Packages"}
-#      - {id: 166, cat: , desc: ""}
-#      - {id: 167, cat: , desc: ""}
-#      - {id: 168, cat: , desc: ""}
-#      - {id: 169, cat: , desc: ""}
-#      - {id: 170, cat: , desc: ""}
-#      - {id: 171, cat: , desc: ""}
-#      - {id: 119, cat: , desc: ""}
-      - {id: 119, cat: TV, desc: "foreign Television integrated subtitles"}
-      - {id: 172, cat: TV, desc: "SD"}
-      - {id: 173, cat: TV, desc: "720p"}
-      - {id: 174, cat: TV, desc: "1080p"}
-      - {id: 175, cat: TV, desc: "Sport"}
-      - {id: 176, cat: TV, desc: "documentaries"}
-      - {id: 177, cat: TV, desc: "Tv Rips"}
-      - {id: 178, cat: TV, desc: "Packages"}
-#      - {id: 172, cat: , desc: ""}
-#      - {id: 173, cat: , desc: ""}
-#      - {id: 174, cat: , desc: ""}
-#      - {id: 175, cat: , desc: ""}
-#      - {id: 176, cat: , desc: ""}
-#      - {id: 177, cat: , desc: ""}
-#      - {id: 178, cat: , desc: ""}
-#      - {id: 120, cat: , desc: ""}
-      - {id: 120, cat: TV, desc: "Greek Television"}
-      - {id: 179, cat: TV, desc: "SD"}
-      - {id: 180, cat: TV, desc: "720p"}
-      - {id: 181, cat: TV, desc: "1080p"}
-      - {id: 182, cat: TV, desc: "Sport"}
-      - {id: 183, cat: TV, desc: "five documentaries"}
-      - {id: 184, cat: TV, desc: "six Tv Rips"}
-      - {id: 185, cat: TV, desc: "Packages"}
-#      - {id: 179, cat: , desc: ""}
-#      - {id: 180, cat: , desc: ""}
-#      - {id: 181, cat: , desc: ""}
-#      - {id: 182, cat: , desc: ""}
-#      - {id: 183, cat: , desc: ""}
-#      - {id: 184, cat: , desc: ""}
-#      - {id: 185, cat: , desc: ""}
-#      - {id: 122, cat: , desc: ""}
-      - {id: 122, cat: Audio, desc: "?e?? ???s???"}
-      - {id: 216, cat: Audio, desc: "1. DJs Stuff & Promos"}
-      - {id: 217, cat: Audio, desc: "2. DJs Stuff & Promos (Flac)"}
-      - {id: 218, cat: Audio, desc: "3. Singles"}
-      - {id: 219, cat: Audio, desc: "4. Singles (Flac)"}
-      - {id: 220, cat: Audio, desc: "5. ??s????af?e?"}
-      - {id: 221, cat: Audio, desc: "6. ??s????af?e? (Flac)"}
-      - {id: 222, cat: Audio, desc: "7. ??af??e? S?????e?"}
-      - {id: 223, cat: Audio, desc: "8. ??af??e? S?????e? (Flac)"}
-      - {id: 224, cat: Audio, desc: "9. SoundTracks"}
-      - {id: 225, cat: Audio, desc: "9.1 Varius Artist"}
-      - {id: 226, cat: Audio, desc: "9.2 Compact Disc Club"}
-      - {id: 227, cat: Audio, desc: "9.3 ???s??a Video Clips"}
-#      - {id: 123, cat: , desc: ""}
-      - {id: 123, cat: Audio, desc: "???????? ???s???"}
-      - {id: 228, cat: Audio, desc: "1. DJs Stuff & Promos"}
-      - {id: 229, cat: Audio, desc: "2. DJs Stuff & Promos (Flac)"}
-      - {id: 230, cat: Audio, desc: "3. Singles"}
-      - {id: 231, cat: Audio, desc: "4. Singles (Flac)"}
-      - {id: 232, cat: Audio, desc: "5. ??s????af?e?"}
-      - {id: 233, cat: Audio, desc: "6. ??s????af?e? (Flac)"}
-      - {id: 234, cat: Audio, desc: "7. ??af??e? S?????e?"}
-      - {id: 235, cat: Audio, desc: "8. ??af??e? S?????e? (Flac)"}
-      - {id: 236, cat: Audio, desc: "9. ?a?d??a"}
-      - {id: 237, cat: Audio, desc: "9.1 SoundTracks"}
-      - {id: 238, cat: Audio, desc: "9.2 Varius Artist"}
-      - {id: 239, cat: Audio, desc: "9.3 Compact Disc Club"}
-      - {id: 240, cat: Audio, desc: "9.4 ???s??a Video Clips"}
-#      - {id: 121, cat: , desc: ""}
-      - {id: 121, cat: Movies, desc: "children"}
-      - {id: 186, cat: Movies, desc: "children's films external subtitles"}
-      - {id: 187, cat: Movies, desc: "two children's films integrated subtitles"}
-      - {id: 188, cat: Movies, desc: "three children's films Metaglotismenes"}
-      - {id: 189, cat: Movies, desc: "four cartoon series external subtitles"}
-      - {id: 190, cat: Movies, desc: "five children's series integrated subtitles"}
-      - {id: 191, cat: Movies, desc: "six children's series Metaglotismenes"}
-      - {id: 192, cat: Movies, desc: "Anime external subtitles"}
-      - {id: 193, cat: Movies, desc: "Anime integrated subtitles"}
-      - {id: 194, cat: Movies, desc: "Anime Metaglotismenes"}
-#      - {id: 186, cat: , desc: ""}
-#      - {id: 187, cat: , desc: ""}
-#      - {id: 188, cat: , desc: ""}
-#      - {id: 189, cat: , desc: ""}
-#      - {id: 190, cat: , desc: ""}
-#      - {id: 191, cat: , desc: ""}
-#      - {id: 192, cat: , desc: ""}
-#      - {id: 193, cat: , desc: ""}
-#      - {id: 194, cat: , desc: ""}
-#      - {id: 128, cat: , desc: ""}
-      - {id: 128, cat: Console, desc: "9.1 ?a????d?a"}
-      - {id: 195, cat: Console, desc: "Windows Games"}
-      - {id: 196, cat: Console, desc: "Nintendo DS"}
-      - {id: 197, cat: Console, desc: "Sony PS1"}
-      - {id: 198, cat: Console, desc: "Sony PS2"}
-      - {id: 199, cat: Console, desc: "Sony PS3"}
-      - {id: 200, cat: Console, desc: "Sony PSP"}
-      - {id: 201, cat: Console, desc: "Wii"}
-      - {id: 202, cat: Console, desc: "XboX 360"}
-#      - {id: 124, cat: , desc: ""}
-      - {id: 124, cat: PC, desc: "9.2 Applications"}
-      - {id: 203, cat: PC, desc: "Applications Windows"}
-      - {id: 204, cat: PC, desc: "Applications Mac"}
-      - {id: 205, cat: PC, desc: "Linux Applications"}
-#      - {id: 203, cat: , desc: ""}
-#      - {id: 204, cat: , desc: ""}
-#      - {id: 205, cat: , desc: ""}
-#      - {id: 126, cat: , desc: ""}
-      - {id: 126, cat: Books, desc: "9.3 Electronic Books"}
-      - {id: 206, cat: Books, desc: "Electronic books"}
-      - {id: 207, cat: Books, desc: "Magazines"}
-      - {id: 208, cat: Books, desc: "Comic Books"}
-#      - {id: 206, cat: , desc: ""}
-#      - {id: 207, cat: , desc: ""}
-#      - {id: 208, cat: , desc: ""}
-#      - {id: 125, cat: , desc: ""}
-      - {id: 125, cat: Other, desc: "9.4 Gallery"}
-      - {id: 209, cat: Other, desc: "Gallery"}
-      - {id: 210, cat: Other, desc: "Gallery HD"}
-      - {id: 211, cat: Other, desc: "Photos 3D"}
-      - {id: 212, cat: Other, desc: "Wallpapers"}
-      - {id: 213, cat: Other, desc: "Screensavers"}
-#      - {id: 209, cat: , desc: ""}
-#      - {id: 210, cat: , desc: ""}
-#      - {id: 211, cat: , desc: ""}
-#      - {id: 212, cat: , desc: ""}
-#      - {id: 213, cat: , desc: ""}
-#      - {id: 127, cat: , desc: ""}
-      - {id: 127, cat: PC/Phone-Other, desc: "9.5 Mobile / Miscellaneous"}
-      - {id: 214, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 215, cat: PC/Phone-Other, desc: "Miscellaneous"}
-#      - {id: 214, cat: , desc: ""}
-#      - {id: 215, cat: , desc: ""}
-#      - {id: 129, cat: , desc: ""}
-      - {id: 129, cat: Other, desc: "9.6 Blocked DREAM TEAM"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-  
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td:contains("remaining tries")
-    test:
-      path: browse.php
-      selector: a[href^="http://dream-team.ml/logout.php"]
-
-  download:
-    before:
-      path: "takethanks.php"
-      method: "post"
-      inputs:
-        torrentid: "{{ .DownloadUri.Query.id }}"
-      
-  search:
-    path: browse.php
-    keywordsfilters:
-      # remove words <= 3 characters and surrounding special characters
-      - name: re_replace
-        args: ["(?:^|\\s)[_\\+\\/\\.\\-\\(\\)]*[\\S]{0,3}[_\\+\\/\\.\\-\\(\\)]*(?:\\s|$)", " "]
-    inputs:
-      do: "search"
-      keywords: "{{ .Keywords }}"
-      search_type: "t_name"
-      category: "0" # multi cat search not supported
-      include_dead_torrents: "yes"
-    rows:
-      selector: table#sortabletable > tbody > tr:has(a[href^="http://dream-team.ml/details.php?id="])
-      filters:
-        - name: andmatch
-          args: 66
-    fields:
-      download:
-        selector: a[href^="http://dream-team.ml/download.php?id="]
-        attribute: href
-      title:
-        selector: a[href^="http://dream-team.ml/details.php?id="]
-      title|optional:
-        selector: div.tooltip-content > div
-      details:
-        selector: a[href^="http://dream-team.ml/details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="http://dream-team.ml/browse.php?category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      banner|optional:
-        selector: div.tooltip-content > img
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          img[alt^="Free Torrent "]: "0"
-          img[alt^="Silver Torrent "]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      date:
-        selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
-        remove: span
-        filters:
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "02-01-2006 15:04 -07:00"
+---
+  site: dreamteam
+  name: Dream Team
+  language: el-gr
+  type: private
+  encoding: UTF-8
+  links:
+    - http://dream-team.ml/
+
+  caps:
+    categorymappings:
+#      - {id: 115, cat: , desc: ""}
+      - {id: 115, cat: Movies, desc: "One foreign films external subtitles"}
+      - {id: 130, cat: Movies, desc: "CAM / TS / TC"}
+      - {id: 131, cat: Movies, desc: "DVDSCR / PPVRiP / WebRip / R5"}
+      - {id: 132, cat: Movies, desc: "DVDRrip"}
+      - {id: 133, cat: Movies, desc: "BDRip / BRRip / HDRip"}
+      - {id: 134, cat: Movies, desc: "MicroHD"}
+      - {id: 135, cat: Movies, desc: "HD - WEB-DL"}
+      - {id: 136, cat: Movies, desc: "HD - 480p"}
+      - {id: 137, cat: Movies, desc: "HD - 720p"}
+      - {id: 138, cat: Movies, desc: "HD - 1080p"}
+      - {id: 139, cat: Movies, desc: "9.01 3D HD 720p Half SBS & OU"}
+      - {id: 140, cat: Movies, desc: "9.2 3D HD 1080p Half SBS & OU"}
+      - {id: 141, cat: Movies, desc: "9.3 3D Bluray Disc HD 720p / 1080p"}
+      - {id: 142, cat: Movies, desc: "9.4 3D MicroHD 720p / 1080p"}
+      - {id: 144, cat: Movies, desc: "9.5 packages"}
+      - {id: 145, cat: Movies, desc: "9.6 filmography"}
+      - {id: 143, cat: Movies, desc: "9.7 Tv Movies"}
+#      - {id: 130, cat: , desc: ""}
+#      - {id: 131, cat: , desc: ""}
+#      - {id: 132, cat: , desc: ""}
+#      - {id: 133, cat: , desc: ""}
+#      - {id: 134, cat: , desc: ""}
+#      - {id: 135, cat: , desc: ""}
+#      - {id: 136, cat: , desc: ""}
+#      - {id: 137, cat: , desc: ""}
+#      - {id: 138, cat: , desc: ""}
+#      - {id: 139, cat: , desc: ""}
+#      - {id: 140, cat: , desc: ""}
+#      - {id: 141, cat: , desc: ""}
+#      - {id: 142, cat: , desc: ""}
+#      - {id: 144, cat: , desc: ""}
+#      - {id: 145, cat: , desc: ""}
+#      - {id: 143, cat: , desc: ""}
+#      - {id: 116, cat: , desc: ""}
+      - {id: 116, cat: Movies, desc: "Two foreign films integrated subtitles"}
+      - {id: 146, cat: Movies, desc: "CAM / TS / TC"}
+      - {id: 147, cat: Movies, desc: "DVDSCR / PPVRiP / WebRip / R5"}
+      - {id: 148, cat: Movies, desc: "DVDRrip"}
+      - {id: 149, cat: Movies, desc: "BDRip / BRRip / HDRip"}
+      - {id: 150, cat: Movies, desc: "MicroHD"}
+      - {id: 151, cat: Movies, desc: "HD - WEB-DL"}
+      - {id: 152, cat: Movies, desc: "Tv Movies"}
+#      - {id: 242, cat: , desc: ""}
+      - {id: 153, cat: Movies, desc: "Packages"}
+      - {id: 154, cat: Movies, desc: "filmography"}
+      - {id: 243, cat: Movies, desc: "HD 1080p"}
+      - {id: 244, cat: Movies, desc: "HD 480p"}
+#      - {id: 146, cat: , desc: ""}
+#      - {id: 147, cat: , desc: ""}
+#      - {id: 148, cat: , desc: ""}
+#      - {id: 149, cat: , desc: ""}
+#      - {id: 150, cat: , desc: ""}
+#      - {id: 151, cat: , desc: ""}
+#      - {id: 152, cat: , desc: ""}
+#      - {id: 242, cat: , desc: ""}
+#      - {id: 153, cat: , desc: ""}
+#      - {id: 154, cat: , desc: ""}
+#      - {id: 243, cat: , desc: ""}
+#      - {id: 244, cat: , desc: ""}
+#      - {id: 117, cat: , desc: ""}
+      - {id: 117, cat: Movies, desc: "???????e? ?a???e?"}
+      - {id: 155, cat: Movies, desc: "CAM / TS / TC"}
+      - {id: 156, cat: Movies, desc: "SCR / PPVRiP / Webrip / R5"}
+      - {id: 157, cat: Movies, desc: "DVDRrip 3"}
+      - {id: 158, cat: Movies, desc: "BDRip / BRRip / HDRip"}
+      - {id: 159, cat: Movies, desc: "MicroHD 5"}
+      - {id: 160, cat: Movies, desc: "HD - 480p"}
+      - {id: 161, cat: Movies, desc: "6.1 HD - 720p"}
+      - {id: 162, cat: Movies, desc: "HD 6.2 - 1080"}
+      - {id: 163, cat: Movies, desc: "TV Movies"}
+      - {id: 164, cat: Movies, desc: "?a?eta 8"}
+      - {id: 165, cat: Movies, desc: "F??µ???af?e?"}
+#      - {id: 155, cat: , desc: ""}
+#      - {id: 156, cat: , desc: ""}
+#      - {id: 157, cat: , desc: ""}
+#      - {id: 158, cat: , desc: ""}
+#      - {id: 159, cat: , desc: ""}
+#      - {id: 160, cat: , desc: ""}
+#      - {id: 161, cat: , desc: ""}
+#      - {id: 162, cat: , desc: ""}
+#      - {id: 163, cat: , desc: ""}
+#      - {id: 164, cat: , desc: ""}
+#      - {id: 165, cat: , desc: ""}
+#      - {id: 118, cat: , desc: ""}
+      - {id: 118, cat: TV, desc: "Foreign Television external subtitles"}
+      - {id: 166, cat: TV, desc: "SD"}
+      - {id: 167, cat: TV, desc: "720p"}
+      - {id: 168, cat: TV, desc: "1080p"}
+      - {id: 169, cat: TV, desc: "Sport"}
+      - {id: 170, cat: TV, desc: "documentaries"}
+      - {id: 171, cat: TV, desc: "Packages"}
+#      - {id: 166, cat: , desc: ""}
+#      - {id: 167, cat: , desc: ""}
+#      - {id: 168, cat: , desc: ""}
+#      - {id: 169, cat: , desc: ""}
+#      - {id: 170, cat: , desc: ""}
+#      - {id: 171, cat: , desc: ""}
+#      - {id: 119, cat: , desc: ""}
+      - {id: 119, cat: TV, desc: "foreign Television integrated subtitles"}
+      - {id: 172, cat: TV, desc: "SD"}
+      - {id: 173, cat: TV, desc: "720p"}
+      - {id: 174, cat: TV, desc: "1080p"}
+      - {id: 175, cat: TV, desc: "Sport"}
+      - {id: 176, cat: TV, desc: "documentaries"}
+      - {id: 177, cat: TV, desc: "Tv Rips"}
+      - {id: 178, cat: TV, desc: "Packages"}
+#      - {id: 172, cat: , desc: ""}
+#      - {id: 173, cat: , desc: ""}
+#      - {id: 174, cat: , desc: ""}
+#      - {id: 175, cat: , desc: ""}
+#      - {id: 176, cat: , desc: ""}
+#      - {id: 177, cat: , desc: ""}
+#      - {id: 178, cat: , desc: ""}
+#      - {id: 120, cat: , desc: ""}
+      - {id: 120, cat: TV, desc: "Greek Television"}
+      - {id: 179, cat: TV, desc: "SD"}
+      - {id: 180, cat: TV, desc: "720p"}
+      - {id: 181, cat: TV, desc: "1080p"}
+      - {id: 182, cat: TV, desc: "Sport"}
+      - {id: 183, cat: TV, desc: "five documentaries"}
+      - {id: 184, cat: TV, desc: "six Tv Rips"}
+      - {id: 185, cat: TV, desc: "Packages"}
+#      - {id: 179, cat: , desc: ""}
+#      - {id: 180, cat: , desc: ""}
+#      - {id: 181, cat: , desc: ""}
+#      - {id: 182, cat: , desc: ""}
+#      - {id: 183, cat: , desc: ""}
+#      - {id: 184, cat: , desc: ""}
+#      - {id: 185, cat: , desc: ""}
+#      - {id: 122, cat: , desc: ""}
+      - {id: 122, cat: Audio, desc: "?e?? ???s???"}
+      - {id: 216, cat: Audio, desc: "1. DJs Stuff & Promos"}
+      - {id: 217, cat: Audio, desc: "2. DJs Stuff & Promos (Flac)"}
+      - {id: 218, cat: Audio, desc: "3. Singles"}
+      - {id: 219, cat: Audio, desc: "4. Singles (Flac)"}
+      - {id: 220, cat: Audio, desc: "5. ??s????af?e?"}
+      - {id: 221, cat: Audio, desc: "6. ??s????af?e? (Flac)"}
+      - {id: 222, cat: Audio, desc: "7. ??af??e? S?????e?"}
+      - {id: 223, cat: Audio, desc: "8. ??af??e? S?????e? (Flac)"}
+      - {id: 224, cat: Audio, desc: "9. SoundTracks"}
+      - {id: 225, cat: Audio, desc: "9.1 Varius Artist"}
+      - {id: 226, cat: Audio, desc: "9.2 Compact Disc Club"}
+      - {id: 227, cat: Audio, desc: "9.3 ???s??a Video Clips"}
+#      - {id: 123, cat: , desc: ""}
+      - {id: 123, cat: Audio, desc: "???????? ???s???"}
+      - {id: 228, cat: Audio, desc: "1. DJs Stuff & Promos"}
+      - {id: 229, cat: Audio, desc: "2. DJs Stuff & Promos (Flac)"}
+      - {id: 230, cat: Audio, desc: "3. Singles"}
+      - {id: 231, cat: Audio, desc: "4. Singles (Flac)"}
+      - {id: 232, cat: Audio, desc: "5. ??s????af?e?"}
+      - {id: 233, cat: Audio, desc: "6. ??s????af?e? (Flac)"}
+      - {id: 234, cat: Audio, desc: "7. ??af??e? S?????e?"}
+      - {id: 235, cat: Audio, desc: "8. ??af??e? S?????e? (Flac)"}
+      - {id: 236, cat: Audio, desc: "9. ?a?d??a"}
+      - {id: 237, cat: Audio, desc: "9.1 SoundTracks"}
+      - {id: 238, cat: Audio, desc: "9.2 Varius Artist"}
+      - {id: 239, cat: Audio, desc: "9.3 Compact Disc Club"}
+      - {id: 240, cat: Audio, desc: "9.4 ???s??a Video Clips"}
+#      - {id: 121, cat: , desc: ""}
+      - {id: 121, cat: Movies, desc: "children"}
+      - {id: 186, cat: Movies, desc: "children's films external subtitles"}
+      - {id: 187, cat: Movies, desc: "two children's films integrated subtitles"}
+      - {id: 188, cat: Movies, desc: "three children's films Metaglotismenes"}
+      - {id: 189, cat: Movies, desc: "four cartoon series external subtitles"}
+      - {id: 190, cat: Movies, desc: "five children's series integrated subtitles"}
+      - {id: 191, cat: Movies, desc: "six children's series Metaglotismenes"}
+      - {id: 192, cat: Movies, desc: "Anime external subtitles"}
+      - {id: 193, cat: Movies, desc: "Anime integrated subtitles"}
+      - {id: 194, cat: Movies, desc: "Anime Metaglotismenes"}
+#      - {id: 186, cat: , desc: ""}
+#      - {id: 187, cat: , desc: ""}
+#      - {id: 188, cat: , desc: ""}
+#      - {id: 189, cat: , desc: ""}
+#      - {id: 190, cat: , desc: ""}
+#      - {id: 191, cat: , desc: ""}
+#      - {id: 192, cat: , desc: ""}
+#      - {id: 193, cat: , desc: ""}
+#      - {id: 194, cat: , desc: ""}
+#      - {id: 128, cat: , desc: ""}
+      - {id: 128, cat: Console, desc: "9.1 ?a????d?a"}
+      - {id: 195, cat: Console, desc: "Windows Games"}
+      - {id: 196, cat: Console, desc: "Nintendo DS"}
+      - {id: 197, cat: Console, desc: "Sony PS1"}
+      - {id: 198, cat: Console, desc: "Sony PS2"}
+      - {id: 199, cat: Console, desc: "Sony PS3"}
+      - {id: 200, cat: Console, desc: "Sony PSP"}
+      - {id: 201, cat: Console, desc: "Wii"}
+      - {id: 202, cat: Console, desc: "XboX 360"}
+#      - {id: 124, cat: , desc: ""}
+      - {id: 124, cat: PC, desc: "9.2 Applications"}
+      - {id: 203, cat: PC, desc: "Applications Windows"}
+      - {id: 204, cat: PC, desc: "Applications Mac"}
+      - {id: 205, cat: PC, desc: "Linux Applications"}
+#      - {id: 203, cat: , desc: ""}
+#      - {id: 204, cat: , desc: ""}
+#      - {id: 205, cat: , desc: ""}
+#      - {id: 126, cat: , desc: ""}
+      - {id: 126, cat: Books, desc: "9.3 Electronic Books"}
+      - {id: 206, cat: Books, desc: "Electronic books"}
+      - {id: 207, cat: Books, desc: "Magazines"}
+      - {id: 208, cat: Books, desc: "Comic Books"}
+#      - {id: 206, cat: , desc: ""}
+#      - {id: 207, cat: , desc: ""}
+#      - {id: 208, cat: , desc: ""}
+#      - {id: 125, cat: , desc: ""}
+      - {id: 125, cat: Other, desc: "9.4 Gallery"}
+      - {id: 209, cat: Other, desc: "Gallery"}
+      - {id: 210, cat: Other, desc: "Gallery HD"}
+      - {id: 211, cat: Other, desc: "Photos 3D"}
+      - {id: 212, cat: Other, desc: "Wallpapers"}
+      - {id: 213, cat: Other, desc: "Screensavers"}
+#      - {id: 209, cat: , desc: ""}
+#      - {id: 210, cat: , desc: ""}
+#      - {id: 211, cat: , desc: ""}
+#      - {id: 212, cat: , desc: ""}
+#      - {id: 213, cat: , desc: ""}
+#      - {id: 127, cat: , desc: ""}
+      - {id: 127, cat: PC/Phone-Other, desc: "9.5 Mobile / Miscellaneous"}
+      - {id: 214, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 215, cat: PC/Phone-Other, desc: "Miscellaneous"}
+#      - {id: 214, cat: , desc: ""}
+#      - {id: 215, cat: , desc: ""}
+#      - {id: 129, cat: , desc: ""}
+      - {id: 129, cat: Other, desc: "9.6 Blocked DREAM TEAM"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+  
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td:contains("remaining tries")
+    test:
+      path: browse.php
+      selector: a[href^="http://dream-team.ml/logout.php"]
+
+  download:
+    before:
+      path: "takethanks.php"
+      method: "post"
+      inputs:
+        torrentid: "{{ .DownloadUri.Query.id }}"
+      
+  search:
+    path: browse.php
+    keywordsfilters:
+      # remove words <= 3 characters and surrounding special characters
+      - name: re_replace
+        args: ["(?:^|\\s)[_\\+\\/\\.\\-\\(\\)]*[\\S]{0,3}[_\\+\\/\\.\\-\\(\\)]*(?:\\s|$)", " "]
+    inputs:
+      do: "search"
+      keywords: "{{ .Keywords }}"
+      search_type: "t_name"
+      category: "0" # multi cat search not supported
+      include_dead_torrents: "yes"
+    rows:
+      selector: table#sortabletable > tbody > tr:has(a[href^="http://dream-team.ml/details.php?id="])
+      filters:
+        - name: andmatch
+          args: 66
+    fields:
+      download:
+        selector: a[href^="http://dream-team.ml/download.php?id="]
+        attribute: href
+      title:
+        selector: a[href^="http://dream-team.ml/details.php?id="]
+      title|optional:
+        selector: div.tooltip-content > div
+      details:
+        selector: a[href^="http://dream-team.ml/details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="http://dream-team.ml/browse.php?category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      banner|optional:
+        selector: div.tooltip-content > img
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          img[alt^="Free Torrent "]: "0"
+          img[alt^="Silver Torrent "]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      date:
+        selector: "td:nth-child(2) > div:has(span[style=\"float: right;\"])"
+        remove: span
+        filters:
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "02-01-2006 15:04 -07:00"
diff --git a/src/Jackett/Definitions/eotforum.yml b/src/Jackett/Definitions/eotforum.yml
index bee3f7f84554357e07d6a7fb00f016e5f95acbc7..61c300a64157b48df2c0e8589e2cb78519e06b8f 100644
--- a/src/Jackett/Definitions/eotforum.yml
+++ b/src/Jackett/Definitions/eotforum.yml
@@ -1,180 +1,180 @@
----
-  site: eotforum
-  name: EoT-Forum
-  description: "A German gerneral tracker"
-  language: de-de
-  type: private
-  encoding: windows-1252
-  links:
-    - http://eot-forum.net
-
-  caps:
-    categorymappings:
-      # Filme
-      - {id: 14, cat: Movies/SD, desc: "SD XviD"}
-      - {id: 15, cat: Movies/SD, desc: "SD x264"}
-      - {id: 16, cat: Movies/HD, desc: "HD"}
-      - {id: 68, cat: Movies/HD, desc: "UHD"}
-      - {id: 17, cat: Movies/3D, desc: "3D"}
-      - {id: 18, cat: Movies/DVD, desc: "DVD-R"}
-      - {id: 19, cat: Movies, desc: "Pack"}
-      - {id: 20, cat: Movies, desc: "International"}
-      - {id: 21, cat: XXX, desc: "XXX"}
-
-      # Serien/TV
-      - {id: 23, cat: TV/SD, desc: "SD XviD"}
-      - {id: 24, cat: TV/SD, desc: "SD x264"}
-      - {id: 25, cat: TV/HD, desc: "HD"}
-      - {id: 26, cat: TV/SD, desc: "DVD-R"}
-      - {id: 27, cat: TV, desc: "Pack"}
-      - {id: 28, cat: TV, desc: "International"}
-      - {id: 29, cat: TV/Sport, desc: "Sport"}
-
-      # Dokus
-      - {id: 31, cat: TV/Documentary, desc: "SD XviD"}
-      - {id: 32, cat: TV/Documentary, desc: "SD x264"}
-      - {id: 33, cat: TV/Documentary, desc: "HD"}
-      - {id: 34, cat: TV/Documentary, desc: "3D"}
-      - {id: 35, cat: TV/Documentary, desc: "Pack"}
-      - {id: 67, cat: TV/Documentary, desc: "DVD-R"}
-      - {id: 36, cat: TV/Documentary, desc: "International"}
-
-      # Audio
-      - {id: 38, cat: Audio, desc: "Charts"}
-      - {id: 39, cat: Audio/MP3, desc: "MP3"}
-      - {id: 40, cat: Audio/Lossless, desc: "Flac"}
-      - {id: 41, cat: Audio, desc: "Pack"}
-      - {id: 42, cat: Audio/Video, desc: "MusikVideo"}
-      - {id: 43, cat: Audio/Audiobook, desc: "Hörbücher"}
-
-      # Spiele
-      - {id: 45, cat: PC/Games, desc: "Windows"}
-      - {id: 46, cat: PC/Mac, desc: "MacOS"}
-      - {id: 47, cat: Console/PS4, desc: "Sony PS"}
-      - {id: 48, cat: Console/Xbox , desc: "Microsoft XBox"}
-      - {id: 49, cat: Console/NDS, desc: "Nintendo"}
-      - {id: 50, cat: PC/Games, desc: "Linux"}
-      - {id: 51, cat: Console, desc: "Andere"}
-
-      # Software
-      - {id: 53, cat: PC, desc: "Windows"}
-      - {id: 54, cat: PC/Mac, desc: "MacOS"}
-      - {id: 55, cat: PC, desc: "Linux"}
-      - {id: 56, cat: PC/Phone-Android, desc: "Android"}
-      - {id: 57, cat: PC/Phone-IOS, desc: "Apple IOS"}
-      - {id: 58, cat: PC/Phone-Other, desc: "Andere"}
-
-      # Sonstiges
-      - {id: 60, cat: Books, desc: "EBooks"}
-      - {id: 61, cat: Other, desc: "Bilder"}
-      - {id: 62, cat: TV/Anime, desc: "Anime"}
-      - {id: 63, cat: Other, desc: "MISC"}
-      - {id: 64, cat: XXX, desc: "XXX-Bilder/EBooks/Audio"}
-
-      # EOT-Specials
-      - {id: 66, cat: Other, desc: "Special"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: index.php?page=login
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-      rememberme: "forever"
-      submit: "Login"
-    error:
-    - selector: td.lista[align="center"][colspan="2"] > span
-    test:
-      path: index.php
-      selector: img[alt="Ratio"]
-
-  ratio:
-    path: index.php
-    selector: img[alt="Ratio"] + font
-
-  search:
-    path: index.php
-    inputs:
-      page: "torrents"
-      search: "{{ .Query.Keywords }}"
-      options: "0"
-      active: "0"
-      gold: "0"
-    rows:
-      selector: table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
-      dateheaders:
-        selector: ":has(td.header > b)"
-        filters:
-          - name: replace
-            args: ["Torrents vom ", ""]
-          - name: replace
-            args: ["Januar", "January"]
-          - name: replace
-            args: ["Februar", "February"]
-          - name: replace
-            args: ["März", "March"]
-          - name: replace
-            args: ["Mai", "May"]
-          - name: replace
-            args: ["Juni", "June"]
-          - name: replace
-            args: ["Juli", "July"]
-          - name: replace
-            args: ["Oktober", "October"]
-          - name: replace
-            args: ["Dezember", "December"]
-          - name: dateparse
-            args: "02.January.2006"
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: a[href^="index.php?page=torrent-details&id="]
-        attribute: title
-        filters:
-          - name: replace
-            args: ["Details anzeigen: ", ""]
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      comments:
-        selector: a[href*="#comments"]
-        attribute: href
-      size:
-        selector: td:nth-child(3)
-      grabs:
-        selector: td:nth-child(5)
-        filters:
-          - name: split
-            args: ["♦", 2]
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: td:nth-child(5) > a:nth-child(1)
-      leechers:
-        selector: td:nth-child(5) > a:nth-child(2)
-      downloadvolumefactor:
-        case:
-          img[alt="gold"]: "0"
-          img[alt="silver"]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt="2x Upload Multiplier"]: "2"
-          img[alt="3x Upload Multiplier"]: "3"
-          img[alt="4x Upload Multiplier"]: "4"
-          img[alt="5x Upload Multiplier"]: "5"
-          img[alt="6x Upload Multiplier"]: "6"
-          img[alt="7x Upload Multiplier"]: "7"
-          img[alt="8x Upload Multiplier"]: "8"
-          img[alt="9x Upload Multiplier"]: "9"
-          img[alt="10x Upload Multiplier"]: "10"
-          "*": "1"
+---
+  site: eotforum
+  name: EoT-Forum
+  description: "A German gerneral tracker"
+  language: de-de
+  type: private
+  encoding: windows-1252
+  links:
+    - http://eot-forum.net
+
+  caps:
+    categorymappings:
+      # Filme
+      - {id: 14, cat: Movies/SD, desc: "SD XviD"}
+      - {id: 15, cat: Movies/SD, desc: "SD x264"}
+      - {id: 16, cat: Movies/HD, desc: "HD"}
+      - {id: 68, cat: Movies/HD, desc: "UHD"}
+      - {id: 17, cat: Movies/3D, desc: "3D"}
+      - {id: 18, cat: Movies/DVD, desc: "DVD-R"}
+      - {id: 19, cat: Movies, desc: "Pack"}
+      - {id: 20, cat: Movies, desc: "International"}
+      - {id: 21, cat: XXX, desc: "XXX"}
+
+      # Serien/TV
+      - {id: 23, cat: TV/SD, desc: "SD XviD"}
+      - {id: 24, cat: TV/SD, desc: "SD x264"}
+      - {id: 25, cat: TV/HD, desc: "HD"}
+      - {id: 26, cat: TV/SD, desc: "DVD-R"}
+      - {id: 27, cat: TV, desc: "Pack"}
+      - {id: 28, cat: TV, desc: "International"}
+      - {id: 29, cat: TV/Sport, desc: "Sport"}
+
+      # Dokus
+      - {id: 31, cat: TV/Documentary, desc: "SD XviD"}
+      - {id: 32, cat: TV/Documentary, desc: "SD x264"}
+      - {id: 33, cat: TV/Documentary, desc: "HD"}
+      - {id: 34, cat: TV/Documentary, desc: "3D"}
+      - {id: 35, cat: TV/Documentary, desc: "Pack"}
+      - {id: 67, cat: TV/Documentary, desc: "DVD-R"}
+      - {id: 36, cat: TV/Documentary, desc: "International"}
+
+      # Audio
+      - {id: 38, cat: Audio, desc: "Charts"}
+      - {id: 39, cat: Audio/MP3, desc: "MP3"}
+      - {id: 40, cat: Audio/Lossless, desc: "Flac"}
+      - {id: 41, cat: Audio, desc: "Pack"}
+      - {id: 42, cat: Audio/Video, desc: "MusikVideo"}
+      - {id: 43, cat: Audio/Audiobook, desc: "Hörbücher"}
+
+      # Spiele
+      - {id: 45, cat: PC/Games, desc: "Windows"}
+      - {id: 46, cat: PC/Mac, desc: "MacOS"}
+      - {id: 47, cat: Console/PS4, desc: "Sony PS"}
+      - {id: 48, cat: Console/Xbox , desc: "Microsoft XBox"}
+      - {id: 49, cat: Console/NDS, desc: "Nintendo"}
+      - {id: 50, cat: PC/Games, desc: "Linux"}
+      - {id: 51, cat: Console, desc: "Andere"}
+
+      # Software
+      - {id: 53, cat: PC, desc: "Windows"}
+      - {id: 54, cat: PC/Mac, desc: "MacOS"}
+      - {id: 55, cat: PC, desc: "Linux"}
+      - {id: 56, cat: PC/Phone-Android, desc: "Android"}
+      - {id: 57, cat: PC/Phone-IOS, desc: "Apple IOS"}
+      - {id: 58, cat: PC/Phone-Other, desc: "Andere"}
+
+      # Sonstiges
+      - {id: 60, cat: Books, desc: "EBooks"}
+      - {id: 61, cat: Other, desc: "Bilder"}
+      - {id: 62, cat: TV/Anime, desc: "Anime"}
+      - {id: 63, cat: Other, desc: "MISC"}
+      - {id: 64, cat: XXX, desc: "XXX-Bilder/EBooks/Audio"}
+
+      # EOT-Specials
+      - {id: 66, cat: Other, desc: "Special"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: index.php?page=login
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+      rememberme: "forever"
+      submit: "Login"
+    error:
+    - selector: td.lista[align="center"][colspan="2"] > span
+    test:
+      path: index.php
+      selector: img[alt="Ratio"]
+
+  ratio:
+    path: index.php
+    selector: img[alt="Ratio"] + font
+
+  search:
+    path: index.php
+    inputs:
+      page: "torrents"
+      search: "{{ .Query.Keywords }}"
+      options: "0"
+      active: "0"
+      gold: "0"
+    rows:
+      selector: table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
+      dateheaders:
+        selector: ":has(td.header > b)"
+        filters:
+          - name: replace
+            args: ["Torrents vom ", ""]
+          - name: replace
+            args: ["Januar", "January"]
+          - name: replace
+            args: ["Februar", "February"]
+          - name: replace
+            args: ["März", "March"]
+          - name: replace
+            args: ["Mai", "May"]
+          - name: replace
+            args: ["Juni", "June"]
+          - name: replace
+            args: ["Juli", "July"]
+          - name: replace
+            args: ["Oktober", "October"]
+          - name: replace
+            args: ["Dezember", "December"]
+          - name: dateparse
+            args: "02.January.2006"
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: a[href^="index.php?page=torrent-details&id="]
+        attribute: title
+        filters:
+          - name: replace
+            args: ["Details anzeigen: ", ""]
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      comments:
+        selector: a[href*="#comments"]
+        attribute: href
+      size:
+        selector: td:nth-child(3)
+      grabs:
+        selector: td:nth-child(5)
+        filters:
+          - name: split
+            args: ["♦", 2]
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: td:nth-child(5) > a:nth-child(1)
+      leechers:
+        selector: td:nth-child(5) > a:nth-child(2)
+      downloadvolumefactor:
+        case:
+          img[alt="gold"]: "0"
+          img[alt="silver"]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt="2x Upload Multiplier"]: "2"
+          img[alt="3x Upload Multiplier"]: "3"
+          img[alt="4x Upload Multiplier"]: "4"
+          img[alt="5x Upload Multiplier"]: "5"
+          img[alt="6x Upload Multiplier"]: "6"
+          img[alt="7x Upload Multiplier"]: "7"
+          img[alt="8x Upload Multiplier"]: "8"
+          img[alt="9x Upload Multiplier"]: "9"
+          img[alt="10x Upload Multiplier"]: "10"
+          "*": "1"
diff --git a/src/Jackett/Definitions/estone.yml b/src/Jackett/Definitions/estone.yml
index a9115bf469126cc58b44a34905562779e152049a..c816bf4ddc2d6b838053e90bb8c4a36ce6b936ad 100644
--- a/src/Jackett/Definitions/estone.yml
+++ b/src/Jackett/Definitions/estone.yml
@@ -1,119 +1,119 @@
----
-  site: estone
-  name: eStone
-  language: hu-hu
-  type: private
-  encoding: UTF-8
-  links:
-    - http://estone.cc/
-
-  caps:
-    categorymappings:
-      - {id: 24, cat: Movies/SD, desc: "Film/XviD/Hun"}
-      - {id: 38, cat: Movies/SD, desc: "Film/XviD/Eng"}
-      - {id: 51, cat: Movies/SD, desc: "Film/SD/Hun"}
-      - {id: 52, cat: Movies/SD, desc: "Film/SD/Eng"}
-      - {id: 25, cat: Movies/DVD, desc: "Film/DVD/Hun"}
-      - {id: 26, cat: Movies/DVD, desc: "Film/DVD/Eng"}
-      - {id: 42, cat: Movies/HD, desc: "Film/HD/Hun"}
-      - {id: 50, cat: Movies/HD, desc: "Film/HD/Eng"}
-      - {id: 36, cat: TV, desc: "Sorozat/Hun"}
-      - {id: 47, cat: TV, desc: "Sorozat/Eng"}
-      - {id: 41, cat: Audio/MP3, desc: "Mp3/Hun"}
-      - {id: 40, cat: Audio/MP3, desc: "Mp3/Eng"}
-      - {id: 35, cat: PC/0day, desc: "Program"}
-      - {id: 28, cat: PC/Games, desc: "Játék/ISO"}
-      - {id: 30, cat: PC/Games, desc: "Játék/Rip"}
-      - {id: 32, cat: Console, desc: "Konzol"}
-      - {id: 34, cat: PC/Phone-Other, desc: "Mobil"}
-      - {id: 44, cat: Books, desc: "Könyv/Hun"}
-      - {id: 33, cat: Books, desc: "Könyv/Eng"}
-      - {id: 31, cat: Other, desc: "Képek"}
-      - {id: 39, cat: XXX, desc: "XXX/Film"}
-      - {id: 49, cat: XXX/Imageset, desc: "XXX/Kép"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      login_username: "{{ .Config.username }}"
-      login_password: "{{ .Config.password }}"
-    error:
-      - selector: script:contains("hiba(\"")
-        message:
-          selector: script:contains("hiba(\"")
-          filters:
-            - name: replace
-              args: ["hiba(\"", ""]
-            - name: replace
-              args: ["\");", ""]
-    test:
-      path: /letoltes.php
-
-  search:
-    path: /letoltes.php
-    method: get
-    inputs:
-      $raw: "{{range .Categories}}kat[]={{.}}&{{end}}"
-      kereses_nev: "{{ .Query.Keywords }}"
-    rows:
-      selector: body > div[id^="torrent_"]
-    fields:
-      title:
-        selector: a[title]
-        attribute: title
-      category:
-        selector: div#kategoria_torrent > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        attribute: id
-        filters:
-          - name: replace
-            args: ["torrent_", "adatlap.php?id="]
-      download:
-        attribute: id
-        filters:
-          - name: replace
-            args: ["torrent_", "download.php?id="]
-      banner:
-        selector: img[onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: borito\("(.*?) +?",
-      size:
-        selector: input[id^="meret_"]
-        attribute: value
-      grabs:
-        selector: div:nth-child(8) > div
-      seeders:
-        selector: div:nth-child(6) > div > a
-      leechers:
-        selector: div:nth-child(7) > div > a
-      date:
-        selector: div:nth-child(4)
-        filters:
-          - name: split
-            args: ["(", 0]
-          - name: append
-            args: "+01:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img[src="pic/free.png"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[src="pic/dupla_up.png"]: "2"
-          "*": "1"
-      description:
-        selector: div:nth-child(2)
-        remove: a
+---
+  site: estone
+  name: eStone
+  language: hu-hu
+  type: private
+  encoding: UTF-8
+  links:
+    - http://estone.cc/
+
+  caps:
+    categorymappings:
+      - {id: 24, cat: Movies/SD, desc: "Film/XviD/Hun"}
+      - {id: 38, cat: Movies/SD, desc: "Film/XviD/Eng"}
+      - {id: 51, cat: Movies/SD, desc: "Film/SD/Hun"}
+      - {id: 52, cat: Movies/SD, desc: "Film/SD/Eng"}
+      - {id: 25, cat: Movies/DVD, desc: "Film/DVD/Hun"}
+      - {id: 26, cat: Movies/DVD, desc: "Film/DVD/Eng"}
+      - {id: 42, cat: Movies/HD, desc: "Film/HD/Hun"}
+      - {id: 50, cat: Movies/HD, desc: "Film/HD/Eng"}
+      - {id: 36, cat: TV, desc: "Sorozat/Hun"}
+      - {id: 47, cat: TV, desc: "Sorozat/Eng"}
+      - {id: 41, cat: Audio/MP3, desc: "Mp3/Hun"}
+      - {id: 40, cat: Audio/MP3, desc: "Mp3/Eng"}
+      - {id: 35, cat: PC/0day, desc: "Program"}
+      - {id: 28, cat: PC/Games, desc: "Játék/ISO"}
+      - {id: 30, cat: PC/Games, desc: "Játék/Rip"}
+      - {id: 32, cat: Console, desc: "Konzol"}
+      - {id: 34, cat: PC/Phone-Other, desc: "Mobil"}
+      - {id: 44, cat: Books, desc: "Könyv/Hun"}
+      - {id: 33, cat: Books, desc: "Könyv/Eng"}
+      - {id: 31, cat: Other, desc: "Képek"}
+      - {id: 39, cat: XXX, desc: "XXX/Film"}
+      - {id: 49, cat: XXX/Imageset, desc: "XXX/Kép"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      login_username: "{{ .Config.username }}"
+      login_password: "{{ .Config.password }}"
+    error:
+      - selector: script:contains("hiba(\"")
+        message:
+          selector: script:contains("hiba(\"")
+          filters:
+            - name: replace
+              args: ["hiba(\"", ""]
+            - name: replace
+              args: ["\");", ""]
+    test:
+      path: /letoltes.php
+
+  search:
+    path: /letoltes.php
+    method: get
+    inputs:
+      $raw: "{{range .Categories}}kat[]={{.}}&{{end}}"
+      kereses_nev: "{{ .Query.Keywords }}"
+    rows:
+      selector: body > div[id^="torrent_"]
+    fields:
+      title:
+        selector: a[title]
+        attribute: title
+      category:
+        selector: div#kategoria_torrent > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        attribute: id
+        filters:
+          - name: replace
+            args: ["torrent_", "adatlap.php?id="]
+      download:
+        attribute: id
+        filters:
+          - name: replace
+            args: ["torrent_", "download.php?id="]
+      banner:
+        selector: img[onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: borito\("(.*?) +?",
+      size:
+        selector: input[id^="meret_"]
+        attribute: value
+      grabs:
+        selector: div:nth-child(8) > div
+      seeders:
+        selector: div:nth-child(6) > div > a
+      leechers:
+        selector: div:nth-child(7) > div > a
+      date:
+        selector: div:nth-child(4)
+        filters:
+          - name: split
+            args: ["(", 0]
+          - name: append
+            args: "+01:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img[src="pic/free.png"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[src="pic/dupla_up.png"]: "2"
+          "*": "1"
+      description:
+        selector: div:nth-child(2)
+        remove: a
diff --git a/src/Jackett/Definitions/ethor.yml b/src/Jackett/Definitions/ethor.yml
index 7663aa031177674c89f86bf4358fa73548ca9e79..d34bb64b13e778f81dde85c29dfc153a5fbb281b 100644
--- a/src/Jackett/Definitions/ethor.yml
+++ b/src/Jackett/Definitions/ethor.yml
@@ -1,119 +1,119 @@
----
-  site: ethor
-  name: Ethor.net (Thor's Land)
-  description: "A French gerneral tracker"
-  language: fr-fr
-  type: private
-  encoding: UTF-8
-  links:
-    - https://ethor.net/
-
-  caps:
-    categorymappings:
-      - {id: 22, cat: PC, desc: "Applications/Divers"}
-      - {id: 1, cat: PC, desc: "Applications/PC ISO"}
-      - {id: 44, cat: PC, desc: "Applications/Portable"}
-      - {id: 47, cat: Movies/BluRay, desc: "Films/Bluray"}
-      - {id: 20, cat: Movies/DVD, desc: "Films/DVDr"}
-      - {id: 42, cat: Movies/HD, desc: "Films/HD Rip"}
-      - {id: 19, cat: Movies/SD, desc: "Films/SD Rip"}
-      - {id: 5, cat: Movies/SD, desc: "Films/VCD"}
-      - {id: 4, cat: PC/Games, desc: "Jeux/PC"}
-      - {id: 41, cat: Console, desc: "Jeux/Portable"}
-      - {id: 34, cat: Console/PS4, desc: "Jeux/PS2-PS3"}
-      - {id: 38, cat: Console/Wii, desc: "Jeux/Wii-GC"}
-      - {id: 40, cat: Console/Xbox, desc: "Jeux/Xbox360"}
-      - {id: 6, cat: Audio, desc: "Musique"}
-      - {id: 37, cat: Audio/Video, desc: "Musique/Video"}
-      - {id: 48, cat: TV/HD, desc: "Série-Télé/Bluray"}
-      - {id: 45, cat: TV/SD, desc: "Série-Télé/DVDr"}
-      - {id: 43, cat: TV/HD, desc: "Série-Télé/HD Rip"}
-      - {id: 7, cat: TV/SD, desc: "Série-Télé/SD Rip"}
-      - {id: 23, cat: Books, desc: "E-Books"}
-      - {id: 46, cat: Other, desc: "Évé. sportif"}
-      - {id: 36, cat: Other, desc: "Kidz"}
-      - {id: 25, cat: Other, desc: "Misc"}
-      - {id: 9, cat: XXX, desc: "XXX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q, imdbid]
-
-  login:
-    path: login3.php
-    method: form
-    form: form[action="login3.php?takelogin=1"]
-    captcha:
-      type: image
-      image: img#validationimage
-      input: validationcode
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      secure_cookie: "0"
-    test:
-      path: browse.php
-
-  ratio:
-    path: browse.php
-    selector: span#ratioRatio
-
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
-      advcat: "0"
-      incldead: "1"
-      stype: "b"
-      dp: "0"
-      isUserClick: "0"
-    rows:
-      selector: p + table > tbody > tr:has(a[href^="/details.php"])
-    fields:
-      download:
-        selector: a[href^="/details.php"]:has(b)
-        attribute: href
-        filters:
-          - name: replace
-            args: ["/details.php", "/download.php"]
-      title:
-        selector: a[href^="/details.php"]:has(b)
-      category:
-        selector: a[href^="/browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      comments:
-        selector: a[href^="/details.php"]:has(b)
-        attribute: href
-      files:
-        selector: a[href*="#filelist"]
-      size:
-        selector: td:nth-child(6)
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " -05:00" # timezone offset
-          - name: dateparse
-            args: "2006-01-0215:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          "img[title^=\"Freeleech: \"]": "0"
-          "img[title^=\"Half Freeleech: \"]": "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: ethor
+  name: Ethor.net (Thor's Land)
+  description: "A French gerneral tracker"
+  language: fr-fr
+  type: private
+  encoding: UTF-8
+  links:
+    - https://ethor.net/
+
+  caps:
+    categorymappings:
+      - {id: 22, cat: PC, desc: "Applications/Divers"}
+      - {id: 1, cat: PC, desc: "Applications/PC ISO"}
+      - {id: 44, cat: PC, desc: "Applications/Portable"}
+      - {id: 47, cat: Movies/BluRay, desc: "Films/Bluray"}
+      - {id: 20, cat: Movies/DVD, desc: "Films/DVDr"}
+      - {id: 42, cat: Movies/HD, desc: "Films/HD Rip"}
+      - {id: 19, cat: Movies/SD, desc: "Films/SD Rip"}
+      - {id: 5, cat: Movies/SD, desc: "Films/VCD"}
+      - {id: 4, cat: PC/Games, desc: "Jeux/PC"}
+      - {id: 41, cat: Console, desc: "Jeux/Portable"}
+      - {id: 34, cat: Console/PS4, desc: "Jeux/PS2-PS3"}
+      - {id: 38, cat: Console/Wii, desc: "Jeux/Wii-GC"}
+      - {id: 40, cat: Console/Xbox, desc: "Jeux/Xbox360"}
+      - {id: 6, cat: Audio, desc: "Musique"}
+      - {id: 37, cat: Audio/Video, desc: "Musique/Video"}
+      - {id: 48, cat: TV/HD, desc: "Série-Télé/Bluray"}
+      - {id: 45, cat: TV/SD, desc: "Série-Télé/DVDr"}
+      - {id: 43, cat: TV/HD, desc: "Série-Télé/HD Rip"}
+      - {id: 7, cat: TV/SD, desc: "Série-Télé/SD Rip"}
+      - {id: 23, cat: Books, desc: "E-Books"}
+      - {id: 46, cat: Other, desc: "Évé. sportif"}
+      - {id: 36, cat: Other, desc: "Kidz"}
+      - {id: 25, cat: Other, desc: "Misc"}
+      - {id: 9, cat: XXX, desc: "XXX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q, imdbid]
+
+  login:
+    path: login3.php
+    method: form
+    form: form[action="login3.php?takelogin=1"]
+    captcha:
+      type: image
+      image: img#validationimage
+      input: validationcode
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      secure_cookie: "0"
+    test:
+      path: browse.php
+
+  ratio:
+    path: browse.php
+    selector: span#ratioRatio
+
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
+      advcat: "0"
+      incldead: "1"
+      stype: "b"
+      dp: "0"
+      isUserClick: "0"
+    rows:
+      selector: p + table > tbody > tr:has(a[href^="/details.php"])
+    fields:
+      download:
+        selector: a[href^="/details.php"]:has(b)
+        attribute: href
+        filters:
+          - name: replace
+            args: ["/details.php", "/download.php"]
+      title:
+        selector: a[href^="/details.php"]:has(b)
+      category:
+        selector: a[href^="/browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      comments:
+        selector: a[href^="/details.php"]:has(b)
+        attribute: href
+      files:
+        selector: a[href*="#filelist"]
+      size:
+        selector: td:nth-child(6)
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " -05:00" # timezone offset
+          - name: dateparse
+            args: "2006-01-0215:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          "img[title^=\"Freeleech: \"]": "0"
+          "img[title^=\"Half Freeleech: \"]": "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/freedomhd.yml b/src/Jackett/Definitions/freedomhd.yml
index 02aec14fc049fe1ee13a02087c448d084589ee66..19773fcb575790a9b2992c4365ff1392a282a209 100644
--- a/src/Jackett/Definitions/freedomhd.yml
+++ b/src/Jackett/Definitions/freedomhd.yml
@@ -1,130 +1,130 @@
----
-  site: freedomhd
-  name: Freedom-HD
-  language: fr-fr
-  type: private
-  encoding: UTF-8
-  links:
-    - http://freedom-paradise.eu/
-
-  caps:
-    categorymappings:
-      # ANIMES
-      - {id: 105, cat: TV/Anime, desc: "1080p"}
-      - {id: 104, cat: TV/Anime, desc: "720p"}
-      - {id: 90, cat: TV/Anime, desc: "HDRIP-720p"}
-      - {id: 93, cat: TV/Anime, desc: "HDRIP1080p"}
-      - {id: 131, cat: TV/Anime, desc: "SD"}
-      - {id: 120, cat: TV/Anime, desc: "X265-1080p"}
-      - {id: 119, cat: TV/Anime, desc: "X265-720p"}
-      - {id: 107, cat: TV/Anime, desc: "1080p"}
-      - {id: 106, cat: TV/Anime, desc: "720p"}
-      - {id: 94, cat: TV/Anime, desc: "HDRIP1080p"}
-      - {id: 91, cat: TV/Anime, desc: "HDRIP720p"}
-
-      # EBOOK
-      - {id: 124, cat: Books, desc: "Livres et Magazines"}
-
-      # FILMS
-      - {id: 97, cat: Movies/HD, desc: "1080p"}
-      - {id: 103, cat: Movies/3D, desc: "3D"}
-      - {id: 111, cat: Movies/HD, desc: "4K"}
-      - {id: 96, cat: Movies/HD, desc: "720p"}
-      - {id: 127, cat: Movies/HD, desc: "BDrip"}
-      - {id: 128, cat: Movies/HD, desc: "BRrip"}
-      - {id: 126, cat: Movies/SD, desc: "DVDrip"}
-      - {id: 89, cat: Movies/HD, desc: "HDRIP-720p"}
-      - {id: 92, cat: Movies/HD, desc: "HDRIP1080p"}
-      - {id: 112, cat: Movies/SD, desc: "Team-Hush"}
-      - {id: 129, cat: Movies/HD, desc: "Team-Romkent"}
-      - {id: 125, cat: Movies/Other, desc: "WEBrip"}
-      - {id: 110, cat: Movies/HD, desc: "X265-1080p"}
-      - {id: 109, cat: Movies/HD, desc: "X265-720p"}
-
-      # MUSIQUES
-      - {id: 114, cat: Audio/Lossless, desc: "Flac"}
-      - {id: 113, cat: Audio/MP3, desc: "MP3"}
-      - {id: 132, cat: Audio, desc: "Musiques-HQ"}
-      - {id: 130, cat: Audio/Video, desc: "video clip"}
-
-      # SERIE-sd
-      - {id: 121, cat: TV/SD, desc: "SD"}
-
-      # SERIES-HD
-      - {id: 102, cat: TV/HD, desc: "1080p"}
-      - {id: 101, cat: TV/HD, desc: "720p"}
-      - {id: 100, cat: TV/HD, desc: "HDrip1080p"}
-      - {id: 99, cat: TV/HD, desc: "HDrip720p"}
-
-      # SPECTACLES
-      - {id: 118, cat: TV/Sport, desc: "HDRIP1080p"}
-      - {id: 117, cat: TV/Sport, desc: "HDRIP720p"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: account-login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      remember: "yes"
-      returnto: "/"
-    error:
-      - selector: div.myFrame:has(font.error)
-    test:
-      path: torrents-search.php
-
-  search:
-    path: torrents-search.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-
-    rows:
-      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
-      filters:
-        - name: andmatch
-      after: 1
-    fields:
-      download:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["torrents-details.php", "download.php"]
-      title:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="torrents.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-      description:
-        selector: ul
-      banner:
-        selector: img.rounded-img
-        attribute: src
-      size:
-        selector: td:nth-child(3)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(4)
-      leechers:
-        selector: td:nth-child(5)
-      downloadvolumefactor:
-        case:
-          img[alt="freeleech"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: freedomhd
+  name: Freedom-HD
+  language: fr-fr
+  type: private
+  encoding: UTF-8
+  links:
+    - http://freedom-paradise.eu/
+
+  caps:
+    categorymappings:
+      # ANIMES
+      - {id: 105, cat: TV/Anime, desc: "1080p"}
+      - {id: 104, cat: TV/Anime, desc: "720p"}
+      - {id: 90, cat: TV/Anime, desc: "HDRIP-720p"}
+      - {id: 93, cat: TV/Anime, desc: "HDRIP1080p"}
+      - {id: 131, cat: TV/Anime, desc: "SD"}
+      - {id: 120, cat: TV/Anime, desc: "X265-1080p"}
+      - {id: 119, cat: TV/Anime, desc: "X265-720p"}
+      - {id: 107, cat: TV/Anime, desc: "1080p"}
+      - {id: 106, cat: TV/Anime, desc: "720p"}
+      - {id: 94, cat: TV/Anime, desc: "HDRIP1080p"}
+      - {id: 91, cat: TV/Anime, desc: "HDRIP720p"}
+
+      # EBOOK
+      - {id: 124, cat: Books, desc: "Livres et Magazines"}
+
+      # FILMS
+      - {id: 97, cat: Movies/HD, desc: "1080p"}
+      - {id: 103, cat: Movies/3D, desc: "3D"}
+      - {id: 111, cat: Movies/HD, desc: "4K"}
+      - {id: 96, cat: Movies/HD, desc: "720p"}
+      - {id: 127, cat: Movies/HD, desc: "BDrip"}
+      - {id: 128, cat: Movies/HD, desc: "BRrip"}
+      - {id: 126, cat: Movies/SD, desc: "DVDrip"}
+      - {id: 89, cat: Movies/HD, desc: "HDRIP-720p"}
+      - {id: 92, cat: Movies/HD, desc: "HDRIP1080p"}
+      - {id: 112, cat: Movies/SD, desc: "Team-Hush"}
+      - {id: 129, cat: Movies/HD, desc: "Team-Romkent"}
+      - {id: 125, cat: Movies/Other, desc: "WEBrip"}
+      - {id: 110, cat: Movies/HD, desc: "X265-1080p"}
+      - {id: 109, cat: Movies/HD, desc: "X265-720p"}
+
+      # MUSIQUES
+      - {id: 114, cat: Audio/Lossless, desc: "Flac"}
+      - {id: 113, cat: Audio/MP3, desc: "MP3"}
+      - {id: 132, cat: Audio, desc: "Musiques-HQ"}
+      - {id: 130, cat: Audio/Video, desc: "video clip"}
+
+      # SERIE-sd
+      - {id: 121, cat: TV/SD, desc: "SD"}
+
+      # SERIES-HD
+      - {id: 102, cat: TV/HD, desc: "1080p"}
+      - {id: 101, cat: TV/HD, desc: "720p"}
+      - {id: 100, cat: TV/HD, desc: "HDrip1080p"}
+      - {id: 99, cat: TV/HD, desc: "HDrip720p"}
+
+      # SPECTACLES
+      - {id: 118, cat: TV/Sport, desc: "HDRIP1080p"}
+      - {id: 117, cat: TV/Sport, desc: "HDRIP720p"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: account-login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      remember: "yes"
+      returnto: "/"
+    error:
+      - selector: div.myFrame:has(font.error)
+    test:
+      path: torrents-search.php
+
+  search:
+    path: torrents-search.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+
+    rows:
+      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
+      filters:
+        - name: andmatch
+      after: 1
+    fields:
+      download:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["torrents-details.php", "download.php"]
+      title:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="torrents.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+      description:
+        selector: ul
+      banner:
+        selector: img.rounded-img
+        attribute: src
+      size:
+        selector: td:nth-child(3)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(4)
+      leechers:
+        selector: td:nth-child(5)
+      downloadvolumefactor:
+        case:
+          img[alt="freeleech"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/gfxpeers.yml b/src/Jackett/Definitions/gfxpeers.yml
index bd2ac02f705862296fa72f9ce9c0ec42352af733..1ad30664b0e8f2e5f19105dda546a0f35d687ec5 100644
--- a/src/Jackett/Definitions/gfxpeers.yml
+++ b/src/Jackett/Definitions/gfxpeers.yml
@@ -1,80 +1,80 @@
----
-  site: gfxpeers
-  name: GFXPeers
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://gfxpeers.net/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: PC/0day, desc: "Applications"}
-      - {id: 2, cat: PC/0day, desc: "Plug-ins"}
-      - {id: 3, cat: Other, desc: "Tutorials"}
-      - {id: 4, cat: Other, desc: "Textures"}
-      - {id: 5, cat: Other, desc: "3D Models"}
-      - {id: 6, cat: Other, desc: "Game-Dev"}
-      - {id: 7, cat: Other, desc: "Miscellaneous"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: "1"
-    error:
-      - selector: .auth_form > .warning
-    test:
-      path: /torrents.php
-
-  search:
-    path: /torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: "time"
-      order_way: "desc"
-      action: "advanced"
-      searchsubmit: "1"
-
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      title:
-        selector: a[href^="torrents.php?id="]
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      category:
-        selector: a[href^="torrents.php?filter_cat"]
-        attribute: href
-        filters:
-          - name: regexp
-            args: "\\[(\\d+?)\\]"
-      details:
-        selector: a[href^="torrents.php?id="]
-        attribute: href
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      files:
-        selector: td:nth-child(3)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      date:
-        selector: td:nth-child(4)
+---
+  site: gfxpeers
+  name: GFXPeers
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://gfxpeers.net/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: PC/0day, desc: "Applications"}
+      - {id: 2, cat: PC/0day, desc: "Plug-ins"}
+      - {id: 3, cat: Other, desc: "Tutorials"}
+      - {id: 4, cat: Other, desc: "Textures"}
+      - {id: 5, cat: Other, desc: "3D Models"}
+      - {id: 6, cat: Other, desc: "Game-Dev"}
+      - {id: 7, cat: Other, desc: "Miscellaneous"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: "1"
+    error:
+      - selector: .auth_form > .warning
+    test:
+      path: /torrents.php
+
+  search:
+    path: /torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: "time"
+      order_way: "desc"
+      action: "advanced"
+      searchsubmit: "1"
+
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      title:
+        selector: a[href^="torrents.php?id="]
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      category:
+        selector: a[href^="torrents.php?filter_cat"]
+        attribute: href
+        filters:
+          - name: regexp
+            args: "\\[(\\d+?)\\]"
+      details:
+        selector: a[href^="torrents.php?id="]
+        attribute: href
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      files:
+        selector: td:nth-child(3)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      date:
+        selector: td:nth-child(4)
diff --git a/src/Jackett/Definitions/gods.yml b/src/Jackett/Definitions/gods.yml
index 6129ab799855a876e0a51f7a999cfc60ee21b534..c3a68e42996de2142fd947affede691931a4374b 100644
--- a/src/Jackett/Definitions/gods.yml
+++ b/src/Jackett/Definitions/gods.yml
@@ -1,162 +1,162 @@
----
-  site: gods
-  name: GODS
-  language: de-de
-  type: private
-  encoding: windows-1252
-  links:
-    - https://gods.lu/
-
-  caps:
-    categorymappings:
-      # Movie
-      - {id: 132, cat: Movies/BluRay, desc: "BluRay"}
-      - {id: 146, cat: Movies/HD, desc: "Remux"}
-      - {id: 186, cat: Movies/HD, desc: "UHD"}
-      - {id: 189, cat: Movies/HD, desc: "HD"}
-      - {id: 190, cat: Movies/SD, desc: "SD"}
-      - {id: 20, cat: Movies/DVD, desc: "DVD"}
-      - {id: 131, cat: Movies/3D, desc: "3D"}
-      - {id: 16, cat: Movies, desc: "Packs"}
-
-      # Serien
-      - {id: 187, cat: TV/HD, desc: "Staffeln UHD"}
-      - {id: 173, cat: TV/HD, desc: "Staffeln HD"}
-      - {id: 133, cat: TV/SD, desc: "Staffeln SD"}
-      - {id: 188, cat: TV/HD, desc: "Folgen UHD"}
-      - {id: 174, cat: TV/HD, desc: "Folgen HD"}
-      - {id: 7, cat: TV/SD, desc: "Folgen SD"}
-
-      # Doku
-      - {id: 152, cat: TV/Documentary, desc: "HD"}
-      - {id: 153, cat: TV/Documentary, desc: "SD"}
-
-      # Spiele
-      - {id: 4, cat: PC/Games, desc: "Windows"}
-      - {id: 29, cat: Console/XBox360, desc: "XBOX 360"}
-      - {id: 126, cat: Console/Wii, desc: "Wii"}
-      - {id: 183, cat: Console/Wii, desc: "Wii U"}
-      - {id: 128, cat: Console/PS3, desc: "PS3"}
-      - {id: 154, cat: Console/Other, desc: "Andere"}
-
-      # Musik
-      - {id: 6, cat: Audio, desc: "Alben"}
-      - {id: 139, cat: Audio/Lossless, desc: "Lossless"}
-      - {id: 177, cat: Audio, desc: "Singles"}
-      - {id: 157, cat: Audio, desc: "Charts"}
-      - {id: 192, cat: Audio, desc: "Packs"}
-      - {id: 161, cat: Audio/Video, desc: "Video"}
-
-      - {id: 22, cat: PC/0day, desc: "Windows"}
-      - {id: 129, cat: PC/Mac, desc: "Mac OS"}
-      - {id: 164, cat: PC/0day, desc: "Linux"}
-      - {id: 124, cat: PC/Phone-Android, desc: "Android"}
-      - {id: 165, cat: PC/Phone-IOS, desc: "Apple iOS"}
-      - {id: 167, cat: PC/Phone-Other, desc: "Andere"}
-
-      # Sport
-      - {id: 130, cat: TV/Sport, desc: "HD"}
-      - {id: 135, cat: TV/Sport, desc: "SD"}
-
-      #  International
-      - {id: 170, cat: Movies/Foreign, desc: "Filme HD"}
-      - {id: 134, cat: Movies/Foreign, desc: "Filme SD"}
-      - {id: 171, cat: TV/Foreign, desc: "Folgen HD"}
-      - {id: 172, cat: TV/Foreign, desc: "Folgen SD"}
-
-      # Sonstiges
-      - {id: 28, cat: TV/Anime, desc: "Anime"}
-      - {id: 13, cat: Books, desc: "e-Book"}
-      - {id: 11, cat: Audio/Audiobook, desc: "Hören"}
-      - {id: 136, cat: Other, desc: "Bilder"}
-      - {id: 9, cat: Other, desc: "Tutorial"}
-      - {id: 178, cat: Other, desc: "Anderes"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  settings:
-    - name: pin
-      type: text
-      label: Pin
-    - name: username
-      type: text
-      label: Username
-    - name: password
-      type: password
-      label: Password
-
-  login:
-    path: /login/
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      pin: "{{ .Config.pin }}"
-    test:
-      path: browse.php
-
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      intitle: "1"
-      incldead: "1"
-      team: "0"
-      orderby: "added"
-      sort: desc
-    rows:
-      selector: table.tableinborder > tbody > tr:has(a[href^="details.php"])
-    fields:
-      title:
-        selector: a[href^="details.php"]
-      banner:
-        selector: a[href^="details.php"] > span > img
-        attribute: src
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php"]
-        attribute: href
-      comments:
-        selector: a[href*="&tocomm="]
-        attribute: href
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
-      grabs:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
-      size:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      seeders:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
-      leechers:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(3)
-      date:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(6)
-        filters:
-          - name: replace
-            args: ["\xA0", " "]
-          - name: dateparse
-            args: "02.01.2006 15:04:05"
-      downloadvolumefactor:
-        case:
-          img[alt="onlyupload"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: gods
+  name: GODS
+  language: de-de
+  type: private
+  encoding: windows-1252
+  links:
+    - https://gods.lu/
+
+  caps:
+    categorymappings:
+      # Movie
+      - {id: 132, cat: Movies/BluRay, desc: "BluRay"}
+      - {id: 146, cat: Movies/HD, desc: "Remux"}
+      - {id: 186, cat: Movies/HD, desc: "UHD"}
+      - {id: 189, cat: Movies/HD, desc: "HD"}
+      - {id: 190, cat: Movies/SD, desc: "SD"}
+      - {id: 20, cat: Movies/DVD, desc: "DVD"}
+      - {id: 131, cat: Movies/3D, desc: "3D"}
+      - {id: 16, cat: Movies, desc: "Packs"}
+
+      # Serien
+      - {id: 187, cat: TV/HD, desc: "Staffeln UHD"}
+      - {id: 173, cat: TV/HD, desc: "Staffeln HD"}
+      - {id: 133, cat: TV/SD, desc: "Staffeln SD"}
+      - {id: 188, cat: TV/HD, desc: "Folgen UHD"}
+      - {id: 174, cat: TV/HD, desc: "Folgen HD"}
+      - {id: 7, cat: TV/SD, desc: "Folgen SD"}
+
+      # Doku
+      - {id: 152, cat: TV/Documentary, desc: "HD"}
+      - {id: 153, cat: TV/Documentary, desc: "SD"}
+
+      # Spiele
+      - {id: 4, cat: PC/Games, desc: "Windows"}
+      - {id: 29, cat: Console/XBox360, desc: "XBOX 360"}
+      - {id: 126, cat: Console/Wii, desc: "Wii"}
+      - {id: 183, cat: Console/Wii, desc: "Wii U"}
+      - {id: 128, cat: Console/PS3, desc: "PS3"}
+      - {id: 154, cat: Console/Other, desc: "Andere"}
+
+      # Musik
+      - {id: 6, cat: Audio, desc: "Alben"}
+      - {id: 139, cat: Audio/Lossless, desc: "Lossless"}
+      - {id: 177, cat: Audio, desc: "Singles"}
+      - {id: 157, cat: Audio, desc: "Charts"}
+      - {id: 192, cat: Audio, desc: "Packs"}
+      - {id: 161, cat: Audio/Video, desc: "Video"}
+
+      - {id: 22, cat: PC/0day, desc: "Windows"}
+      - {id: 129, cat: PC/Mac, desc: "Mac OS"}
+      - {id: 164, cat: PC/0day, desc: "Linux"}
+      - {id: 124, cat: PC/Phone-Android, desc: "Android"}
+      - {id: 165, cat: PC/Phone-IOS, desc: "Apple iOS"}
+      - {id: 167, cat: PC/Phone-Other, desc: "Andere"}
+
+      # Sport
+      - {id: 130, cat: TV/Sport, desc: "HD"}
+      - {id: 135, cat: TV/Sport, desc: "SD"}
+
+      #  International
+      - {id: 170, cat: Movies/Foreign, desc: "Filme HD"}
+      - {id: 134, cat: Movies/Foreign, desc: "Filme SD"}
+      - {id: 171, cat: TV/Foreign, desc: "Folgen HD"}
+      - {id: 172, cat: TV/Foreign, desc: "Folgen SD"}
+
+      # Sonstiges
+      - {id: 28, cat: TV/Anime, desc: "Anime"}
+      - {id: 13, cat: Books, desc: "e-Book"}
+      - {id: 11, cat: Audio/Audiobook, desc: "Hören"}
+      - {id: 136, cat: Other, desc: "Bilder"}
+      - {id: 9, cat: Other, desc: "Tutorial"}
+      - {id: 178, cat: Other, desc: "Anderes"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  settings:
+    - name: pin
+      type: text
+      label: Pin
+    - name: username
+      type: text
+      label: Username
+    - name: password
+      type: password
+      label: Password
+
+  login:
+    path: /login/
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      pin: "{{ .Config.pin }}"
+    test:
+      path: browse.php
+
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      intitle: "1"
+      incldead: "1"
+      team: "0"
+      orderby: "added"
+      sort: desc
+    rows:
+      selector: table.tableinborder > tbody > tr:has(a[href^="details.php"])
+    fields:
+      title:
+        selector: a[href^="details.php"]
+      banner:
+        selector: a[href^="details.php"] > span > img
+        attribute: src
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php"]
+        attribute: href
+      comments:
+        selector: a[href*="&tocomm="]
+        attribute: href
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
+      grabs:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
+      size:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      seeders:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
+      leechers:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(3)
+      date:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(6)
+        filters:
+          - name: replace
+            args: ["\xA0", " "]
+          - name: dateparse
+            args: "02.01.2006 15:04:05"
+      downloadvolumefactor:
+        case:
+          img[alt="onlyupload"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/gormogon.yml b/src/Jackett/Definitions/gormogon.yml
index 98f9f69171e3a5aaffe019049f2376622d3c9078..b8ca5eadf9c3b0fcc246133d7d593d356d6ea145 100644
--- a/src/Jackett/Definitions/gormogon.yml
+++ b/src/Jackett/Definitions/gormogon.yml
@@ -1,193 +1,193 @@
----
-  site: gormogon
-  name: Gormogon
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.gormogon.com
-
-  caps:
-    categorymappings:
-      # Movies:
-      - {id: 1, cat: Movies/DVD, desc: "DVD-R"}
-      - {id: 2, cat: Movies, desc: "Action"}
-      - {id: 14, cat: Movies, desc: "Adventure"}
-      - {id: 15, cat: Movies, desc: "Animation"}
-      - {id: 16, cat: Movies, desc: "Biography"}
-      - {id: 17, cat: Movies, desc: "Comedy"}
-      - {id: 18, cat: Movies, desc: "Crime"}
-      - {id: 19, cat: Movies, desc: "Disney"}
-      - {id: 92, cat: Movies, desc: "Documentary"}
-      - {id: 20, cat: Movies, desc: "Drama"}
-      - {id: 21, cat: Movies, desc: "Family"}
-      - {id: 22, cat: Movies, desc: "Fantasy"}
-      - {id: 23, cat: Movies, desc: "Film Noir"}
-      - {id: 97, cat: Movies, desc: "History"}
-      - {id: 24, cat: Movies, desc: "Horror"}
-      - {id: 25, cat: Movies, desc: "Martial Arts"}
-      - {id: 26, cat: Movies, desc: "Musicals"}
-      - {id: 27, cat: Movies, desc: "Mystery"}
-      - {id: 28, cat: Movies, desc: "Romance"}
-      - {id: 29, cat: Movies, desc: "Sci-Fi"}
-      - {id: 30, cat: Movies, desc: "Thriller"}
-      - {id: 31, cat: Movies, desc: "War"}
-      - {id: 32, cat: Movies, desc: "Western"}
-      - {id: 33, cat: Movies, desc: "Other"}
-
-      # Classic TV:
-      - {id: 34, cat: TV, desc: "Action"}
-      - {id: 35, cat: TV, desc: "Adventure"}
-      - {id: 36, cat: TV, desc: "Animation"}
-      - {id: 37, cat: TV, desc: "Biography"}
-      - {id: 38, cat: TV, desc: "Comedy"}
-      - {id: 39, cat: TV, desc: "Crime"}
-      - {id: 40, cat: TV, desc: "Disney"}
-      - {id: 41, cat: TV, desc: "Documentary"}
-      - {id: 42, cat: TV, desc: "Drama"}
-      - {id: 43, cat: TV, desc: "Family"}
-      - {id: 44, cat: TV, desc: "Fantasy"}
-      - {id: 45, cat: TV, desc: "TV Noir"}
-      - {id: 46, cat: TV, desc: "Horror"}
-      - {id: 47, cat: TV, desc: "Martial Arts"}
-      - {id: 49, cat: TV, desc: "Musicals"}
-      - {id: 50, cat: TV, desc: "Mystery"}
-      - {id: 51, cat: TV, desc: "Romance"}
-      - {id: 52, cat: TV, desc: "Sci-Fi"}
-      - {id: 48, cat: TV, desc: "Shows"}
-      - {id: 53, cat: TV, desc: "Thriller"}
-      - {id: 54, cat: TV, desc: "War"}
-      - {id: 55, cat: TV, desc: "Western"}
-      - {id: 56, cat: TV, desc: "Other"}
-      - {id: 90, cat: TV, desc: "TV Movies"}
-
-      # Old Time Radio
-      - {id: 57, cat: Audio, desc: "Action"}
-      - {id: 58, cat: Audio, desc: "Adventure"}
-      - {id: 59, cat: Audio, desc: "Biography"}
-      - {id: 60, cat: Audio, desc: "Comedy"}
-      - {id: 61, cat: Audio, desc: "Crime"}
-      - {id: 62, cat: Audio, desc: "Documentary"}
-      - {id: 63, cat: Audio, desc: "Drama"}
-      - {id: 64, cat: Audio, desc: "Family"}
-      - {id: 65, cat: Audio, desc: "Fantasy"}
-      - {id: 66, cat: Audio, desc: "Radio Noir"}
-      - {id: 67, cat: Audio, desc: "Horror"}
-      - {id: 68, cat: Audio, desc: "Musicals"}
-      - {id: 69, cat: Audio, desc: "Mystery"}
-      - {id: 70, cat: Audio, desc: "Romance"}
-      - {id: 71, cat: Audio, desc: "Sci-Fi"}
-      - {id: 72, cat: Audio, desc: "Shows"}
-      - {id: 73, cat: Audio, desc: "Thriller"}
-      - {id: 74, cat: Audio, desc: "War"}
-      - {id: 75, cat: Audio, desc: "Western"}
-      - {id: 76, cat: Audio, desc: "Other"}
-
-      # Music:
-      - {id: 77, cat: Audio, desc: "Official Sountracks"}
-      - {id: 78, cat: Audio, desc: "Theme Tunes"}
-      - {id: 79, cat: Audio, desc: "Music 30s"}
-      - {id: 80, cat: Audio, desc: "Music 40s"}
-      - {id: 81, cat: Audio, desc: "Music 50s"}
-      - {id: 85, cat: Audio, desc: "Music 60s"}
-      - {id: 86, cat: Audio, desc: "Music 70s"}
-      - {id: 87, cat: Audio, desc: "Music '80 - '84"}
-
-      # Printed:
-      - {id: 82, cat: Books, desc: "Books"}
-      - {id: 91, cat: Books, desc: "Newspaper"}
-      - {id: 83, cat: Books, desc: "Scripts"}
-      - {id: 84, cat: Books, desc: "Posters"}
-      - {id: 88, cat: Books, desc: "Comics"}
-      - {id: 89, cat: Books, desc: "Magazines"}
-
-      # Software:
-      - {id: 94, cat: Other, desc: "Screensavers"}
-      - {id: 95, cat: PC, desc: "Programs"}
-      - {id: 96, cat: Other, desc: "Other"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: index.php?page=login&returnto=index.php
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    error:
-      - selector: td.lista > span[style="color:#FF0000;"]
-    test:
-      path: index.php
-      selector: form[name="jump1"]
-
-  ratio:
-    path: index.php
-    selector: form[name="jump1"] > table > tbody > tr > td:contains("SR ")
-    filters:
-      - name: trim
-        args: ")"
-      - name: split
-        args: [" ", 1]
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: index.php
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      category: "{{range .Categories}}{{.}};{{end}}"
-      page: torrents
-      active: 0
-    rows:
-      selector: table.lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
-    fields:
-      download:
-        selector: a[href^="index.php?page=downloadcheck&id="]
-        attribute: href
-      title:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: td:nth-child(10)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: dateparse
-            args: "02/01/2006"
-      grabs:
-        selector: td:nth-child(8)
-        filters:
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      downloadvolumefactor:
-        case:
-          img[alt="gold"]: "0"
-          img[alt="silver"]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt="2x Upload Multiplier"]: "2"
-          img[alt="3x Upload Multiplier"]: "3"
-          img[alt="4x Upload Multiplier"]: "4"
-          img[alt="5x Upload Multiplier"]: "5"
-          img[alt="6x Upload Multiplier"]: "6"
-          img[alt="7x Upload Multiplier"]: "7"
-          img[alt="8x Upload Multiplier"]: "8"
-          img[alt="9x Upload Multiplier"]: "9"
-          img[alt="10x Upload Multiplier"]: "10"
+---
+  site: gormogon
+  name: Gormogon
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.gormogon.com
+
+  caps:
+    categorymappings:
+      # Movies:
+      - {id: 1, cat: Movies/DVD, desc: "DVD-R"}
+      - {id: 2, cat: Movies, desc: "Action"}
+      - {id: 14, cat: Movies, desc: "Adventure"}
+      - {id: 15, cat: Movies, desc: "Animation"}
+      - {id: 16, cat: Movies, desc: "Biography"}
+      - {id: 17, cat: Movies, desc: "Comedy"}
+      - {id: 18, cat: Movies, desc: "Crime"}
+      - {id: 19, cat: Movies, desc: "Disney"}
+      - {id: 92, cat: Movies, desc: "Documentary"}
+      - {id: 20, cat: Movies, desc: "Drama"}
+      - {id: 21, cat: Movies, desc: "Family"}
+      - {id: 22, cat: Movies, desc: "Fantasy"}
+      - {id: 23, cat: Movies, desc: "Film Noir"}
+      - {id: 97, cat: Movies, desc: "History"}
+      - {id: 24, cat: Movies, desc: "Horror"}
+      - {id: 25, cat: Movies, desc: "Martial Arts"}
+      - {id: 26, cat: Movies, desc: "Musicals"}
+      - {id: 27, cat: Movies, desc: "Mystery"}
+      - {id: 28, cat: Movies, desc: "Romance"}
+      - {id: 29, cat: Movies, desc: "Sci-Fi"}
+      - {id: 30, cat: Movies, desc: "Thriller"}
+      - {id: 31, cat: Movies, desc: "War"}
+      - {id: 32, cat: Movies, desc: "Western"}
+      - {id: 33, cat: Movies, desc: "Other"}
+
+      # Classic TV:
+      - {id: 34, cat: TV, desc: "Action"}
+      - {id: 35, cat: TV, desc: "Adventure"}
+      - {id: 36, cat: TV, desc: "Animation"}
+      - {id: 37, cat: TV, desc: "Biography"}
+      - {id: 38, cat: TV, desc: "Comedy"}
+      - {id: 39, cat: TV, desc: "Crime"}
+      - {id: 40, cat: TV, desc: "Disney"}
+      - {id: 41, cat: TV, desc: "Documentary"}
+      - {id: 42, cat: TV, desc: "Drama"}
+      - {id: 43, cat: TV, desc: "Family"}
+      - {id: 44, cat: TV, desc: "Fantasy"}
+      - {id: 45, cat: TV, desc: "TV Noir"}
+      - {id: 46, cat: TV, desc: "Horror"}
+      - {id: 47, cat: TV, desc: "Martial Arts"}
+      - {id: 49, cat: TV, desc: "Musicals"}
+      - {id: 50, cat: TV, desc: "Mystery"}
+      - {id: 51, cat: TV, desc: "Romance"}
+      - {id: 52, cat: TV, desc: "Sci-Fi"}
+      - {id: 48, cat: TV, desc: "Shows"}
+      - {id: 53, cat: TV, desc: "Thriller"}
+      - {id: 54, cat: TV, desc: "War"}
+      - {id: 55, cat: TV, desc: "Western"}
+      - {id: 56, cat: TV, desc: "Other"}
+      - {id: 90, cat: TV, desc: "TV Movies"}
+
+      # Old Time Radio
+      - {id: 57, cat: Audio, desc: "Action"}
+      - {id: 58, cat: Audio, desc: "Adventure"}
+      - {id: 59, cat: Audio, desc: "Biography"}
+      - {id: 60, cat: Audio, desc: "Comedy"}
+      - {id: 61, cat: Audio, desc: "Crime"}
+      - {id: 62, cat: Audio, desc: "Documentary"}
+      - {id: 63, cat: Audio, desc: "Drama"}
+      - {id: 64, cat: Audio, desc: "Family"}
+      - {id: 65, cat: Audio, desc: "Fantasy"}
+      - {id: 66, cat: Audio, desc: "Radio Noir"}
+      - {id: 67, cat: Audio, desc: "Horror"}
+      - {id: 68, cat: Audio, desc: "Musicals"}
+      - {id: 69, cat: Audio, desc: "Mystery"}
+      - {id: 70, cat: Audio, desc: "Romance"}
+      - {id: 71, cat: Audio, desc: "Sci-Fi"}
+      - {id: 72, cat: Audio, desc: "Shows"}
+      - {id: 73, cat: Audio, desc: "Thriller"}
+      - {id: 74, cat: Audio, desc: "War"}
+      - {id: 75, cat: Audio, desc: "Western"}
+      - {id: 76, cat: Audio, desc: "Other"}
+
+      # Music:
+      - {id: 77, cat: Audio, desc: "Official Sountracks"}
+      - {id: 78, cat: Audio, desc: "Theme Tunes"}
+      - {id: 79, cat: Audio, desc: "Music 30s"}
+      - {id: 80, cat: Audio, desc: "Music 40s"}
+      - {id: 81, cat: Audio, desc: "Music 50s"}
+      - {id: 85, cat: Audio, desc: "Music 60s"}
+      - {id: 86, cat: Audio, desc: "Music 70s"}
+      - {id: 87, cat: Audio, desc: "Music '80 - '84"}
+
+      # Printed:
+      - {id: 82, cat: Books, desc: "Books"}
+      - {id: 91, cat: Books, desc: "Newspaper"}
+      - {id: 83, cat: Books, desc: "Scripts"}
+      - {id: 84, cat: Books, desc: "Posters"}
+      - {id: 88, cat: Books, desc: "Comics"}
+      - {id: 89, cat: Books, desc: "Magazines"}
+
+      # Software:
+      - {id: 94, cat: Other, desc: "Screensavers"}
+      - {id: 95, cat: PC, desc: "Programs"}
+      - {id: 96, cat: Other, desc: "Other"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: index.php?page=login&returnto=index.php
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    error:
+      - selector: td.lista > span[style="color:#FF0000;"]
+    test:
+      path: index.php
+      selector: form[name="jump1"]
+
+  ratio:
+    path: index.php
+    selector: form[name="jump1"] > table > tbody > tr > td:contains("SR ")
+    filters:
+      - name: trim
+        args: ")"
+      - name: split
+        args: [" ", 1]
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: index.php
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      category: "{{range .Categories}}{{.}};{{end}}"
+      page: torrents
+      active: 0
+    rows:
+      selector: table.lista > tbody > tr:has(a[href^="index.php?page=torrents&category="])
+    fields:
+      download:
+        selector: a[href^="index.php?page=downloadcheck&id="]
+        attribute: href
+      title:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: td:nth-child(10)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: dateparse
+            args: "02/01/2006"
+      grabs:
+        selector: td:nth-child(8)
+        filters:
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      downloadvolumefactor:
+        case:
+          img[alt="gold"]: "0"
+          img[alt="silver"]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt="2x Upload Multiplier"]: "2"
+          img[alt="3x Upload Multiplier"]: "3"
+          img[alt="4x Upload Multiplier"]: "4"
+          img[alt="5x Upload Multiplier"]: "5"
+          img[alt="6x Upload Multiplier"]: "6"
+          img[alt="7x Upload Multiplier"]: "7"
+          img[alt="8x Upload Multiplier"]: "8"
+          img[alt="9x Upload Multiplier"]: "9"
+          img[alt="10x Upload Multiplier"]: "10"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/hdbits.yml b/src/Jackett/Definitions/hdbits.yml
index 7503cef9cb2e8c61a67f47ca421b8146baebe50a..cc196a4afd134f513dc0c08daa6ce11071a6b586 100644
--- a/src/Jackett/Definitions/hdbits.yml
+++ b/src/Jackett/Definitions/hdbits.yml
@@ -1,83 +1,83 @@
----
-  site: hdbits
-  name: HDBits
-  description: "Best HD Tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://hdbits.org
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: "Movies", desc: "Movie"}
-      - {id: 2, cat: "TV", desc: "TV"}
-      - {id: 3, cat: "TV/Documentary", desc: "Documentary"}
-      - {id: 4, cat: "Audio", desc: "Music"}
-      - {id: 5, cat: "TV/Sport", desc: "Sport"}
-      - {id: 6, cat: "Audio", desc: "Audio Track"}
-      - {id: 7, cat: "XXX", desc: "XXX"}
-      - {id: 8, cat: "Other", desc: "Misc/Demo"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: /login
-    method: form
-    form: form
-    inputs:
-      uname: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table.main:contains("Login Failed!")
-    test:
-      path: my.php
-
-  download:
-    selector: a[href^="/download.php"]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table#torrent-list > tbody > tr:has(a[href^="/details.php?id="])
-    fields:
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      title:
-        selector: td:nth-child(3) a
-      download:
-        selector: a[href^="/download.php"]
-        attribute: href
-      details:
-        selector: a[href^="/details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(7) a
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " ago"
-      downloadvolumefactor:
-        case:
-          "a[title=\"25% Free Leech: only 75% of the download is counted.\"]": "0.25"
-          "a[title=\"50% Free Leech: only half the download is counted.\"]": "0.5"
-          "a[title=\"100% FL: no download is counted.\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: hdbits
+  name: HDBits
+  description: "Best HD Tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://hdbits.org
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: "Movies", desc: "Movie"}
+      - {id: 2, cat: "TV", desc: "TV"}
+      - {id: 3, cat: "TV/Documentary", desc: "Documentary"}
+      - {id: 4, cat: "Audio", desc: "Music"}
+      - {id: 5, cat: "TV/Sport", desc: "Sport"}
+      - {id: 6, cat: "Audio", desc: "Audio Track"}
+      - {id: 7, cat: "XXX", desc: "XXX"}
+      - {id: 8, cat: "Other", desc: "Misc/Demo"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: /login
+    method: form
+    form: form
+    inputs:
+      uname: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table.main:contains("Login Failed!")
+    test:
+      path: my.php
+
+  download:
+    selector: a[href^="/download.php"]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table#torrent-list > tbody > tr:has(a[href^="/details.php?id="])
+    fields:
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      title:
+        selector: td:nth-child(3) a
+      download:
+        selector: a[href^="/download.php"]
+        attribute: href
+      details:
+        selector: a[href^="/details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(7) a
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " ago"
+      downloadvolumefactor:
+        case:
+          "a[title=\"25% Free Leech: only 75% of the download is counted.\"]": "0.25"
+          "a[title=\"50% Free Leech: only half the download is counted.\"]": "0.5"
+          "a[title=\"100% FL: no download is counted.\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/hdbitscom.yml b/src/Jackett/Definitions/hdbitscom.yml
index 96894cc44ff0b702e4701e8b75c651c689150913..87eb74075ee1f897c4170e79982a6f136a25d01a 100644
--- a/src/Jackett/Definitions/hdbitscom.yml
+++ b/src/Jackett/Definitions/hdbitscom.yml
@@ -1,97 +1,97 @@
----
-  site: hdbitscom
-  name: HD-Bits.com
-  description: "HD tracker"
-  language: en-us
-  encoding: UTF-8
-  type: private
-  links:
-    - https://www.hd-bits.com
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Audio, desc: "Music"}
-      - {id: 2, cat: Movies, desc: "Movies"}
-      - {id: 3, cat: TV, desc: "TV-Series"}
-      - {id: 4, cat: PC, desc: "Applications"}
-      - {id: 5, cat: XXX, desc: "Adult"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: 1
-      login: "Log in"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: torrents.php
-
-  ratio:
-    path: torrents.php
-    selector: li#stats_ratio > span
-
-  search:
-    path: torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: time
-      order_way: desc
-      action: basic
-      searchsubmit: 1
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      description:
-        selector: div.group_info div.tags
-      title:
-        selector: div.group_info a[href^="torrents.php?id="]
-      category:
-        selector: td.cats_col
-        case:
-          div.cats_music: 1
-          div.cats_movies: 2
-          div.cats_tvseries: 3
-          div.cats_applications: 4
-          div.cats_xxx: 5
-      comments:
-        selector: a[href^="torrents.php?id="]
-        attribute: href
-      imdb:
-        selector: a[href*="http://www.imdb.com/title/"]
-        optional: true
-        attribute: href
-      banner:
-        selector: img[alt="Cover"]
-        optional: true
-        attribute: src
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          "div.freeleech:contains('Freeleech!')": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: hdbitscom
+  name: HD-Bits.com
+  description: "HD tracker"
+  language: en-us
+  encoding: UTF-8
+  type: private
+  links:
+    - https://www.hd-bits.com
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Audio, desc: "Music"}
+      - {id: 2, cat: Movies, desc: "Movies"}
+      - {id: 3, cat: TV, desc: "TV-Series"}
+      - {id: 4, cat: PC, desc: "Applications"}
+      - {id: 5, cat: XXX, desc: "Adult"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: 1
+      login: "Log in"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: torrents.php
+
+  ratio:
+    path: torrents.php
+    selector: li#stats_ratio > span
+
+  search:
+    path: torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: time
+      order_way: desc
+      action: basic
+      searchsubmit: 1
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      description:
+        selector: div.group_info div.tags
+      title:
+        selector: div.group_info a[href^="torrents.php?id="]
+      category:
+        selector: td.cats_col
+        case:
+          div.cats_music: 1
+          div.cats_movies: 2
+          div.cats_tvseries: 3
+          div.cats_applications: 4
+          div.cats_xxx: 5
+      comments:
+        selector: a[href^="torrents.php?id="]
+        attribute: href
+      imdb:
+        selector: a[href*="http://www.imdb.com/title/"]
+        optional: true
+        attribute: href
+      banner:
+        selector: img[alt="Cover"]
+        optional: true
+        attribute: src
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          "div.freeleech:contains('Freeleech!')": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/hdchina.yml b/src/Jackett/Definitions/hdchina.yml
index 372de77d4c82d9ef96060bdfff3bc47d42543035..f96878bc4dbfe72ce34ffd4e771386e27e566b2d 100755
--- a/src/Jackett/Definitions/hdchina.yml
+++ b/src/Jackett/Definitions/hdchina.yml
@@ -1,121 +1,121 @@
----
-  site: hdchina
-  name: HDChina
-  description: "A chinese tracker"
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://hdchina.club/
-
-  caps:
-    categorymappings:
-      - {id: 20, cat: Movies/BluRay, desc: "Movie Full BD"}
-      - {id: 17, cat: Movies/HD, desc: "Movie 1080p"}
-      - {id: 16, cat: Movies/HD, desc: "Movie 1080i"}
-      - {id: 9, cat: Movies/HD, desc: "Movie 720p"}
-      - {id: 13, cat: TV, desc: "EU/US TV series"}
-      - {id: 25, cat: TV, desc: "Chinese TV series"}
-      - {id: 26, cat: TV, desc: "Kor Drama"}
-      - {id: 24, cat: TV, desc: "Jpn Drama"}
-      - {id: 21, cat: TV, desc: "EU/US TV series pack"}
-      - {id: 22, cat: TV, desc: "Chinese TV series pack"}
-      - {id: 23, cat: TV, desc: "JPN/KOR drama pack"}
-      - {id: 27, cat: Movies/SD, desc: "iPad Video"}
-      - {id: 5, cat: TV/Documentary, desc: "Documentary"}
-      - {id: 15, cat: TV/Sport, desc: "Sports"}
-      - {id: 14, cat: TV/Anime, desc: "Animation"}
-      - {id: 401, cat: TV, desc: "TV Shows"}
-      - {id: 402, cat: Audio, desc: "Vocal Concert"}
-      - {id: 406, cat: Audio, desc: "Music Video"}
-      - {id: 408, cat: Audio, desc: "Music"}
-      - {id: 19, cat: Audio, desc: "Audio Track"}
-      - {id: 405, cat: Audio, desc: "Drama"}
-      - {id: 404, cat: Books, desc: "Book"}
-      - {id: 409, cat: Other, desc: "Other"}
-      - {id: 410, cat: Movies/HD, desc: "4K UltraHD"}
-      - {id: 411, cat: TV, desc: "Travel"}
-      - {id: 412, cat: TV, desc: "Food"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    captcha:
-      type: image
-      image: img[alt="CAPTCHA"]
-      input: imagestring
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "0"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: "0"
-    rows:
-      selector: table.torrent_list > tbody > tr:has(a[href^="?cat="])
-    fields:
-      title:
-        selector: td:nth-child(2) a
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php", "download.php"]
-      size:
-        selector: td.t_size
-      grabs:
-        selector: td.t_completed
-      seeders:
-        selector: td.t_torrents
-      leechers:
-        selector: td.t_leech
-      date:
-        selector: td.t_time
-        filters:
-          - name: replace
-            args: ["时", " hours"]
-          - name: replace
-            args: ["分", " minutes"]
-          - name: replace
-            args: ["天", " days"]
-          - name: replace
-            args: ["年", " year"]
-          - name: replace
-            args: ["月", " months"]
-          - name: append
-            args: " ago"
-      downloadvolumefactor:
-        case:
-          img.pro_50pctdown: ".5"
-          img.pro_30pctdown: ".3"
-          img.pro_free: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: hdchina
+  name: HDChina
+  description: "A chinese tracker"
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://hdchina.club/
+
+  caps:
+    categorymappings:
+      - {id: 20, cat: Movies/BluRay, desc: "Movie Full BD"}
+      - {id: 17, cat: Movies/HD, desc: "Movie 1080p"}
+      - {id: 16, cat: Movies/HD, desc: "Movie 1080i"}
+      - {id: 9, cat: Movies/HD, desc: "Movie 720p"}
+      - {id: 13, cat: TV, desc: "EU/US TV series"}
+      - {id: 25, cat: TV, desc: "Chinese TV series"}
+      - {id: 26, cat: TV, desc: "Kor Drama"}
+      - {id: 24, cat: TV, desc: "Jpn Drama"}
+      - {id: 21, cat: TV, desc: "EU/US TV series pack"}
+      - {id: 22, cat: TV, desc: "Chinese TV series pack"}
+      - {id: 23, cat: TV, desc: "JPN/KOR drama pack"}
+      - {id: 27, cat: Movies/SD, desc: "iPad Video"}
+      - {id: 5, cat: TV/Documentary, desc: "Documentary"}
+      - {id: 15, cat: TV/Sport, desc: "Sports"}
+      - {id: 14, cat: TV/Anime, desc: "Animation"}
+      - {id: 401, cat: TV, desc: "TV Shows"}
+      - {id: 402, cat: Audio, desc: "Vocal Concert"}
+      - {id: 406, cat: Audio, desc: "Music Video"}
+      - {id: 408, cat: Audio, desc: "Music"}
+      - {id: 19, cat: Audio, desc: "Audio Track"}
+      - {id: 405, cat: Audio, desc: "Drama"}
+      - {id: 404, cat: Books, desc: "Book"}
+      - {id: 409, cat: Other, desc: "Other"}
+      - {id: 410, cat: Movies/HD, desc: "4K UltraHD"}
+      - {id: 411, cat: TV, desc: "Travel"}
+      - {id: 412, cat: TV, desc: "Food"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    captcha:
+      type: image
+      image: img[alt="CAPTCHA"]
+      input: imagestring
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "0"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: "0"
+    rows:
+      selector: table.torrent_list > tbody > tr:has(a[href^="?cat="])
+    fields:
+      title:
+        selector: td:nth-child(2) a
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php", "download.php"]
+      size:
+        selector: td.t_size
+      grabs:
+        selector: td.t_completed
+      seeders:
+        selector: td.t_torrents
+      leechers:
+        selector: td.t_leech
+      date:
+        selector: td.t_time
+        filters:
+          - name: replace
+            args: ["时", " hours"]
+          - name: replace
+            args: ["分", " minutes"]
+          - name: replace
+            args: ["天", " days"]
+          - name: replace
+            args: ["年", " year"]
+          - name: replace
+            args: ["月", " months"]
+          - name: append
+            args: " ago"
+      downloadvolumefactor:
+        case:
+          img.pro_50pctdown: ".5"
+          img.pro_30pctdown: ".3"
+          img.pro_free: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/hdhome.yml b/src/Jackett/Definitions/hdhome.yml
index d411aacc1a8b1a93381fd12cd42a523acd3793a5..79400ee3378318834ab3e7abb7fdc4ebb129dcf3 100644
--- a/src/Jackett/Definitions/hdhome.yml
+++ b/src/Jackett/Definitions/hdhome.yml
@@ -1,142 +1,142 @@
----
-  site: hdhome
-  name: HDHome
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://hdhome.org
-
-  caps:
-    categorymappings:
-      - {id: 411, cat: Movies/SD, desc: "Movies SD"}
-      - {id: 412, cat: Movies/SD, desc: "Movies IPad"}
-      - {id: 413, cat: Movies/HD, desc: "Movies 720p"}
-      - {id: 414, cat: Movies/HD, desc: "Movies 1080p"}
-      - {id: 415, cat: Movies/HD, desc: "Movies REMUX"}
-      - {id: 450, cat: Movies/BluRay, desc: "Movies Bluray"}
-      - {id: 416, cat: Movies/HD, desc: "Movies 2160p"}
-      - {id: 417, cat: TV/Documentary, desc: "Doc SD"}
-      - {id: 418, cat: TV/Documentary, desc: "Doc IPad"}
-      - {id: 419, cat: TV/Documentary, desc: "Doc 720p"}
-      - {id: 420, cat: TV/Documentary, desc: "Doc 1080p"}
-      - {id: 421, cat: TV/Documentary, desc: "Doc REMUX"}
-      - {id: 451, cat: TV/Documentary, desc: "Doc Bluray"}
-      - {id: 422, cat: TV/Documentary, desc: "Doc 2160p"}
-      - {id: 423, cat: TV/HD, desc: "TVMusic 720p"}
-      - {id: 424, cat: TV/HD, desc: "TVMusic 1080i"}
-      - {id: 425, cat: TV/SD, desc: "TVShow SD"}
-      - {id: 426, cat: TV/SD, desc: "TVShow IPad"}
-      - {id: 427, cat: TV/HD, desc: "TVShow 720p"}
-      - {id: 428, cat: TV/HD, desc: "TVShow 1080i"}
-      - {id: 429, cat: TV/HD, desc: "TVShow 1080p"}
-      - {id: 430, cat: TV/HD, desc: "TVShow REMUX"}
-      - {id: 452, cat: TV/HD, desc: "TVShows Bluray"}
-      - {id: 431, cat: TV/HD, desc: "TVShow 2160p"}
-      - {id: 432, cat: TV/SD, desc: "TVSeries SD"}
-      - {id: 433, cat: TV/SD, desc: "TVSeries IPad"}
-      - {id: 434, cat: TV/HD, desc: "TVSeries 720p"}
-      - {id: 435, cat: TV/HD, desc: "TVSeries 1080i"}
-      - {id: 436, cat: TV/HD, desc: "TVSeries 1080p"}
-      - {id: 437, cat: TV/HD, desc: "TVSeries REMUX"}
-      - {id: 453, cat: TV/HD, desc: "TVSereis Bluray"}
-      - {id: 438, cat: TV/HD, desc: "TVSeries 2160p"}
-      - {id: 439, cat: Audio/Other, desc: "Musics APE"}
-      - {id: 440, cat: Audio/Lossless, desc: "Musics FLAC"}
-      - {id: 441, cat: Audio/Video, desc: "Musics MV"}
-      - {id: 442, cat: TV/Sport, desc: "Sports 720p"}
-      - {id: 443, cat: TV/Sport, desc: "Sports 1080i"}
-      - {id: 444, cat: TV/Anime, desc: "Anime SD"}
-      - {id: 445, cat: TV/Anime, desc: "Anime IPad"}
-      - {id: 446, cat: TV/Anime, desc: "Anime 720p"}
-      - {id: 447, cat: TV/Anime, desc: "Anime 1080p"}
-      - {id: 448, cat: TV/Anime, desc: "Anime REMUX"}
-      - {id: 454, cat: TV/Anime, desc: "Anime Bluray"}
-      - {id: 409, cat: Other, desc: "Misc"}
-      - {id: 449, cat: TV/Anime, desc: "Anime 2160p"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    captcha:
-      type: image
-      image: img[alt="CAPTCHA"]
-      input: imagestring
-    inputs:
-      logintype: "username"
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("姿势不正确"))
-      - selector: td.embedded:has(h2:contains("失败"))
-    test:
-      path: /torrents.php
-        
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "1"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: "0"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[title][href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      size:
-        selector: td.rowfollow:nth-child(5)
-      grabs:
-        selector: td.rowfollow:nth-child(8)
-      seeders:
-        selector: td.rowfollow:nth-child(6)
-      leechers:
-        selector: td.rowfollow:nth-child(7)
-      date:
-        selector: td.rowfollow:nth-child(4) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
+---
+  site: hdhome
+  name: HDHome
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://hdhome.org
+
+  caps:
+    categorymappings:
+      - {id: 411, cat: Movies/SD, desc: "Movies SD"}
+      - {id: 412, cat: Movies/SD, desc: "Movies IPad"}
+      - {id: 413, cat: Movies/HD, desc: "Movies 720p"}
+      - {id: 414, cat: Movies/HD, desc: "Movies 1080p"}
+      - {id: 415, cat: Movies/HD, desc: "Movies REMUX"}
+      - {id: 450, cat: Movies/BluRay, desc: "Movies Bluray"}
+      - {id: 416, cat: Movies/HD, desc: "Movies 2160p"}
+      - {id: 417, cat: TV/Documentary, desc: "Doc SD"}
+      - {id: 418, cat: TV/Documentary, desc: "Doc IPad"}
+      - {id: 419, cat: TV/Documentary, desc: "Doc 720p"}
+      - {id: 420, cat: TV/Documentary, desc: "Doc 1080p"}
+      - {id: 421, cat: TV/Documentary, desc: "Doc REMUX"}
+      - {id: 451, cat: TV/Documentary, desc: "Doc Bluray"}
+      - {id: 422, cat: TV/Documentary, desc: "Doc 2160p"}
+      - {id: 423, cat: TV/HD, desc: "TVMusic 720p"}
+      - {id: 424, cat: TV/HD, desc: "TVMusic 1080i"}
+      - {id: 425, cat: TV/SD, desc: "TVShow SD"}
+      - {id: 426, cat: TV/SD, desc: "TVShow IPad"}
+      - {id: 427, cat: TV/HD, desc: "TVShow 720p"}
+      - {id: 428, cat: TV/HD, desc: "TVShow 1080i"}
+      - {id: 429, cat: TV/HD, desc: "TVShow 1080p"}
+      - {id: 430, cat: TV/HD, desc: "TVShow REMUX"}
+      - {id: 452, cat: TV/HD, desc: "TVShows Bluray"}
+      - {id: 431, cat: TV/HD, desc: "TVShow 2160p"}
+      - {id: 432, cat: TV/SD, desc: "TVSeries SD"}
+      - {id: 433, cat: TV/SD, desc: "TVSeries IPad"}
+      - {id: 434, cat: TV/HD, desc: "TVSeries 720p"}
+      - {id: 435, cat: TV/HD, desc: "TVSeries 1080i"}
+      - {id: 436, cat: TV/HD, desc: "TVSeries 1080p"}
+      - {id: 437, cat: TV/HD, desc: "TVSeries REMUX"}
+      - {id: 453, cat: TV/HD, desc: "TVSereis Bluray"}
+      - {id: 438, cat: TV/HD, desc: "TVSeries 2160p"}
+      - {id: 439, cat: Audio/Other, desc: "Musics APE"}
+      - {id: 440, cat: Audio/Lossless, desc: "Musics FLAC"}
+      - {id: 441, cat: Audio/Video, desc: "Musics MV"}
+      - {id: 442, cat: TV/Sport, desc: "Sports 720p"}
+      - {id: 443, cat: TV/Sport, desc: "Sports 1080i"}
+      - {id: 444, cat: TV/Anime, desc: "Anime SD"}
+      - {id: 445, cat: TV/Anime, desc: "Anime IPad"}
+      - {id: 446, cat: TV/Anime, desc: "Anime 720p"}
+      - {id: 447, cat: TV/Anime, desc: "Anime 1080p"}
+      - {id: 448, cat: TV/Anime, desc: "Anime REMUX"}
+      - {id: 454, cat: TV/Anime, desc: "Anime Bluray"}
+      - {id: 409, cat: Other, desc: "Misc"}
+      - {id: 449, cat: TV/Anime, desc: "Anime 2160p"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    captcha:
+      type: image
+      image: img[alt="CAPTCHA"]
+      input: imagestring
+    inputs:
+      logintype: "username"
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("姿势不正确"))
+      - selector: td.embedded:has(h2:contains("失败"))
+    test:
+      path: /torrents.php
+        
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "1"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: "0"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[title][href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      size:
+        selector: td.rowfollow:nth-child(5)
+      grabs:
+        selector: td.rowfollow:nth-child(8)
+      seeders:
+        selector: td.rowfollow:nth-child(6)
+      leechers:
+        selector: td.rowfollow:nth-child(7)
+      date:
+        selector: td.rowfollow:nth-child(4) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
         remove: a, img
\ No newline at end of file
diff --git a/src/Jackett/Definitions/hdsky.yml b/src/Jackett/Definitions/hdsky.yml
index aebefef446d1e181985cbd001aa66cabb5957214..fffd54c4c72137d8b0feb54447a6cfd42f74baab 100644
--- a/src/Jackett/Definitions/hdsky.yml
+++ b/src/Jackett/Definitions/hdsky.yml
@@ -1,119 +1,119 @@
----
-  site: hdsky
-  name: HDSky
-  description: "A chinese tracker"
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://hdsky.me
-
-  caps:
-    categorymappings:
-      - {id: 401, cat: Movies, desc: "Movies/电影"}
-      - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
-      - {id: 410, cat: Movies, desc: "iPad/iPad影视"}
-      - {id: 405, cat: TV/Anime, desc: "Animations/动漫"}
-      - {id: 402, cat: TV, desc: "TV Series/剧集"}
-      - {id: 403, cat: TV, desc: "TV Shows/综艺"}
-      - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
-      - {id: 407, cat: TV/Sport, desc: "Sports/体育"}
-      - {id: 408, cat: Audio, desc: "HQ Audio/无损音乐"}
-      - {id: 409, cat: Other, desc: "Misc/其他"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    captcha:
-      type: image
-      image: img[alt="CAPTCHA"]
-      input: imagestring
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-
-  ratio:
-    path: /torrents.php
-    selector: table#info_block
-    filters:
-      - name: regexp
-        args: "Ratio:\\s(.*?)\\s\\s"
-        
-  download:
-    method: post
-
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "1"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: "0"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[title][href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: form[action^="download.php?id="]
-        attribute: action
-      imdb:
-        selector: a[href^="http://www.imdb.com/title/tt"]
-        attribute: href
-      size:
-        selector: td.rowfollow:nth-child(5)
-      grabs:
-        selector: td.rowfollow:nth-child(8)
-      seeders:
-        selector: td.rowfollow:nth-child(6)
-      leechers:
-        selector: td.rowfollow:nth-child(7)
-      date:
-        selector: td.rowfollow:nth-child(4) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
+---
+  site: hdsky
+  name: HDSky
+  description: "A chinese tracker"
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://hdsky.me
+
+  caps:
+    categorymappings:
+      - {id: 401, cat: Movies, desc: "Movies/电影"}
+      - {id: 404, cat: TV/Documentary, desc: "Documentaries/纪录片"}
+      - {id: 410, cat: Movies, desc: "iPad/iPad影视"}
+      - {id: 405, cat: TV/Anime, desc: "Animations/动漫"}
+      - {id: 402, cat: TV, desc: "TV Series/剧集"}
+      - {id: 403, cat: TV, desc: "TV Shows/综艺"}
+      - {id: 406, cat: Audio/Video, desc: "Music Videos/音乐MV"}
+      - {id: 407, cat: TV/Sport, desc: "Sports/体育"}
+      - {id: 408, cat: Audio, desc: "HQ Audio/无损音乐"}
+      - {id: 409, cat: Other, desc: "Misc/其他"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    captcha:
+      type: image
+      image: img[alt="CAPTCHA"]
+      input: imagestring
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+
+  ratio:
+    path: /torrents.php
+    selector: table#info_block
+    filters:
+      - name: regexp
+        args: "Ratio:\\s(.*?)\\s\\s"
+        
+  download:
+    method: post
+
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "1"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: "0"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[title][href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: form[action^="download.php?id="]
+        attribute: action
+      imdb:
+        selector: a[href^="http://www.imdb.com/title/tt"]
+        attribute: href
+      size:
+        selector: td.rowfollow:nth-child(5)
+      grabs:
+        selector: td.rowfollow:nth-child(8)
+      seeders:
+        selector: td.rowfollow:nth-child(6)
+      leechers:
+        selector: td.rowfollow:nth-child(7)
+      date:
+        selector: td.rowfollow:nth-child(4) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
         remove: a, img
\ No newline at end of file
diff --git a/src/Jackett/Definitions/hyperay.yml b/src/Jackett/Definitions/hyperay.yml
index e40d66e9dff72a9b7e0d2c8f269c33748bad9f71..dff64c7e542da69386543e307f8913abcb298bde 100644
--- a/src/Jackett/Definitions/hyperay.yml
+++ b/src/Jackett/Definitions/hyperay.yml
@@ -1,107 +1,107 @@
----
-  site: hyperay
-  name: Hyperay
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://www.hyperay.cc
-
-  caps:
-    categorymappings:
-      - {id: 410, cat: Movies/HD, desc: "Movies 1080p"}
-      - {id: 411, cat: Movies/HD, desc: "Movies 720p"}
-      - {id: 401, cat: Movies/BluRay, desc: "Movies Blu-ray"}
-      - {id: 415, cat: Movies, desc: "Movies REMUX"}
-      - {id: 416, cat: Movies/3D, desc: "Movies 3D"}
-      - {id: 414, cat: Movies/DVD, desc: "Movies DVD"}
-      - {id: 412, cat: Movies/WEBDL, desc: "Movies WEB-DL"}
-      - {id: 413, cat: Movies/SD, desc: "Movies HDTV"}
-      - {id: 417, cat: Movies/Other, desc: "Movies iPad"}
-      - {id: 402, cat: TV, desc: "TV Series"}
-      - {id: 403, cat: TV, desc: "TV Shows"}
-      - {id: 404, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 405, cat: TV/Anime, desc: "Animations"}
-      - {id: 406, cat: Audio/Video, desc: "Music Videos"}
-      - {id: 407, cat: TV/Sport, desc: "Sports"}
-      - {id: 408, cat: Audio, desc: "HQ Audio"}
-      - {id: 418, cat: Books, desc: "Book"}
-      - {id: 409, cat: Other, desc: "Misc"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      authcode: ""
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "1"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: "0"
-    rows:
-      selector: table.torrents > tbody > tr[class]
-    fields:
-      title:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[title][href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      imdb:
-        selector: a[href^="http://www.imdb.com/title/"]
-        attribute: href
-      banner:
-        selector: a[title][onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "showmenu\\(this,'.*','(.*)'\\);"
-      size:
-        selector: td.rowfollow:nth-child(6)
-      grabs:
-        selector: td.rowfollow:nth-child(9)
-      seeders:
-        selector: td.rowfollow:nth-child(7)
-      leechers:
-        selector: td.rowfollow:nth-child(8)
-      date:
-        selector: td.rowfollow:nth-child(5) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: hyperay
+  name: Hyperay
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://www.hyperay.cc
+
+  caps:
+    categorymappings:
+      - {id: 410, cat: Movies/HD, desc: "Movies 1080p"}
+      - {id: 411, cat: Movies/HD, desc: "Movies 720p"}
+      - {id: 401, cat: Movies/BluRay, desc: "Movies Blu-ray"}
+      - {id: 415, cat: Movies, desc: "Movies REMUX"}
+      - {id: 416, cat: Movies/3D, desc: "Movies 3D"}
+      - {id: 414, cat: Movies/DVD, desc: "Movies DVD"}
+      - {id: 412, cat: Movies/WEBDL, desc: "Movies WEB-DL"}
+      - {id: 413, cat: Movies/SD, desc: "Movies HDTV"}
+      - {id: 417, cat: Movies/Other, desc: "Movies iPad"}
+      - {id: 402, cat: TV, desc: "TV Series"}
+      - {id: 403, cat: TV, desc: "TV Shows"}
+      - {id: 404, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 405, cat: TV/Anime, desc: "Animations"}
+      - {id: 406, cat: Audio/Video, desc: "Music Videos"}
+      - {id: 407, cat: TV/Sport, desc: "Sports"}
+      - {id: 408, cat: Audio, desc: "HQ Audio"}
+      - {id: 418, cat: Books, desc: "Book"}
+      - {id: 409, cat: Other, desc: "Misc"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      authcode: ""
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "1"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: "0"
+    rows:
+      selector: table.torrents > tbody > tr[class]
+    fields:
+      title:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[title][href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      imdb:
+        selector: a[href^="http://www.imdb.com/title/"]
+        attribute: href
+      banner:
+        selector: a[title][onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "showmenu\\(this,'.*','(.*)'\\);"
+      size:
+        selector: td.rowfollow:nth-child(6)
+      grabs:
+        selector: td.rowfollow:nth-child(9)
+      seeders:
+        selector: td.rowfollow:nth-child(7)
+      leechers:
+        selector: td.rowfollow:nth-child(8)
+      date:
+        selector: td.rowfollow:nth-child(5) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/icetorrent.yml b/src/Jackett/Definitions/icetorrent.yml
index 037ec2691ba41f2a564d5366f97e3fd496d153be..309ffdd766117db213a9d358a9d1db8ca0cab53a 100755
--- a/src/Jackett/Definitions/icetorrent.yml
+++ b/src/Jackett/Definitions/icetorrent.yml
@@ -1,151 +1,151 @@
----
-  site: icetorrent
-  name: ICE Torrent
-  language: ro-ro
-  type: private
-  encoding: UTF-8
-  links:
-    - https://www.icetorrent.org
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: PC/0day , desc: "Appz"}
-      - {id: 85, cat: Audio/Audiobook, desc: "AudioBooks"}
-      - {id: 68, cat: Books, desc: "Carti/Reviste"}
-      - {id: 23, cat: Books, desc: "Cartoons"}
-      - {id: 73, cat: Audio/Video, desc: "Concert/Videoclip"}
-      - {id: 75, cat: Other, desc: "Diverse"}
-      - {id: 69, cat: Books, desc: "Documentare"}
-      - {id: 51, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 43, cat: Books, desc: "eBooks"}
-      - {id: 63, cat: Movies/DVD, desc: "Filme DVD"}
-      - {id: 65, cat: Movies/HD, desc: "Filme HD"}
-      - {id: 64, cat: Movies/SD, desc: "Filme Xvid"}
-      - {id: 40, cat: Console, desc: "Games/Console"}
-      - {id: 26, cat: PC/Games, desc: "Games/PC"}
-      - {id: 38, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 59, cat: Movies/3D, desc: "Movies/3D"}
-      - {id: 92, cat: Movies/HD, desc: "Movies/4K-UHD"}
-      - {id: 32, cat: Movies/BluRay, desc: "Movies/Blu-Ray"}
-      - {id: 28, cat: Movies/DVD, desc: "Movies/DVD"}
-      - {id: 42, cat: Movies/HD, desc: "Movies/HD-x264"}
-      - {id: 91, cat: Movies/HD, desc: "Movies/HEVC-x265"}
-      - {id: 79, cat: Movies/HD, desc: "Movies/microHD"}
-      - {id: 29, cat: Movies/SD, desc: "Movies/SD"}
-      - {id: 72, cat: Audio/Lossless, desc: "Music/FLAC"}
-      - {id: 6, cat: Audio/MP3, desc: "Music/MP3"}
-      - {id: 37, cat: Audio/Video, desc: "Music/Video"}
-      - {id: 70, cat: Audio/Lossless, desc: "Muzica FLAC"}
-      - {id: 71, cat: Audio/MP3, desc: "Muzica MP3"}
-      - {id: 74, cat: Other, desc: "Other"}
-      - {id: 41, cat: Other, desc: "Pictures"}
-      - {id: 67, cat: TV, desc: "Seriale TV"}
-      - {id: 48, cat: TV/Sport, desc: "Sports"}
-      - {id: 87, cat: Other, desc: "TUTS"}
-      - {id: 33, cat: TV/SD, desc: "TV Episodes"}
-      - {id: 34, cat: TV/HD, desc: "TVHD Episodes"}
-      - {id: 9, cat: XXX, desc: "XXX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: /login.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: font:contains("failed") + table
-    test:
-      path: /browse.php
-      
-  ratio:
-    text: -1
-
-  search:
-    paths:
-    - path: browse.php
-      categorymappings: ["!", 9]
-    - path: browseadult.php
-      categorymappings: [9]
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: 1
-      search_by: "{{ if .Query.IMDBID }}imdb{{else}}name{{end}}"
-    rows:
-      selector: table.torrenttable > tbody > tr:has(a[title][href^="details.php?id="])
-    fields:
-      title:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      details:
-        selector: a[title][href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href*=".php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      imdb:
-        selector: a[title="IMDB"]
-        attribute: href
-      banner:
-        attribute: rel
-      imdb:
-        selector: a[href^="http://www.imdb.com/title/"]
-        optional: true
-        attribute: href
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(5) > a
-        filters:
-          - name: regexp
-            args: (\d+)
-      size:
-        selector: td:nth-child(5)
-        remove: a
-      date:
-        selector: td:nth-child(2) > div
-        remove: b
-        filters:
-          - name: replace
-            args: ["\xA0", " "]
-          - name: replace
-            args: ["Added on ", ""]
-          - name: replace
-            args: ["st ", " "]
-          - name: replace
-            args: ["nd ", " "]
-          - name: replace
-            args: ["rd ", " "]  
-          - name: replace
-            args: ["th ", " "]
-          - name: replace
-            args: [" by", ""]
-          - name: append
-            args: " +02:00"
-          - name: dateparse
-            args: "2 Jan 2006 15:04:05 -07:00"
-      grabs:
-        selector: td:nth-child(6)
-      downloadvolumefactor:
-        case:
-          "*": "0"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a[title][href^="details.php?id="], div
-      seeders:
-        text: "9999"
-      leechers:
-        text: "9999"
+---
+  site: icetorrent
+  name: ICE Torrent
+  language: ro-ro
+  type: private
+  encoding: UTF-8
+  links:
+    - https://www.icetorrent.org
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: PC/0day , desc: "Appz"}
+      - {id: 85, cat: Audio/Audiobook, desc: "AudioBooks"}
+      - {id: 68, cat: Books, desc: "Carti/Reviste"}
+      - {id: 23, cat: Books, desc: "Cartoons"}
+      - {id: 73, cat: Audio/Video, desc: "Concert/Videoclip"}
+      - {id: 75, cat: Other, desc: "Diverse"}
+      - {id: 69, cat: Books, desc: "Documentare"}
+      - {id: 51, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 43, cat: Books, desc: "eBooks"}
+      - {id: 63, cat: Movies/DVD, desc: "Filme DVD"}
+      - {id: 65, cat: Movies/HD, desc: "Filme HD"}
+      - {id: 64, cat: Movies/SD, desc: "Filme Xvid"}
+      - {id: 40, cat: Console, desc: "Games/Console"}
+      - {id: 26, cat: PC/Games, desc: "Games/PC"}
+      - {id: 38, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 59, cat: Movies/3D, desc: "Movies/3D"}
+      - {id: 92, cat: Movies/HD, desc: "Movies/4K-UHD"}
+      - {id: 32, cat: Movies/BluRay, desc: "Movies/Blu-Ray"}
+      - {id: 28, cat: Movies/DVD, desc: "Movies/DVD"}
+      - {id: 42, cat: Movies/HD, desc: "Movies/HD-x264"}
+      - {id: 91, cat: Movies/HD, desc: "Movies/HEVC-x265"}
+      - {id: 79, cat: Movies/HD, desc: "Movies/microHD"}
+      - {id: 29, cat: Movies/SD, desc: "Movies/SD"}
+      - {id: 72, cat: Audio/Lossless, desc: "Music/FLAC"}
+      - {id: 6, cat: Audio/MP3, desc: "Music/MP3"}
+      - {id: 37, cat: Audio/Video, desc: "Music/Video"}
+      - {id: 70, cat: Audio/Lossless, desc: "Muzica FLAC"}
+      - {id: 71, cat: Audio/MP3, desc: "Muzica MP3"}
+      - {id: 74, cat: Other, desc: "Other"}
+      - {id: 41, cat: Other, desc: "Pictures"}
+      - {id: 67, cat: TV, desc: "Seriale TV"}
+      - {id: 48, cat: TV/Sport, desc: "Sports"}
+      - {id: 87, cat: Other, desc: "TUTS"}
+      - {id: 33, cat: TV/SD, desc: "TV Episodes"}
+      - {id: 34, cat: TV/HD, desc: "TVHD Episodes"}
+      - {id: 9, cat: XXX, desc: "XXX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: /login.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: font:contains("failed") + table
+    test:
+      path: /browse.php
+      
+  ratio:
+    text: -1
+
+  search:
+    paths:
+    - path: browse.php
+      categorymappings: ["!", 9]
+    - path: browseadult.php
+      categorymappings: [9]
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: 1
+      search_by: "{{ if .Query.IMDBID }}imdb{{else}}name{{end}}"
+    rows:
+      selector: table.torrenttable > tbody > tr:has(a[title][href^="details.php?id="])
+    fields:
+      title:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      details:
+        selector: a[title][href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href*=".php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      imdb:
+        selector: a[title="IMDB"]
+        attribute: href
+      banner:
+        attribute: rel
+      imdb:
+        selector: a[href^="http://www.imdb.com/title/"]
+        optional: true
+        attribute: href
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(5) > a
+        filters:
+          - name: regexp
+            args: (\d+)
+      size:
+        selector: td:nth-child(5)
+        remove: a
+      date:
+        selector: td:nth-child(2) > div
+        remove: b
+        filters:
+          - name: replace
+            args: ["\xA0", " "]
+          - name: replace
+            args: ["Added on ", ""]
+          - name: replace
+            args: ["st ", " "]
+          - name: replace
+            args: ["nd ", " "]
+          - name: replace
+            args: ["rd ", " "]  
+          - name: replace
+            args: ["th ", " "]
+          - name: replace
+            args: [" by", ""]
+          - name: append
+            args: " +02:00"
+          - name: dateparse
+            args: "2 Jan 2006 15:04:05 -07:00"
+      grabs:
+        selector: td:nth-child(6)
+      downloadvolumefactor:
+        case:
+          "*": "0"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a[title][href^="details.php?id="], div
+      seeders:
+        text: "9999"
+      leechers:
+        text: "9999"
diff --git a/src/Jackett/Definitions/iloveclassics.yml b/src/Jackett/Definitions/iloveclassics.yml
index b29a48367eae0baf26e8d29878a41606de5071d1..78a945c1611feefa8d514bcd9230aaa9c14829f0 100644
--- a/src/Jackett/Definitions/iloveclassics.yml
+++ b/src/Jackett/Definitions/iloveclassics.yml
@@ -1,106 +1,106 @@
----
-  site: iloveclassics
-  name: I Love Classics
-  description: "Classics movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.iloveclassics.com/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Action/Adventure"}
-      - {id: 22, cat: Movies, desc: "Animation"}
-      - {id: 18, cat: Movies, desc: "Audio"}
-      - {id: 2, cat: Movies, desc: "Comedy"}
-      - {id: 12, cat: Movies, desc: "Crime/Mystery"}
-      - {id: 4, cat: Movies, desc: "Documentary"}
-      - {id: 3, cat: Movies, desc: "Drama"}
-      - {id: 24, cat: Movies, desc: "E-Book"}
-      - {id: 9, cat: Movies, desc: "Family"}
-      - {id: 23, cat: Movies, desc: "Fantasy"}
-      - {id: 6, cat: Movies, desc: "Film Noir"}
-      - {id: 7, cat: Movies, desc: "Film Short"}
-      - {id: 8, cat: Movies, desc: "Horror"}
-      - {id: 10, cat: Movies, desc: "Martial Arts"}
-      - {id: 11, cat: Movies, desc: "Musical"}
-      - {id: 20, cat: Movies, desc: "Other"}
-      - {id: 13, cat: Movies, desc: "Romance"}
-      - {id: 5, cat: Movies, desc: "Sci-Fi"}
-      - {id: 14, cat: Movies, desc: "Silent"}
-      - {id: 15, cat: Movies, desc: "Thriller"}
-      - {id: 19, cat: Movies, desc: "TV Shows"}
-      - {id: 16, cat: Movies, desc: "War"}
-      - {id: 17, cat: Movies, desc: "Western"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table#hover-over > tbody > tr.table_col1
-      filters:
-        - name: andmatch
-    fields:
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      title:
-        selector: td:nth-child(2) a
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(9)
-        filters:
-          - name: regexp
-            args: (\d+\s+)(?=x)
-      files:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(9)
-        filters:
-          - name: regexp
-            args: (\d+.*(MB|GB)+)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      date:
-        selector: td:nth-child(2)
-      downloadvolumefactor:
-        case:
-          "img[title=\"This Torrent is on Free Leech. Download amounts do not count to your ratio\"]": "0"
-          "img[title=\"This Torrent is Free Leech because it has 5 or more seeders. Download amounts do not count to your ratio while 5 seeders remain\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: iloveclassics
+  name: I Love Classics
+  description: "Classics movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.iloveclassics.com/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Action/Adventure"}
+      - {id: 22, cat: Movies, desc: "Animation"}
+      - {id: 18, cat: Movies, desc: "Audio"}
+      - {id: 2, cat: Movies, desc: "Comedy"}
+      - {id: 12, cat: Movies, desc: "Crime/Mystery"}
+      - {id: 4, cat: Movies, desc: "Documentary"}
+      - {id: 3, cat: Movies, desc: "Drama"}
+      - {id: 24, cat: Movies, desc: "E-Book"}
+      - {id: 9, cat: Movies, desc: "Family"}
+      - {id: 23, cat: Movies, desc: "Fantasy"}
+      - {id: 6, cat: Movies, desc: "Film Noir"}
+      - {id: 7, cat: Movies, desc: "Film Short"}
+      - {id: 8, cat: Movies, desc: "Horror"}
+      - {id: 10, cat: Movies, desc: "Martial Arts"}
+      - {id: 11, cat: Movies, desc: "Musical"}
+      - {id: 20, cat: Movies, desc: "Other"}
+      - {id: 13, cat: Movies, desc: "Romance"}
+      - {id: 5, cat: Movies, desc: "Sci-Fi"}
+      - {id: 14, cat: Movies, desc: "Silent"}
+      - {id: 15, cat: Movies, desc: "Thriller"}
+      - {id: 19, cat: Movies, desc: "TV Shows"}
+      - {id: 16, cat: Movies, desc: "War"}
+      - {id: 17, cat: Movies, desc: "Western"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table#hover-over > tbody > tr.table_col1
+      filters:
+        - name: andmatch
+    fields:
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      title:
+        selector: td:nth-child(2) a
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(9)
+        filters:
+          - name: regexp
+            args: (\d+\s+)(?=x)
+      files:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(9)
+        filters:
+          - name: regexp
+            args: (\d+.*(MB|GB)+)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      date:
+        selector: td:nth-child(2)
+      downloadvolumefactor:
+        case:
+          "img[title=\"This Torrent is on Free Leech. Download amounts do not count to your ratio\"]": "0"
+          "img[title=\"This Torrent is Free Leech because it has 5 or more seeders. Download amounts do not count to your ratio while 5 seeders remain\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/infinityt.yml b/src/Jackett/Definitions/infinityt.yml
index 06275298697b3984d3ce6be59c970a255ca0e2c8..af9e4d0ad15ee7f8c0e74bf0020a5181e108f806 100644
--- a/src/Jackett/Definitions/infinityt.yml
+++ b/src/Jackett/Definitions/infinityt.yml
@@ -1,106 +1,106 @@
----
-  site: infinityt
-  name: Infinity-T
-  language: da-dk
-  type: private
-  encoding: UTF-8
-  links:
-    - https://infinity-t.org/
-
-  caps:
-    categorymappings:
-      - {id: 22, cat: Audio/Audiobook, desc: "aBook"}
-      - {id: 13, cat: PC/Phone-Android, desc: "Appz/Android"}
-      - {id: 14, cat: PC/Phone-IOS, desc: "Appz/iPhone"}
-      - {id: 12, cat: PC/Mac, desc: "Appz/Mac"}
-      - {id: 11, cat: PC/0day, desc: "Appz/Win"}
-      - {id: 19, cat: Movies, desc: "AU/NEED"}
-      - {id: 20, cat: Books, desc: "eBook"}
-      - {id: 17, cat: Console, desc: "Games/Console"}
-      - {id: 16, cat: PC/Mac, desc: "Games/Mac"}
-      - {id: 15, cat: PC/Games, desc: "Games/PC"}
-      - {id: 8, cat: Movies, desc: "Movie/Boxset"}
-      - {id: 7, cat: Movies/DVD, desc: "Movie/DVD"}
-      - {id: 5, cat: Movies/HD, desc: "Movie/HD"}
-      - {id: 6, cat: Movies/SD, desc: "Movie/SD"}
-      - {id: 10, cat: Audio/Lossless, desc: "Music/FLAC"}
-      - {id: 9, cat: Audio/MP3, desc: "Music/MP3"}
-      - {id: 21, cat: Movies/Bluray, desc: "REMUX/Bluray"}
-      - {id: 4, cat: TV, desc: "TV/Boxset"}
-      - {id: 3, cat: TV, desc: "TV/DVD"}
-      - {id: 1, cat: TV/HD, desc: "TV/HD"}
-      - {id: 2, cat: TV/SD, desc: "TV/SD"}
-      - {id: 18, cat: XXX, desc: "XXX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /browse.php
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: td.outer > table > tbody > tr[id]
-    fields:
-      imdb:
-        selector: a[href^="https://www.nullrefer.com/?http://imdb.com/title/"]
-        attribute: href
-      banner:
-        selector: a[rel]
-        attribute: rel
-        filters:
-          - name: replace
-            args: ["pic/noposter.jpg", ""]
-      title:
-        selector: a[href^="details.php?id="]
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: replace
-            args: ["I Dag", "Today"]
-          - name: replace
-            args: ["I Går", "Yesterday"]
-            
-      grabs:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          td[style*="/pic/free.png"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: infinityt
+  name: Infinity-T
+  language: da-dk
+  type: private
+  encoding: UTF-8
+  links:
+    - https://infinity-t.org/
+
+  caps:
+    categorymappings:
+      - {id: 22, cat: Audio/Audiobook, desc: "aBook"}
+      - {id: 13, cat: PC/Phone-Android, desc: "Appz/Android"}
+      - {id: 14, cat: PC/Phone-IOS, desc: "Appz/iPhone"}
+      - {id: 12, cat: PC/Mac, desc: "Appz/Mac"}
+      - {id: 11, cat: PC/0day, desc: "Appz/Win"}
+      - {id: 19, cat: Movies, desc: "AU/NEED"}
+      - {id: 20, cat: Books, desc: "eBook"}
+      - {id: 17, cat: Console, desc: "Games/Console"}
+      - {id: 16, cat: PC/Mac, desc: "Games/Mac"}
+      - {id: 15, cat: PC/Games, desc: "Games/PC"}
+      - {id: 8, cat: Movies, desc: "Movie/Boxset"}
+      - {id: 7, cat: Movies/DVD, desc: "Movie/DVD"}
+      - {id: 5, cat: Movies/HD, desc: "Movie/HD"}
+      - {id: 6, cat: Movies/SD, desc: "Movie/SD"}
+      - {id: 10, cat: Audio/Lossless, desc: "Music/FLAC"}
+      - {id: 9, cat: Audio/MP3, desc: "Music/MP3"}
+      - {id: 21, cat: Movies/Bluray, desc: "REMUX/Bluray"}
+      - {id: 4, cat: TV, desc: "TV/Boxset"}
+      - {id: 3, cat: TV, desc: "TV/DVD"}
+      - {id: 1, cat: TV/HD, desc: "TV/HD"}
+      - {id: 2, cat: TV/SD, desc: "TV/SD"}
+      - {id: 18, cat: XXX, desc: "XXX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /browse.php
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: td.outer > table > tbody > tr[id]
+    fields:
+      imdb:
+        selector: a[href^="https://www.nullrefer.com/?http://imdb.com/title/"]
+        attribute: href
+      banner:
+        selector: a[rel]
+        attribute: rel
+        filters:
+          - name: replace
+            args: ["pic/noposter.jpg", ""]
+      title:
+        selector: a[href^="details.php?id="]
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: replace
+            args: ["I Dag", "Today"]
+          - name: replace
+            args: ["I Går", "Yesterday"]
+            
+      grabs:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          td[style*="/pic/free.png"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/inperil.yml b/src/Jackett/Definitions/inperil.yml
index 089d2b2f3dfe6ccbbe0c91383efadd659d19fc86..aff82ecb12fdddc5846c32d1ac9e2650c104023a 100644
--- a/src/Jackett/Definitions/inperil.yml
+++ b/src/Jackett/Definitions/inperil.yml
@@ -1,104 +1,104 @@
----
-  site: inperil
-  name: inPeril
-  type: private
-  language: lv-lv
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.inperil.net/
-
-  caps:
-    categorymappings:
-      - {id: 34, cat: TV/Anime, desc: "Animation"}
-      - {id: 22, cat: PC/0day, desc: "Appz"}
-      - {id: 25, cat: PC/Games, desc: "Games/Console"}
-      - {id: 4, cat: PC/Games, desc: "Games/PC"}
-      - {id: 27, cat: Other/Misc, desc: "Misc"}
-      - {id: 35, cat: Movies/HD, desc: "Movies/HD"}
-      - {id: 37, cat: Movies/Foreign, desc: "Movies/LAT"}
-      - {id: 42, cat: Movies, desc: "Movies/Pack"}
-      - {id: 38, cat: Movies, desc: "Movies/Retro"}
-      - {id: 36, cat: Movies/Foreign, desc: "Movies/RUS"}
-      - {id: 19, cat: Movies/SD, desc: "Movies/SD"}
-      - {id: 6, cat: Audio, desc: "Music"}
-      - {id: 26, cat: Audio/Video, desc: "Music Videos"}
-      - {id: 31, cat: Audio/Lossless, desc: "Music/FLAC"}
-      - {id: 39, cat: TV/HD, desc: "TV/HD"}
-      - {id: 43, cat: TV, desc: "TV/Pack"}
-      - {id: 7, cat: TV/SD, desc: "TV/SD"}
-      - {id: 40, cat: XXX, desc: "XXX/HD"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: font.logintext
-    test:
-      path: /browse.php
-      
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: table > tbody > tr:has(a[href^="details.php?id="])
-    fields:
-      title:
-        selector: a[href^="details.php?id="][title]
-        attribute: title
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="download.php/"]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      size:
-        selector: td:nth-child(6)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " +02:00"
-          - name: dateparse
-            args: "2006-01-0215:04:05 -07:00"
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: ([,\d]+)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      banner:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=([^\s]+)
-      downloadvolumefactor:
-        case:
-          "img[alt=\"Zelta Torrents\"]": "0"
-          "img[alt=\"Sudraba Torrents\"]": "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: inperil
+  name: inPeril
+  type: private
+  language: lv-lv
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.inperil.net/
+
+  caps:
+    categorymappings:
+      - {id: 34, cat: TV/Anime, desc: "Animation"}
+      - {id: 22, cat: PC/0day, desc: "Appz"}
+      - {id: 25, cat: PC/Games, desc: "Games/Console"}
+      - {id: 4, cat: PC/Games, desc: "Games/PC"}
+      - {id: 27, cat: Other/Misc, desc: "Misc"}
+      - {id: 35, cat: Movies/HD, desc: "Movies/HD"}
+      - {id: 37, cat: Movies/Foreign, desc: "Movies/LAT"}
+      - {id: 42, cat: Movies, desc: "Movies/Pack"}
+      - {id: 38, cat: Movies, desc: "Movies/Retro"}
+      - {id: 36, cat: Movies/Foreign, desc: "Movies/RUS"}
+      - {id: 19, cat: Movies/SD, desc: "Movies/SD"}
+      - {id: 6, cat: Audio, desc: "Music"}
+      - {id: 26, cat: Audio/Video, desc: "Music Videos"}
+      - {id: 31, cat: Audio/Lossless, desc: "Music/FLAC"}
+      - {id: 39, cat: TV/HD, desc: "TV/HD"}
+      - {id: 43, cat: TV, desc: "TV/Pack"}
+      - {id: 7, cat: TV/SD, desc: "TV/SD"}
+      - {id: 40, cat: XXX, desc: "XXX/HD"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: font.logintext
+    test:
+      path: /browse.php
+      
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: table > tbody > tr:has(a[href^="details.php?id="])
+    fields:
+      title:
+        selector: a[href^="details.php?id="][title]
+        attribute: title
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="download.php/"]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      size:
+        selector: td:nth-child(6)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " +02:00"
+          - name: dateparse
+            args: "2006-01-0215:04:05 -07:00"
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: ([,\d]+)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      banner:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=([^\s]+)
+      downloadvolumefactor:
+        case:
+          "img[alt=\"Zelta Torrents\"]": "0"
+          "img[alt=\"Sudraba Torrents\"]": "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/insanetracker.yml b/src/Jackett/Definitions/insanetracker.yml
index 10576252f8246f8fdafe28a156884bea79ae0f80..947820bc25f7b49cbdfb8567fbf68940723275d9 100644
--- a/src/Jackett/Definitions/insanetracker.yml
+++ b/src/Jackett/Definitions/insanetracker.yml
@@ -1,140 +1,140 @@
----
-  site: insanetracker
-  name: Insane Tracker
-  language: hu-hu
-  type: private
-  encoding: UTF-8
-  links:
-    - https://newinsane.info/
-
-  caps:
-    categorymappings:
-      - {id: 8, cat: TV/SD, desc: "Sorozat/Hun"}
-      - {id: 40, cat: TV/HD, desc: "Sorozat/Hun/HD"}
-      - {id: 41, cat: Movies/SD, desc: "Film/Hun/SD"}
-      - {id: 15, cat: Movies/DVD, desc: "Film/Hun/DVD-R"}
-      - {id: 27, cat: Movies/HD, desc: "Film/Hun/HD"}
-      - {id: 44, cat: Movies/HD, desc: "Film/Hun/UHD"}
-      - {id: 2, cat: Books, desc: "eBook/Hun"}
-      - {id: 7, cat: TV/SD, desc: "Sorozat/Eng"}
-      - {id: 39, cat: TV/HD, desc: "Sorozat/Eng/HD"}
-      - {id: 42, cat: Movies/SD, desc: "Film/Eng/SD"}
-      - {id: 14, cat: Movies/DVD, desc: "Film/Eng/DVD-R"}
-      - {id: 25, cat: Movies/HD, desc: "Film/Eng/HD"}
-      - {id: 45, cat: Movies/HD, desc: "Film/Eng/UHD"}
-      - {id: 1, cat: Books, desc: "eBook/Eng"}
-      - {id: 38, cat: Audio/Audiobook, desc: "Hangoskönyv"}
-      - {id: 21, cat: XXX, desc: "XXX"}
-      - {id: 4, cat: PC/ISO, desc: "Program/ISO"}
-      - {id: 19, cat: Audio/Other, desc: "Zene/Hun"}
-      - {id: 37, cat: Audio/Lossless, desc: "Lossless/Hun"}
-      - {id: 9, cat: PC/Games, desc: "Játék/ISO"}
-      - {id: 43, cat: Console, desc: "Játék/Konzol"}
-      - {id: 29, cat: Other, desc: "Képek"}
-      - {id: 28, cat: XXX/Imageset, desc: "XXX Képek"}
-      - {id: 3, cat: PC/0day, desc: "Program/Egyéb"}
-      - {id: 18, cat: Audio/Other, desc: "Zene/Eng"}
-      - {id: 26, cat: Audio/Lossless, desc: "Lossless/Eng"}
-      - {id: 11, cat: PC/Games, desc: "Játék/Rip"}
-      - {id: 13, cat: PC/Phone-Other, desc: "Mobil"}
-
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q, imdbid]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      notsecure: "1"
-    error:
-      - selector: div.login_error_content
-    test:
-      path: /browse.php
-        
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
-      t: "all"
-    rows:
-      selector: table.torrentable > tbody > tr:has(td.maintd)
-    fields:
-      title:
-        selector: div.tortitle > a
-        attribute: title
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: div.tortitle > a
-        attribute: href
-      download:
-        selector: a[href^="download.php/"]
-        attribute: href
-      imdb|optional:
-        selector: a[title="IMDb link"]
-        attribute: href
-      banner|optional|1:
-        selector: img[alt="offer"]
-        attribute: src
-      banner|optional|2:
-        selector: a.cover
-        attribute: href
-      files:
-        selector: td:nth-child(6)
-        filters:
-          - name: replace
-            args: [".", ""]
-      size:
-        selector: td:nth-child(8)
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      grabs:
-        selector: td:nth-child(9) > div:first-child
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: regexp
-            args: "^([\\d]+)"
-      seeders:
-        selector: td:nth-child(9) > div:first-child
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: regexp
-            args: "\\|\\s*([\\d]+)\\s*\\|"
-      leechers:
-        selector: td:nth-child(9) > div:first-child
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: regexp
-            args: "([\\d]+)$"
-      date:
-        selector: td.date
-        filters:
-          - name: dateparse
-            args: "2006.01.02 15:04:05"
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
-        case:
-          img[src^="pic/4x.gif"]: "4"
-          img[src^="pic/3x.gif"]: "3"
-          img[src^="pic/2x.gif"]: "2"
-          "*": "1"
-      description:
-        selector: td.maintd
-        remove: div.tortitle, div.markcont, div.tablebuttons, div.tablebigbuttons
+---
+  site: insanetracker
+  name: Insane Tracker
+  language: hu-hu
+  type: private
+  encoding: UTF-8
+  links:
+    - https://newinsane.info/
+
+  caps:
+    categorymappings:
+      - {id: 8, cat: TV/SD, desc: "Sorozat/Hun"}
+      - {id: 40, cat: TV/HD, desc: "Sorozat/Hun/HD"}
+      - {id: 41, cat: Movies/SD, desc: "Film/Hun/SD"}
+      - {id: 15, cat: Movies/DVD, desc: "Film/Hun/DVD-R"}
+      - {id: 27, cat: Movies/HD, desc: "Film/Hun/HD"}
+      - {id: 44, cat: Movies/HD, desc: "Film/Hun/UHD"}
+      - {id: 2, cat: Books, desc: "eBook/Hun"}
+      - {id: 7, cat: TV/SD, desc: "Sorozat/Eng"}
+      - {id: 39, cat: TV/HD, desc: "Sorozat/Eng/HD"}
+      - {id: 42, cat: Movies/SD, desc: "Film/Eng/SD"}
+      - {id: 14, cat: Movies/DVD, desc: "Film/Eng/DVD-R"}
+      - {id: 25, cat: Movies/HD, desc: "Film/Eng/HD"}
+      - {id: 45, cat: Movies/HD, desc: "Film/Eng/UHD"}
+      - {id: 1, cat: Books, desc: "eBook/Eng"}
+      - {id: 38, cat: Audio/Audiobook, desc: "Hangoskönyv"}
+      - {id: 21, cat: XXX, desc: "XXX"}
+      - {id: 4, cat: PC/ISO, desc: "Program/ISO"}
+      - {id: 19, cat: Audio/Other, desc: "Zene/Hun"}
+      - {id: 37, cat: Audio/Lossless, desc: "Lossless/Hun"}
+      - {id: 9, cat: PC/Games, desc: "Játék/ISO"}
+      - {id: 43, cat: Console, desc: "Játék/Konzol"}
+      - {id: 29, cat: Other, desc: "Képek"}
+      - {id: 28, cat: XXX/Imageset, desc: "XXX Képek"}
+      - {id: 3, cat: PC/0day, desc: "Program/Egyéb"}
+      - {id: 18, cat: Audio/Other, desc: "Zene/Eng"}
+      - {id: 26, cat: Audio/Lossless, desc: "Lossless/Eng"}
+      - {id: 11, cat: PC/Games, desc: "Játék/Rip"}
+      - {id: 13, cat: PC/Phone-Other, desc: "Mobil"}
+
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q, imdbid]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      notsecure: "1"
+    error:
+      - selector: div.login_error_content
+    test:
+      path: /browse.php
+        
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
+      t: "all"
+    rows:
+      selector: table.torrentable > tbody > tr:has(td.maintd)
+    fields:
+      title:
+        selector: div.tortitle > a
+        attribute: title
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: div.tortitle > a
+        attribute: href
+      download:
+        selector: a[href^="download.php/"]
+        attribute: href
+      imdb|optional:
+        selector: a[title="IMDb link"]
+        attribute: href
+      banner|optional|1:
+        selector: img[alt="offer"]
+        attribute: src
+      banner|optional|2:
+        selector: a.cover
+        attribute: href
+      files:
+        selector: td:nth-child(6)
+        filters:
+          - name: replace
+            args: [".", ""]
+      size:
+        selector: td:nth-child(8)
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      grabs:
+        selector: td:nth-child(9) > div:first-child
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: regexp
+            args: "^([\\d]+)"
+      seeders:
+        selector: td:nth-child(9) > div:first-child
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: regexp
+            args: "\\|\\s*([\\d]+)\\s*\\|"
+      leechers:
+        selector: td:nth-child(9) > div:first-child
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: regexp
+            args: "([\\d]+)$"
+      date:
+        selector: td.date
+        filters:
+          - name: dateparse
+            args: "2006.01.02 15:04:05"
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
+        case:
+          img[src^="pic/4x.gif"]: "4"
+          img[src^="pic/3x.gif"]: "3"
+          img[src^="pic/2x.gif"]: "2"
+          "*": "1"
+      description:
+        selector: td.maintd
+        remove: div.tortitle, div.markcont, div.tablebuttons, div.tablebigbuttons
diff --git a/src/Jackett/Definitions/jpopsuki.yml b/src/Jackett/Definitions/jpopsuki.yml
index 543f5c862c55c72be1ef6a53d6626ee1ecfbc69b..1c273504ed7548aef70ad207bb7f94e8bc2ee21f 100644
--- a/src/Jackett/Definitions/jpopsuki.yml
+++ b/src/Jackett/Definitions/jpopsuki.yml
@@ -1,105 +1,105 @@
----
-  site: jpopsuki
-  name: JPopsuki
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://jpopsuki.eu/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Audio, desc: "Album"}
-      - {id: 2, cat: Audio, desc: "Single"}
-      - {id: 3, cat: Movies, desc: "PV"}
-      - {id: 4, cat: Movies/DVD, desc: "DVD"}
-      - {id: 5, cat: TV, desc: "TV-Music"}
-      - {id: 6, cat: TV, desc: "TV-Variety"}
-      - {id: 7, cat: TV, desc: "TV-Drama"}
-      - {id: 8, cat: Other, desc: "Fansubs"}
-      - {id: 9, cat: Other, desc: "Pictures"}
-      - {id: 10, cat: Other/Misc, desc: "Misc"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: 1
-      login: "Log in"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: torrents.php
-
-  ratio:
-    path: torrents.php
-    selector: li#stats_ratio > span
-
-  search:
-    path: torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: time
-      order_way: desc
-      action: basic
-      searchsubmit: 1
-    rows:
-      selector: table#torrent_table > tbody > tr[class^="torrent"]
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      description:
-        selector: div.tags
-      title:
-        selector: td:nth-child(4)
-        remove: span, div.tags, a[title="View Comments"]
-        filters:
-          - name: replace
-            args: [" ()", ""]
-          - name: replace
-            args: [" / Freeleech!", ""]
-      category:
-        selector: a[href*="filter_cat"]
-        attribute: href
-        filters:
-          - name: regexp
-            args: "%5B(\\d+?)%5D"
-      details:
-        selector: a[href^="torrents.php?id="]
-        attribute: href
-      banner:
-        selector: td:nth-child(3) img
-        attribute: src
-      files:
-        selector: td:nth-child(5)
-      date:
-        selector: td:nth-child(6)
-        attribute: title
-        filters:
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "Jan 02 2006, 15:04 -07:00"
-      size:
-        selector: td:nth-child(7)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      downloadvolumefactor:
-        case:
-          "strong:contains(\"Freeleech!\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: jpopsuki
+  name: JPopsuki
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://jpopsuki.eu/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Audio, desc: "Album"}
+      - {id: 2, cat: Audio, desc: "Single"}
+      - {id: 3, cat: Movies, desc: "PV"}
+      - {id: 4, cat: Movies/DVD, desc: "DVD"}
+      - {id: 5, cat: TV, desc: "TV-Music"}
+      - {id: 6, cat: TV, desc: "TV-Variety"}
+      - {id: 7, cat: TV, desc: "TV-Drama"}
+      - {id: 8, cat: Other, desc: "Fansubs"}
+      - {id: 9, cat: Other, desc: "Pictures"}
+      - {id: 10, cat: Other/Misc, desc: "Misc"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: 1
+      login: "Log in"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: torrents.php
+
+  ratio:
+    path: torrents.php
+    selector: li#stats_ratio > span
+
+  search:
+    path: torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: time
+      order_way: desc
+      action: basic
+      searchsubmit: 1
+    rows:
+      selector: table#torrent_table > tbody > tr[class^="torrent"]
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      description:
+        selector: div.tags
+      title:
+        selector: td:nth-child(4)
+        remove: span, div.tags, a[title="View Comments"]
+        filters:
+          - name: replace
+            args: [" ()", ""]
+          - name: replace
+            args: [" / Freeleech!", ""]
+      category:
+        selector: a[href*="filter_cat"]
+        attribute: href
+        filters:
+          - name: regexp
+            args: "%5B(\\d+?)%5D"
+      details:
+        selector: a[href^="torrents.php?id="]
+        attribute: href
+      banner:
+        selector: td:nth-child(3) img
+        attribute: src
+      files:
+        selector: td:nth-child(5)
+      date:
+        selector: td:nth-child(6)
+        attribute: title
+        filters:
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "Jan 02 2006, 15:04 -07:00"
+      size:
+        selector: td:nth-child(7)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      downloadvolumefactor:
+        case:
+          "strong:contains(\"Freeleech!\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/karagarga.yml b/src/Jackett/Definitions/karagarga.yml
index 03c8c49b87e27fc6fd2da3525079a6ab8145854d..c0807530996c45f67e184e35cc0bb824f9085b68 100644
--- a/src/Jackett/Definitions/karagarga.yml
+++ b/src/Jackett/Definitions/karagarga.yml
@@ -1,83 +1,83 @@
----
-  site: karagarga
-  name: Karagarga
-  description: "Rare and obscure movie tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://karagarga.in/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Movies"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    captcha:
-      type: image
-      image: img#captcha_img
-      input: imagestring
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "\"{{ .Query.Keywords }}\""
-      search_type: "title"
-    rows:
-      selector: table#browse > tbody > tr:has(a[href^="browse.php?genre="])
-    fields:
-      category:
-        text: 1
-      title:
-        selector: td:nth-child(2) span
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(12)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      files:
-        selector: td:nth-child(10)
-      size:
-        selector: td:nth-child(11)
-      seeders:
-        selector: td:nth-child(13)
-      leechers:
-        selector: td:nth-child(14)
-      date:
-        selector: td:nth-child(9)
-        filters:
-          - name: replace
-            args: ["'", ""]
-          - name: dateparse
-            args: "Jan 02 06"
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: karagarga
+  name: Karagarga
+  description: "Rare and obscure movie tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://karagarga.in/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Movies"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    captcha:
+      type: image
+      image: img#captcha_img
+      input: imagestring
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "\"{{ .Query.Keywords }}\""
+      search_type: "title"
+    rows:
+      selector: table#browse > tbody > tr:has(a[href^="browse.php?genre="])
+    fields:
+      category:
+        text: 1
+      title:
+        selector: td:nth-child(2) span
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(12)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      files:
+        selector: td:nth-child(10)
+      size:
+        selector: td:nth-child(11)
+      seeders:
+        selector: td:nth-child(13)
+      leechers:
+        selector: td:nth-child(14)
+      date:
+        selector: td:nth-child(9)
+        filters:
+          - name: replace
+            args: ["'", ""]
+          - name: dateparse
+            args: "Jan 02 06"
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/leparadisdunet.yml b/src/Jackett/Definitions/leparadisdunet.yml
index ef5ffe0c363843599b88f133142ad49679a304eb..aa9f96007f7911740f1e6640fa0136bd1922cb74 100644
--- a/src/Jackett/Definitions/leparadisdunet.yml
+++ b/src/Jackett/Definitions/leparadisdunet.yml
@@ -1,163 +1,163 @@
----
-  site: leparadisdunet
-  name: Le Paradis Du Net
-  language: fr-fr
-  type: semi-private
-  encoding: UTF-8
-  links:
-    - https://le-paradis-du-net.com/
-
-  caps:
-    categorymappings:
-      - {id: 10, cat: Movies/3D, desc: "3D"}
-      - {id: 9, cat: XXX, desc: "Adultes"}
-      - {id: 1, cat: PC, desc: "APPLICATION"}
-      - {id: 33, cat: PC/Phone-Other, desc: "  Iphone/Ipod/Android"}
-      - {id: 3, cat: PC/0day, desc: "  Linux"}
-      - {id: 32, cat: PC/Mac, desc: "  Mac"}
-      - {id: 4, cat: PC/0day, desc: "  Windows"}
-      - {id: 70, cat: Movies/HD, desc: "BDRIP"}
-      - {id: 69, cat: Movies/BluRay, desc: "Blueray"}
-      - {id: 73, cat: Movies/HD, desc: "BRRIP"}
-      - {id: 22, cat: Movies/SD, desc: "CAM TS SCREENER"}
-      - {id: 39, cat: Movies/DVD, desc: "  R5"}
-      - {id: 13, cat: TV/Anime, desc: "DESSINS ANIMES"}
-      - {id: 48, cat: TV/Anime, desc: "  Animations"}
-      - {id: 47, cat: TV/Anime, desc: "  Mangas"}
-      - {id: 14, cat: TV/Documentary, desc: "DOCUMENTAIRE"}
-      - {id: 52, cat: TV/Documentary, desc: "  EmissionsTV"}
-      - {id: 49, cat: TV/Documentary, desc: "  Tv docs"}
-      - {id: 15, cat: Movies/DVD, desc: "DVDR"}
-      - {id: 16, cat: Movies/SD, desc: "DVDRIP"}
-      - {id: 35, cat: Movies, desc: "  Action"}
-      - {id: 64, cat: Movies, desc: "  Autres"}
-      - {id: 36, cat: Movies, desc: "  Aventure"}
-      - {id: 55, cat: Movies, desc: "  Comédie"}
-      - {id: 37, cat: Movies, desc: "  Drame"}
-      - {id: 38, cat: Movies, desc: "  Fantastique"}
-      - {id: 63, cat: Movies, desc: "  Guerre"}
-      - {id: 72, cat: Movies, desc: "  Historique/Biopic"}
-      - {id: 67, cat: Movies, desc: "  Horreur"}
-      - {id: 65, cat: Movies, desc: "  Thriller"}
-      - {id: 71, cat: Movies, desc: "  Werstern"}
-      - {id: 17, cat: Movies/SD, desc: "DVDRIP VOSTFR"}
-      - {id: 19, cat: Books, desc: "EBOOK"}
-      - {id: 54, cat: Books, desc: "  Journaux"}
-      - {id: 81, cat: Books, desc: "  Magazines"}
-      - {id: 82, cat: Books, desc: "  People"}
-      - {id: 40, cat: Movies/HD, desc: "HD"}
-      - {id: 41, cat: Movies/HD, desc: "  1080p"}
-      - {id: 42, cat: Movies/HD, desc: "  720P"}
-      - {id: 77, cat: Movies/HD, desc: "  HD LIGHT"}
-      - {id: 86, cat: TV/SD, desc: "  HDTV"}
-      - {id: 20, cat: Console/Other, desc: "JEUX"}
-      - {id: 56, cat: Console/NDS, desc: "  DS"}
-      - {id: 57, cat: PC/Games, desc: "  Pc"}
-      - {id: 26, cat: Console/PS3, desc: "  PS3"}
-      - {id: 58, cat: Console/PSP, desc: "  PSP"}
-      - {id: 25, cat: Console/Wii, desc: "  Wii"}
-      - {id: 24, cat: Console/Xbox360, desc: "  Xbox360"}
-      - {id: 21, cat: Audio, desc: "MUSIQUES"}
-      - {id: 29, cat: Audio/Video, desc: "  Clip"}
-      - {id: 68, cat: Audio/Video, desc: "  Concert"}
-      - {id: 31, cat: Audio/Lossless, desc: "  FLAC"}
-      - {id: 30, cat: Audio/MP3, desc: "  mp3"}
-      - {id: 28, cat: Audio/Lossless, desc: "  wave"}
-      - {id: 27, cat: Audio/Other, desc: "  wma"}
-      - {id: 5, cat: TV, desc: "SERIES"}
-      - {id: 79, cat: TV/HD, desc: "  SERIES HD 1080P"}
-      - {id: 80, cat: TV/HD, desc: "  SERIES HD 720p"}
-      - {id: 75, cat: TV, desc: "  TV pack"}
-      - {id: 8, cat: TV, desc: "  vf"}
-      - {id: 6, cat: TV, desc: "  vo"}
-      - {id: 7, cat: TV, desc: "  vost"}
-      - {id: 12, cat: TV/Sport, desc: "SPORTS"}
-      - {id: 61, cat: TV/Sport, desc: "  Autres "}
-      - {id: 45, cat: TV/Sport, desc: "  Catch VF"}
-      - {id: 59, cat: TV/Sport, desc: "  Catch VO"}
-      - {id: 44, cat: TV/Sport, desc: "  Football"}
-      - {id: 60, cat: TV/Sport, desc: "  UFC/MMA"}
-      - {id: 76, cat: TV, desc: "Télévision"}
-      - {id: 78, cat: Movies/WEBDL, desc: "WEBRIP"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: table:has(td:contains("Une erreur est survenue"))
-    test:
-      path: browse.php
-
-  download:
-    before:
-      path: "/takethanks.php"
-      method: "post"
-      inputs:
-        torrentid: "{{ re_replace .DownloadUri.AbsolutePath \"^.*download-torrent-(\\d+)/.*$\" \"$1\" }}"
-
-  search:
-    path: browse.php
-    inputs:
-      do: "chercher"
-      keywords: "{{ .Query.Keywords }}"
-      search_type: "t_name"
-      category: "0" # multi cat search not supported
-      include_dead_torrents: "yes"
-    rows:
-      selector: table#sortabletable > tbody > tr:has(a[href*="/torrent-details-"])
-    fields:
-      download:
-        selector: a[href*="/torrent-details-"]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["torrent-details-", "download-torrent-"]
-      title:
-        selector: a[href*="/torrent-details-"]
-      details:
-        selector: a[href*="/torrent-details-"]
-        attribute: href
-      category:
-        selector: a[href*="/torrent-category-"]
-        attribute: href
-        filters:
-          - name: regexp
-            args: torrent-category-(\d+)
-      size:
-        selector: td:nth-child(4)
-      date:
-        selector: td:nth-child(2) > div > font[color="white"]
-        filters:
-          - name: replace
-            args: ["le ", ""]
-          - name: replace
-            args: [" à ", " "]
-          - name: trim
-            args: "\t"
-          - name: trim
-            args: "\n"
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02-01-2006 15:04 -07:00"
-      grabs:
-        selector: td:nth-child(5)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      downloadvolumefactor:
-        case:
-          img[alt^="Free Torrent "]: "0"
-          img[alt^="Silver Torrent "]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: leparadisdunet
+  name: Le Paradis Du Net
+  language: fr-fr
+  type: semi-private
+  encoding: UTF-8
+  links:
+    - https://le-paradis-du-net.com/
+
+  caps:
+    categorymappings:
+      - {id: 10, cat: Movies/3D, desc: "3D"}
+      - {id: 9, cat: XXX, desc: "Adultes"}
+      - {id: 1, cat: PC, desc: "APPLICATION"}
+      - {id: 33, cat: PC/Phone-Other, desc: "  Iphone/Ipod/Android"}
+      - {id: 3, cat: PC/0day, desc: "  Linux"}
+      - {id: 32, cat: PC/Mac, desc: "  Mac"}
+      - {id: 4, cat: PC/0day, desc: "  Windows"}
+      - {id: 70, cat: Movies/HD, desc: "BDRIP"}
+      - {id: 69, cat: Movies/BluRay, desc: "Blueray"}
+      - {id: 73, cat: Movies/HD, desc: "BRRIP"}
+      - {id: 22, cat: Movies/SD, desc: "CAM TS SCREENER"}
+      - {id: 39, cat: Movies/DVD, desc: "  R5"}
+      - {id: 13, cat: TV/Anime, desc: "DESSINS ANIMES"}
+      - {id: 48, cat: TV/Anime, desc: "  Animations"}
+      - {id: 47, cat: TV/Anime, desc: "  Mangas"}
+      - {id: 14, cat: TV/Documentary, desc: "DOCUMENTAIRE"}
+      - {id: 52, cat: TV/Documentary, desc: "  EmissionsTV"}
+      - {id: 49, cat: TV/Documentary, desc: "  Tv docs"}
+      - {id: 15, cat: Movies/DVD, desc: "DVDR"}
+      - {id: 16, cat: Movies/SD, desc: "DVDRIP"}
+      - {id: 35, cat: Movies, desc: "  Action"}
+      - {id: 64, cat: Movies, desc: "  Autres"}
+      - {id: 36, cat: Movies, desc: "  Aventure"}
+      - {id: 55, cat: Movies, desc: "  Comédie"}
+      - {id: 37, cat: Movies, desc: "  Drame"}
+      - {id: 38, cat: Movies, desc: "  Fantastique"}
+      - {id: 63, cat: Movies, desc: "  Guerre"}
+      - {id: 72, cat: Movies, desc: "  Historique/Biopic"}
+      - {id: 67, cat: Movies, desc: "  Horreur"}
+      - {id: 65, cat: Movies, desc: "  Thriller"}
+      - {id: 71, cat: Movies, desc: "  Werstern"}
+      - {id: 17, cat: Movies/SD, desc: "DVDRIP VOSTFR"}
+      - {id: 19, cat: Books, desc: "EBOOK"}
+      - {id: 54, cat: Books, desc: "  Journaux"}
+      - {id: 81, cat: Books, desc: "  Magazines"}
+      - {id: 82, cat: Books, desc: "  People"}
+      - {id: 40, cat: Movies/HD, desc: "HD"}
+      - {id: 41, cat: Movies/HD, desc: "  1080p"}
+      - {id: 42, cat: Movies/HD, desc: "  720P"}
+      - {id: 77, cat: Movies/HD, desc: "  HD LIGHT"}
+      - {id: 86, cat: TV/SD, desc: "  HDTV"}
+      - {id: 20, cat: Console/Other, desc: "JEUX"}
+      - {id: 56, cat: Console/NDS, desc: "  DS"}
+      - {id: 57, cat: PC/Games, desc: "  Pc"}
+      - {id: 26, cat: Console/PS3, desc: "  PS3"}
+      - {id: 58, cat: Console/PSP, desc: "  PSP"}
+      - {id: 25, cat: Console/Wii, desc: "  Wii"}
+      - {id: 24, cat: Console/Xbox360, desc: "  Xbox360"}
+      - {id: 21, cat: Audio, desc: "MUSIQUES"}
+      - {id: 29, cat: Audio/Video, desc: "  Clip"}
+      - {id: 68, cat: Audio/Video, desc: "  Concert"}
+      - {id: 31, cat: Audio/Lossless, desc: "  FLAC"}
+      - {id: 30, cat: Audio/MP3, desc: "  mp3"}
+      - {id: 28, cat: Audio/Lossless, desc: "  wave"}
+      - {id: 27, cat: Audio/Other, desc: "  wma"}
+      - {id: 5, cat: TV, desc: "SERIES"}
+      - {id: 79, cat: TV/HD, desc: "  SERIES HD 1080P"}
+      - {id: 80, cat: TV/HD, desc: "  SERIES HD 720p"}
+      - {id: 75, cat: TV, desc: "  TV pack"}
+      - {id: 8, cat: TV, desc: "  vf"}
+      - {id: 6, cat: TV, desc: "  vo"}
+      - {id: 7, cat: TV, desc: "  vost"}
+      - {id: 12, cat: TV/Sport, desc: "SPORTS"}
+      - {id: 61, cat: TV/Sport, desc: "  Autres "}
+      - {id: 45, cat: TV/Sport, desc: "  Catch VF"}
+      - {id: 59, cat: TV/Sport, desc: "  Catch VO"}
+      - {id: 44, cat: TV/Sport, desc: "  Football"}
+      - {id: 60, cat: TV/Sport, desc: "  UFC/MMA"}
+      - {id: 76, cat: TV, desc: "Télévision"}
+      - {id: 78, cat: Movies/WEBDL, desc: "WEBRIP"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: table:has(td:contains("Une erreur est survenue"))
+    test:
+      path: browse.php
+
+  download:
+    before:
+      path: "/takethanks.php"
+      method: "post"
+      inputs:
+        torrentid: "{{ re_replace .DownloadUri.AbsolutePath \"^.*download-torrent-(\\d+)/.*$\" \"$1\" }}"
+
+  search:
+    path: browse.php
+    inputs:
+      do: "chercher"
+      keywords: "{{ .Query.Keywords }}"
+      search_type: "t_name"
+      category: "0" # multi cat search not supported
+      include_dead_torrents: "yes"
+    rows:
+      selector: table#sortabletable > tbody > tr:has(a[href*="/torrent-details-"])
+    fields:
+      download:
+        selector: a[href*="/torrent-details-"]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["torrent-details-", "download-torrent-"]
+      title:
+        selector: a[href*="/torrent-details-"]
+      details:
+        selector: a[href*="/torrent-details-"]
+        attribute: href
+      category:
+        selector: a[href*="/torrent-category-"]
+        attribute: href
+        filters:
+          - name: regexp
+            args: torrent-category-(\d+)
+      size:
+        selector: td:nth-child(4)
+      date:
+        selector: td:nth-child(2) > div > font[color="white"]
+        filters:
+          - name: replace
+            args: ["le ", ""]
+          - name: replace
+            args: [" à ", " "]
+          - name: trim
+            args: "\t"
+          - name: trim
+            args: "\n"
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02-01-2006 15:04 -07:00"
+      grabs:
+        selector: td:nth-child(5)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      downloadvolumefactor:
+        case:
+          img[alt^="Free Torrent "]: "0"
+          img[alt^="Silver Torrent "]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/losslessclub.yml b/src/Jackett/Definitions/losslessclub.yml
index 87721c8e864bb6cfb8b2bc7767fffc9b4dd6b7e9..a470950500340f66118b90bde07f50383b81a5e1 100644
--- a/src/Jackett/Definitions/losslessclub.yml
+++ b/src/Jackett/Definitions/losslessclub.yml
@@ -1,82 +1,82 @@
----
-  site: losslessclub
-  name: LosslessClub
-  language: ru-ru
-  type: private
-  encoding: windows-1251
-  links:
-    - https://losslessclub.com/
-
-  caps:
-    categories:
-      1: Audio/Lossless
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded > div.error
-    test:
-      path: /browse.php
-      selector: span.bar_user_welcome
-        
-  search:
-    path: /browse.php
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      t: "all"
-    rows:
-      selector: div#releases-table > table > tbody > tr:has(a.browselink)
-    fields:
-      title:
-        selector: a.browselink
-      category:
-        text: "1"
-      details:
-        selector: a.browselink
-        attribute: href
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      banner|optional:
-        selector: img.thumbnail
-        attribute: src
-      size:
-        selector: td:nth-child(5)
-      grabs|optional:
-        selector: td:nth-child(6) br + span
-      seeders:
-        selector: td:nth-child(6)
-        remove: br + span
-        filters:
-          - name: regexp
-            args: "([\\.\\d]+)\\s+\\|"
-      leechers:
-        selector: td:nth-child(6)
-        remove: br + span
-        filters:
-          - name: regexp
-            args: "\\|\\s*([\\.\\d]+)"
-      date:
-        selector: td:nth-child(7)
-        remove: a, i
-        filters:
-          - name: replace
-            args: ["by", ""]
-          - name: dateparse
-            args: "2/01/06"
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: div.tag_list_browse
+---
+  site: losslessclub
+  name: LosslessClub
+  language: ru-ru
+  type: private
+  encoding: windows-1251
+  links:
+    - https://losslessclub.com/
+
+  caps:
+    categories:
+      1: Audio/Lossless
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded > div.error
+    test:
+      path: /browse.php
+      selector: span.bar_user_welcome
+        
+  search:
+    path: /browse.php
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      t: "all"
+    rows:
+      selector: div#releases-table > table > tbody > tr:has(a.browselink)
+    fields:
+      title:
+        selector: a.browselink
+      category:
+        text: "1"
+      details:
+        selector: a.browselink
+        attribute: href
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      banner|optional:
+        selector: img.thumbnail
+        attribute: src
+      size:
+        selector: td:nth-child(5)
+      grabs|optional:
+        selector: td:nth-child(6) br + span
+      seeders:
+        selector: td:nth-child(6)
+        remove: br + span
+        filters:
+          - name: regexp
+            args: "([\\.\\d]+)\\s+\\|"
+      leechers:
+        selector: td:nth-child(6)
+        remove: br + span
+        filters:
+          - name: regexp
+            args: "\\|\\s*([\\.\\d]+)"
+      date:
+        selector: td:nth-child(7)
+        remove: a, i
+        filters:
+          - name: replace
+            args: ["by", ""]
+          - name: dateparse
+            args: "2/01/06"
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: div.tag_list_browse
diff --git a/src/Jackett/Definitions/mteamtp.yml b/src/Jackett/Definitions/mteamtp.yml
index 4d87d4ab99e60dc174026217873ad0d25a1f5ac2..a34b63c005987d04e4d2af34c887a0c98455d9d9 100644
--- a/src/Jackett/Definitions/mteamtp.yml
+++ b/src/Jackett/Definitions/mteamtp.yml
@@ -1,132 +1,132 @@
----
-  site: mteamtp
-  name: M-Team - TP
-  description: "A chinese tracker"
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://tp.m-team.cc
-
-  caps:
-    categorymappings:
-      - {id: 401, cat: Movies/SD, desc: "Movie(電影)/SD"}
-      - {id: 419, cat: Movies/HD, desc: "Movie(電影)/HD"}
-      - {id: 420, cat: Movies/DVD, desc: "Movie(電影)/DVDiSo"}
-      - {id: 421, cat: Movies/BluRay, desc: "Movie(電影)/Blu-Ray"}
-      - {id: 439, cat: Movies/Other, desc: "Movie(電影)/Remux"}
-      - {id: 403, cat: TV/SD, desc: "TV Series(影劇/綜藝)/SD"}
-      - {id: 402, cat: TV/HD, desc: "TV Series(影劇/綜藝)/HD"}
-      - {id: 435, cat: TV/SD, desc: "TV Series(影劇/綜藝)/DVDiSo"}
-      - {id: 438, cat: TV/HD, desc: "TV Series(影劇/綜藝)/BD"}
-      - {id: 404, cat: TV/Documentary, desc: "紀錄教育"}
-      - {id: 405, cat: TV/Anime, desc: "Anime(動畫)"}
-      - {id: 406, cat: Audio/Video, desc: "MV(演唱)"}
-      - {id: 408, cat: Audio/Other, desc: "Music(AAC/ALAC)"}
-      - {id: 434, cat: Audio, desc: "Music(無損)"}
-      - {id: 407, cat: TV/Sport, desc: "Sports(運動)"}
-      - {id: 422, cat: PC/0day, desc: "Software(軟體)"}
-      - {id: 423, cat: PC/Games, desc: "PCGame(PC遊戲)"}
-      - {id: 427, cat: Books, desc: "eBook(電子書)"}
-      - {id: 409, cat: Other, desc: "Misc(其他)"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-
-  ratio:
-    path: /torrents.php
-    selector: table#info_block
-    filters:
-      - name: regexp
-        args: "Ratio:\\s(.*?)\\s\\s"
-
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "0"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: "0"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[title][href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      banner:
-        selector: img[alt="torrent thumbnail"]
-        attribute: src
-        filters:
-          - name: replace
-            args: ["pic/nopic.jpg", ""]
-      size:
-        selector: td.rowfollow:nth-child(5)
-      grabs:
-        selector: td.rowfollow:nth-child(8)
-      seeders:
-        selector: td.rowfollow:nth-child(6)
-      leechers:
-        selector: td.rowfollow:nth-child(7)
-      date:
-        selector: td.rowfollow:nth-child(4):not(:has(span))
-        optional: true
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-0215:04:05 -07:00"
-      date:
-        selector: td.rowfollow:nth-child(4) > span[title]
-        optional: true
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
+---
+  site: mteamtp
+  name: M-Team - TP
+  description: "A chinese tracker"
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://tp.m-team.cc
+
+  caps:
+    categorymappings:
+      - {id: 401, cat: Movies/SD, desc: "Movie(電影)/SD"}
+      - {id: 419, cat: Movies/HD, desc: "Movie(電影)/HD"}
+      - {id: 420, cat: Movies/DVD, desc: "Movie(電影)/DVDiSo"}
+      - {id: 421, cat: Movies/BluRay, desc: "Movie(電影)/Blu-Ray"}
+      - {id: 439, cat: Movies/Other, desc: "Movie(電影)/Remux"}
+      - {id: 403, cat: TV/SD, desc: "TV Series(影劇/綜藝)/SD"}
+      - {id: 402, cat: TV/HD, desc: "TV Series(影劇/綜藝)/HD"}
+      - {id: 435, cat: TV/SD, desc: "TV Series(影劇/綜藝)/DVDiSo"}
+      - {id: 438, cat: TV/HD, desc: "TV Series(影劇/綜藝)/BD"}
+      - {id: 404, cat: TV/Documentary, desc: "紀錄教育"}
+      - {id: 405, cat: TV/Anime, desc: "Anime(動畫)"}
+      - {id: 406, cat: Audio/Video, desc: "MV(演唱)"}
+      - {id: 408, cat: Audio/Other, desc: "Music(AAC/ALAC)"}
+      - {id: 434, cat: Audio, desc: "Music(無損)"}
+      - {id: 407, cat: TV/Sport, desc: "Sports(運動)"}
+      - {id: 422, cat: PC/0day, desc: "Software(軟體)"}
+      - {id: 423, cat: PC/Games, desc: "PCGame(PC遊戲)"}
+      - {id: 427, cat: Books, desc: "eBook(電子書)"}
+      - {id: 409, cat: Other, desc: "Misc(其他)"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+
+  ratio:
+    path: /torrents.php
+    selector: table#info_block
+    filters:
+      - name: regexp
+        args: "Ratio:\\s(.*?)\\s\\s"
+
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "0"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: "0"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[title][href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      banner:
+        selector: img[alt="torrent thumbnail"]
+        attribute: src
+        filters:
+          - name: replace
+            args: ["pic/nopic.jpg", ""]
+      size:
+        selector: td.rowfollow:nth-child(5)
+      grabs:
+        selector: td.rowfollow:nth-child(8)
+      seeders:
+        selector: td.rowfollow:nth-child(6)
+      leechers:
+        selector: td.rowfollow:nth-child(7)
+      date:
+        selector: td.rowfollow:nth-child(4):not(:has(span))
+        optional: true
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-0215:04:05 -07:00"
+      date:
+        selector: td.rowfollow:nth-child(4) > span[title]
+        optional: true
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
         remove: a, img
\ No newline at end of file
diff --git a/src/Jackett/Definitions/myspleen.yml b/src/Jackett/Definitions/myspleen.yml
index dd84203633c74f86429c784fe6b9df8089950800..60fa4a90b210643924b00fcc9237c88b9b0ea32b 100644
--- a/src/Jackett/Definitions/myspleen.yml
+++ b/src/Jackett/Definitions/myspleen.yml
@@ -1,99 +1,99 @@
----
-  site: myspleen
-  name: MySpleen
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://www.myspleen.org
-
-  caps:
-    categorymappings:
-      - {id: 31, cat: TV, desc: "Adult Swim"}
-      - {id: 30, cat: TV, desc: "Animation"}
-      - {id: 25, cat: TV, desc: "Cartoon Network"}
-      - {id: 3, cat: TV, desc: "Comedy"}
-      - {id: 26, cat: TV, desc: "Comedy Central"}
-      - {id: 24, cat: TV, desc: "MST3K"}
-      - {id: 28, cat: TV, desc: "MTV"}
-      - {id: 29, cat: TV, desc: "Nick"}
-      - {id: 20, cat: Other, desc: "Other"}
-      - {id: 32, cat: TV, desc: "Star Wars"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      returnto: "/"
-    error:
-      - selector: div#content:has(h2:contains("Login Failed"))
-    test:
-      path: /browse.php
-      selector: span.key:contains("Ratio") + span.value
-
-  ratio:
-    path: /browse.php
-    selector: span.key:contains("Ratio") + span.value
-
-  search:
-    path: /browse.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      title: "0"
-    rows:
-      selector: table#main-torrents > tbody > tr
-    fields:
-      title:
-        selector: td.tor-name > a
-        attribute: title
-      category:
-        selector: td[class^="cat-"] > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: td.tor-name > a
-        attribute: href      
-      download:
-        selector: td.tor-down > a
-        attribute: href
-      files:
-        selector: td:nth-child(5)
-      size:
-        selector: td:nth-child(8)
-      grabs:
-        selector: td:nth-child(9)
-        filters:
-        - name: regexp
-          args: "(\\d+)"
-      seeders:
-        selector: td:nth-child(10)
-        filters:
-        - name: regexp
-          args: "^(\\d+)"
-      leechers:
-        selector: td:nth-child(11)
-        filters:
-        - name: regexp
-          args: "^(\\d+)"
-      date:
-        selector: td:nth-child(7)
-      downloadvolumefactor:
-        case:
-          span.star: "0"
-          span.fltime: "0"
-          ":root li[id=\"alert-fl\"][class=\"alert\"]:contains(\"Freeleech ends in \")": 0
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: myspleen
+  name: MySpleen
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://www.myspleen.org
+
+  caps:
+    categorymappings:
+      - {id: 31, cat: TV, desc: "Adult Swim"}
+      - {id: 30, cat: TV, desc: "Animation"}
+      - {id: 25, cat: TV, desc: "Cartoon Network"}
+      - {id: 3, cat: TV, desc: "Comedy"}
+      - {id: 26, cat: TV, desc: "Comedy Central"}
+      - {id: 24, cat: TV, desc: "MST3K"}
+      - {id: 28, cat: TV, desc: "MTV"}
+      - {id: 29, cat: TV, desc: "Nick"}
+      - {id: 20, cat: Other, desc: "Other"}
+      - {id: 32, cat: TV, desc: "Star Wars"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      returnto: "/"
+    error:
+      - selector: div#content:has(h2:contains("Login Failed"))
+    test:
+      path: /browse.php
+      selector: span.key:contains("Ratio") + span.value
+
+  ratio:
+    path: /browse.php
+    selector: span.key:contains("Ratio") + span.value
+
+  search:
+    path: /browse.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      title: "0"
+    rows:
+      selector: table#main-torrents > tbody > tr
+    fields:
+      title:
+        selector: td.tor-name > a
+        attribute: title
+      category:
+        selector: td[class^="cat-"] > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: td.tor-name > a
+        attribute: href      
+      download:
+        selector: td.tor-down > a
+        attribute: href
+      files:
+        selector: td:nth-child(5)
+      size:
+        selector: td:nth-child(8)
+      grabs:
+        selector: td:nth-child(9)
+        filters:
+        - name: regexp
+          args: "(\\d+)"
+      seeders:
+        selector: td:nth-child(10)
+        filters:
+        - name: regexp
+          args: "^(\\d+)"
+      leechers:
+        selector: td:nth-child(11)
+        filters:
+        - name: regexp
+          args: "^(\\d+)"
+      date:
+        selector: td:nth-child(7)
+      downloadvolumefactor:
+        case:
+          span.star: "0"
+          span.fltime: "0"
+          ":root li[id=\"alert-fl\"][class=\"alert\"]:contains(\"Freeleech ends in \")": 0
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/nachtwerk.yml b/src/Jackett/Definitions/nachtwerk.yml
index 5b090ee77522b86e50d729225690042a28b04c73..7552d7c38cffb2734326d62bf966bd9ec2534fff 100644
--- a/src/Jackett/Definitions/nachtwerk.yml
+++ b/src/Jackett/Definitions/nachtwerk.yml
@@ -1,152 +1,152 @@
----
-  site: nachtwerk
-  name: Nachtwerk
-  language: de-de
-  type: private
-  encoding: ISO-8859-15
-  links:
-    - https://nwtracker.com/
-
-  caps:
-    categorymappings:
-      - {id: 75, cat: Movies/3D, desc: "Filme - 3D"}
-      - {id: 34, cat: Movies, desc: "Filme - Xvid / x264"}
-      - {id: 55, cat: Movies/BluRay, desc: "Filme - Blu-Ray"}
-      - {id: 20, cat: Movies/DVD, desc: "Filme - DVD-R"}
-      - {id: 71, cat: Movies/HD, desc: "Filme - HD 1080p"}
-      - {id: 70, cat: Movies/HD, desc: "Filme - HD 720p"}
-      - {id: 35, cat: Movies/Foreign, desc: "Filme - Inter"}
-      - {id: 104, cat: Movies/HD, desc: "Filme - UHD"}
-      - {id: 107, cat: Movies/Other, desc: "Filme - Remux"}
-      - {id: 7, cat: TV/SD, desc: "Serien - Xvid / x264"}
-      - {id: 72, cat: TV/HD, desc: "Serien - HD"}
-      - {id: 82, cat: TV/Foreign, desc: "Serien - Inter"}
-      - {id: 69, cat: TV, desc: "Serien - Pack's"}
-      - {id: 42, cat: TV, desc: "Serien - TV Show"}
-      - {id: 105, cat: TV/HD, desc: "Serien - UHD"}
-      - {id: 51, cat: XXX, desc: "XXX - Xvid / x264"}
-      - {id: 73, cat: XXX, desc: "XXX - HD"}
-      - {id: 84, cat: XXX, desc: "XXX - Pack's"}
-      - {id: 85, cat: XXX, desc: "XXX - Sonstiges"}
-      - {id: 102, cat: XXX, desc: "XXX - Hentai"}
-      - {id: 103, cat: XXX, desc: "XXX - UHD"}
-      - {id: 6, cat: Audio/MP3, desc: "Audio - MP3"}
-      - {id: 74, cat: Audio/Lossless, desc: "Audio - Flac"}
-      - {id: 86, cat: Audio/Video, desc: "Audio - Videos"}
-      - {id: 24, cat: Audio/Audiobook, desc: "Audio - Hörspiel/Hörbuch"}
-      - {id: 93, cat: PC/Mac, desc: "Appz - Mac"}
-      - {id: 67, cat: PC/0day, desc: "Appz - Windows"}
-      - {id: 31, cat: PC/Phone-Other, desc: "Appz - Handy"}
-      - {id: 81, cat: PC, desc: "Appz - Sonstiges"}
-      - {id: 25, cat: TV/Documentary, desc: "Dokus - Xvid / x264"}
-      - {id: 76, cat: TV/Documentary, desc: "Dokus - HD"}
-      - {id: 99, cat: TV/Documentary, desc: "Dokus - Pack's"}
-      - {id: 100, cat: TV/Documentary, desc: "Dokus - 3D"}
-      - {id: 106, cat: TV/Documentary, desc: "Dokus - UHD"}
-      - {id: 90, cat: Console/PS3, desc: "Games - PSX"}
-      - {id: 56, cat: Console/Wii, desc: "Games - WII"}
-      - {id: 43, cat: Console/Xbox, desc: "Games - XboX"}
-      - {id: 4, cat: PC/Games, desc: "Games - PC"}
-      - {id: 88, cat: Console/NDS, desc: "Games - xDS"}
-      - {id: 91, cat: PC/Mac, desc: "Games - Mac"}
-      - {id: 92, cat: Console, desc: "Games - Sonstiges"}
-      - {id: 23, cat: TV/Anime, desc: "Anime - Xvid / x264"}
-      - {id: 80, cat: TV/Anime, desc: "Anime - HD"}
-      - {id: 98, cat: TV/Anime, desc: "Anime - Serien"}
-      - {id: 94, cat: Books/Magazines, desc: "eBooks - Magazine/Zeitungen"}
-      - {id: 95, cat: Books/Comics, desc: "eBooks - Comics"}
-      - {id: 30, cat: Books, desc: "eBooks - Bücher"}
-      - {id: 96, cat: TV/Sport, desc: "Sport - Wrestling"}
-      - {id: 97, cat: TV/Sport, desc: "Sport - Fussball"}
-      - {id: 45, cat: TV/Sport, desc: "Sport - Sonstiges"}
-      - {id: 9, cat: Other, desc: "Diverses - Sonstiges"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /browse.php
-
-  download:
-    selector: a[href^="download.php?torrent="]
-      
-  search:
-    path: /browse.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      spstate: "0"
-      inclbookmarked: "0"
-      search_area: "0"
-      search_mode: "0"
-    rows:
-      selector: table.tableinborder[cellspacing="1"][cellpadding="0"] > tbody > tr
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-        filters:
-          - name: replace
-            args: ["[NW] ", ""]
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:  
-          - name: replace
-            args: ["details.php?id=", "thanks1.php?torrentid="]
-      banner:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "src=.*'\\);"
-      size:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      files:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
-      grabs:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
-      seeders:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
-      leechers:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
-      date:
-        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5)
-        filters:
-          - name: replace
-            args: ["\xA0", " "]
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02.01.2006 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img[src="pic/onlyuploadd.gif"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: nachtwerk
+  name: Nachtwerk
+  language: de-de
+  type: private
+  encoding: ISO-8859-15
+  links:
+    - https://nwtracker.com/
+
+  caps:
+    categorymappings:
+      - {id: 75, cat: Movies/3D, desc: "Filme - 3D"}
+      - {id: 34, cat: Movies, desc: "Filme - Xvid / x264"}
+      - {id: 55, cat: Movies/BluRay, desc: "Filme - Blu-Ray"}
+      - {id: 20, cat: Movies/DVD, desc: "Filme - DVD-R"}
+      - {id: 71, cat: Movies/HD, desc: "Filme - HD 1080p"}
+      - {id: 70, cat: Movies/HD, desc: "Filme - HD 720p"}
+      - {id: 35, cat: Movies/Foreign, desc: "Filme - Inter"}
+      - {id: 104, cat: Movies/HD, desc: "Filme - UHD"}
+      - {id: 107, cat: Movies/Other, desc: "Filme - Remux"}
+      - {id: 7, cat: TV/SD, desc: "Serien - Xvid / x264"}
+      - {id: 72, cat: TV/HD, desc: "Serien - HD"}
+      - {id: 82, cat: TV/Foreign, desc: "Serien - Inter"}
+      - {id: 69, cat: TV, desc: "Serien - Pack's"}
+      - {id: 42, cat: TV, desc: "Serien - TV Show"}
+      - {id: 105, cat: TV/HD, desc: "Serien - UHD"}
+      - {id: 51, cat: XXX, desc: "XXX - Xvid / x264"}
+      - {id: 73, cat: XXX, desc: "XXX - HD"}
+      - {id: 84, cat: XXX, desc: "XXX - Pack's"}
+      - {id: 85, cat: XXX, desc: "XXX - Sonstiges"}
+      - {id: 102, cat: XXX, desc: "XXX - Hentai"}
+      - {id: 103, cat: XXX, desc: "XXX - UHD"}
+      - {id: 6, cat: Audio/MP3, desc: "Audio - MP3"}
+      - {id: 74, cat: Audio/Lossless, desc: "Audio - Flac"}
+      - {id: 86, cat: Audio/Video, desc: "Audio - Videos"}
+      - {id: 24, cat: Audio/Audiobook, desc: "Audio - Hörspiel/Hörbuch"}
+      - {id: 93, cat: PC/Mac, desc: "Appz - Mac"}
+      - {id: 67, cat: PC/0day, desc: "Appz - Windows"}
+      - {id: 31, cat: PC/Phone-Other, desc: "Appz - Handy"}
+      - {id: 81, cat: PC, desc: "Appz - Sonstiges"}
+      - {id: 25, cat: TV/Documentary, desc: "Dokus - Xvid / x264"}
+      - {id: 76, cat: TV/Documentary, desc: "Dokus - HD"}
+      - {id: 99, cat: TV/Documentary, desc: "Dokus - Pack's"}
+      - {id: 100, cat: TV/Documentary, desc: "Dokus - 3D"}
+      - {id: 106, cat: TV/Documentary, desc: "Dokus - UHD"}
+      - {id: 90, cat: Console/PS3, desc: "Games - PSX"}
+      - {id: 56, cat: Console/Wii, desc: "Games - WII"}
+      - {id: 43, cat: Console/Xbox, desc: "Games - XboX"}
+      - {id: 4, cat: PC/Games, desc: "Games - PC"}
+      - {id: 88, cat: Console/NDS, desc: "Games - xDS"}
+      - {id: 91, cat: PC/Mac, desc: "Games - Mac"}
+      - {id: 92, cat: Console, desc: "Games - Sonstiges"}
+      - {id: 23, cat: TV/Anime, desc: "Anime - Xvid / x264"}
+      - {id: 80, cat: TV/Anime, desc: "Anime - HD"}
+      - {id: 98, cat: TV/Anime, desc: "Anime - Serien"}
+      - {id: 94, cat: Books/Magazines, desc: "eBooks - Magazine/Zeitungen"}
+      - {id: 95, cat: Books/Comics, desc: "eBooks - Comics"}
+      - {id: 30, cat: Books, desc: "eBooks - Bücher"}
+      - {id: 96, cat: TV/Sport, desc: "Sport - Wrestling"}
+      - {id: 97, cat: TV/Sport, desc: "Sport - Fussball"}
+      - {id: 45, cat: TV/Sport, desc: "Sport - Sonstiges"}
+      - {id: 9, cat: Other, desc: "Diverses - Sonstiges"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /browse.php
+
+  download:
+    selector: a[href^="download.php?torrent="]
+      
+  search:
+    path: /browse.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      spstate: "0"
+      inclbookmarked: "0"
+      search_area: "0"
+      search_mode: "0"
+    rows:
+      selector: table.tableinborder[cellspacing="1"][cellpadding="0"] > tbody > tr
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+        filters:
+          - name: replace
+            args: ["[NW] ", ""]
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:  
+          - name: replace
+            args: ["details.php?id=", "thanks1.php?torrentid="]
+      banner:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "src=.*'\\);"
+      size:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      files:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
+      grabs:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(3) > b:nth-child(1)
+      seeders:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
+      leechers:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
+      date:
+        selector: td:nth-child(2) > table > tbody > tr:nth-child(2) > td:nth-child(5)
+        filters:
+          - name: replace
+            args: ["\xA0", " "]
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02.01.2006 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img[src="pic/onlyuploadd.gif"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/nethd.yml b/src/Jackett/Definitions/nethd.yml
index ad4b715914a4abeea296ca2f3d6fb98074c72b37..ccfcba777ee6f4568e0db96e90d1e44fc91e8f95 100644
--- a/src/Jackett/Definitions/nethd.yml
+++ b/src/Jackett/Definitions/nethd.yml
@@ -1,99 +1,99 @@
----
-  site: nethd
-  name: NetHD
-  description: "A vietnamese tracker"
-  language: vi-vn
-  type: semi-private
-  encoding: UTF-8
-  links:
-    - http://nethd.org/
-
-  caps:
-    categorymappings:
-      - {id: 401, cat: Movies, desc: "Movies"}
-      - {id: 402, cat: Audio, desc: "Music"}
-      - {id: 403, cat: PC/Games, desc: "Game"}
-      - {id: 404, cat: PC, desc: "Software"}
-      - {id: 405, cat: Other, desc: "Image"}
-      - {id: 406, cat: Books, desc: "Book"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: /torrents.php
-
-  ratio:
-    path: /torrents.php
-    selector: div.user-info-extend > dl > dt:contains("Ratio:") + dd
-  search:
-    path: /torrents.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: 0
-      spstate: 0
-      inclbookmarked: 0
-      incldead: 1
-    rows:
-      selector: tr:has(td.name)
-    fields:
-      title:
-        selector: td.name > div > a.poster-preview[title]
-        attribute: title
-      category:
-        selector: td.category > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: td.name > div > a.poster-preview[title]
-        attribute: href
-      comments:
-        selector: a[href*="#comments"]
-        attribute: href
-      download:
-        selector: a.bookmark[onclick]
-        attribute: onclick
-        filters:
-          - name: replace
-            args: [",false)", ""]
-          - name: replace
-            args: ["return bookmark(", "download.php?id="]
-      size:
-        selector: td:nth-child(5)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      grabs:
-        selector: td:nth-child(8)
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: append
-            args: " +0700"
-          - name: dateparse
-            args: "2006-01-0215:04:05 -0700"
-      downloadvolumefactor:
-        case:
-          "span.label:contains(\"Free\")": "0"
-          "span.label:contains(\"50%\")": "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "span.label:contains(\"2X\")": "2"
+---
+  site: nethd
+  name: NetHD
+  description: "A vietnamese tracker"
+  language: vi-vn
+  type: semi-private
+  encoding: UTF-8
+  links:
+    - http://nethd.org/
+
+  caps:
+    categorymappings:
+      - {id: 401, cat: Movies, desc: "Movies"}
+      - {id: 402, cat: Audio, desc: "Music"}
+      - {id: 403, cat: PC/Games, desc: "Game"}
+      - {id: 404, cat: PC, desc: "Software"}
+      - {id: 405, cat: Other, desc: "Image"}
+      - {id: 406, cat: Books, desc: "Book"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: /torrents.php
+
+  ratio:
+    path: /torrents.php
+    selector: div.user-info-extend > dl > dt:contains("Ratio:") + dd
+  search:
+    path: /torrents.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: 0
+      spstate: 0
+      inclbookmarked: 0
+      incldead: 1
+    rows:
+      selector: tr:has(td.name)
+    fields:
+      title:
+        selector: td.name > div > a.poster-preview[title]
+        attribute: title
+      category:
+        selector: td.category > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: td.name > div > a.poster-preview[title]
+        attribute: href
+      comments:
+        selector: a[href*="#comments"]
+        attribute: href
+      download:
+        selector: a.bookmark[onclick]
+        attribute: onclick
+        filters:
+          - name: replace
+            args: [",false)", ""]
+          - name: replace
+            args: ["return bookmark(", "download.php?id="]
+      size:
+        selector: td:nth-child(5)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      grabs:
+        selector: td:nth-child(8)
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: append
+            args: " +0700"
+          - name: dateparse
+            args: "2006-01-0215:04:05 -0700"
+      downloadvolumefactor:
+        case:
+          "span.label:contains(\"Free\")": "0"
+          "span.label:contains(\"50%\")": "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "span.label:contains(\"2X\")": "2"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/newretro.yml b/src/Jackett/Definitions/newretro.yml
index a0c67110b6bd8dfe7882b1cb78e92235e75775f3..16e0889807861a764fb5dbd22b7c416519829161 100644
--- a/src/Jackett/Definitions/newretro.yml
+++ b/src/Jackett/Definitions/newretro.yml
@@ -1,121 +1,121 @@
----
-  site: newretro
-  name: The New Retro
-  description: "A German gerneral tracker"
-  language: de-de
-  type: private
-  encoding: windows-1252
-  links:
-    - http://new-retro.eu/
-
-  caps:
-    categorymappings:
-      - {id: 101, cat: TV/Anime, desc: "Filme - Animie"}
-      - {id: 102, cat: Movies/BluRay, desc: "Filme - Bluray"}
-      - {id: 131, cat: Movies/Other, desc: "Filme - Bollywood"}
-      - {id: 103, cat: Movies/DVD, desc: "Filme - DVD"}
-      - {id: 104, cat: Movies/DVD, desc: "Filme - DVD-R"}
-      - {id: 132, cat: Movies/DVD, desc: "Filme - HD2DVD"}
-      - {id: 130, cat: Movies, desc: "Filme - Klassiker"}
-      - {id: 105, cat: Movies, desc: "Filme - x264"}
-      - {id: 106, cat: Movies, desc: "Filme - XviD / DivX"}
-      - {id: 69, cat: XXX, desc: " XXX"}
-      - {id: 124, cat: Audio, desc: "Musik - Alben"}
-      - {id: 122, cat: Audio/Audiobook, desc: "Musik - Hörbuch"}
-      - {id: 123, cat: Audio, desc: "Musik - Mixe"}
-      - {id: 133, cat: Audio/MP3, desc: "Musik - MP3"}
-      - {id: 125, cat: Audio/Video, desc: "Musik - Video"}
-      - {id: 113, cat: PC, desc: "Programme - Linux"}
-      - {id: 114, cat: PC/Mac, desc: "Programme - Mac"}
-      - {id: 115, cat: PC, desc: "Programme - Windows"}
-      - {id: 117, cat: TV, desc: "Allgemein - Serien"}
-      - {id: 116, cat: TV/Documentary, desc: "Serien - Dokus"}
-      - {id: 118, cat: TV/Sport, desc: "Serien - Sport"}
-      - {id: 119, cat: Other, desc: "Bilder"}
-      - {id: 120, cat: Books, desc: "Ebook"}
-      - {id: 127, cat: Other, desc: "Für Unsere kleinsten"}
-      - {id: 121, cat: Other, desc: "Handy Stuff"}
-      - {id: 129, cat: Other, desc: "Sonstiges"}
-      - {id: 109, cat: Other, desc: "Spiele - Handy"}
-      - {id: 112, cat: Console, desc: "Spiele - Konsolen"}
-      - {id: 111, cat: PC/Games, desc: "Spiele - Mac / Linux"}
-      - {id: 110, cat: PC/Games, desc: "Spiele - PC"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      returnto: "/"
-    error:
-    - selector: table.tableinborder:contains("Anmeldung Gescheitert!") > tbody > tr > td.tablea
-    test:
-      path: /usercp.php
-
-  ratio:
-    path: /usercp.php
-    selector: div#lmtd table > tbody > tr:contains("Ratio:") > td:nth-child(2)
-    filters:
-      - name: replace
-        args: [".", ""]
-      - name: replace
-        args: [",", "."]
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      showsearch: "1"
-      orderby: "added"
-      sort: "desc"
-      incldead: "1"
-
-    rows:
-      selector: table.tableinborder[summary] > tbody > tr
-      filters:
-        - name: andmatch
-    fields:
-      download:
-        selector: a[href^="download.php?torrent="]
-        attribute: href
-      title:
-        selector: a[href^="details.php?id="]:has(b)
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      comments:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(4) > a
-        attribute: href
-      size:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
-      grabs:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(3) > b
-      files:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
-      seeders:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
-      leechers:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
-      date:
-        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(5)
-        filters:
-          - name: replace
-            args: ["\u00a0", " "]
-          - name: dateparse
-            args: "02.01.2006 15:04:05"
-      downloadvolumefactor:
-        case:
-          "font[color=\"red\"]:contains(\"Only Upload\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: newretro
+  name: The New Retro
+  description: "A German gerneral tracker"
+  language: de-de
+  type: private
+  encoding: windows-1252
+  links:
+    - http://new-retro.eu/
+
+  caps:
+    categorymappings:
+      - {id: 101, cat: TV/Anime, desc: "Filme - Animie"}
+      - {id: 102, cat: Movies/BluRay, desc: "Filme - Bluray"}
+      - {id: 131, cat: Movies/Other, desc: "Filme - Bollywood"}
+      - {id: 103, cat: Movies/DVD, desc: "Filme - DVD"}
+      - {id: 104, cat: Movies/DVD, desc: "Filme - DVD-R"}
+      - {id: 132, cat: Movies/DVD, desc: "Filme - HD2DVD"}
+      - {id: 130, cat: Movies, desc: "Filme - Klassiker"}
+      - {id: 105, cat: Movies, desc: "Filme - x264"}
+      - {id: 106, cat: Movies, desc: "Filme - XviD / DivX"}
+      - {id: 69, cat: XXX, desc: " XXX"}
+      - {id: 124, cat: Audio, desc: "Musik - Alben"}
+      - {id: 122, cat: Audio/Audiobook, desc: "Musik - Hörbuch"}
+      - {id: 123, cat: Audio, desc: "Musik - Mixe"}
+      - {id: 133, cat: Audio/MP3, desc: "Musik - MP3"}
+      - {id: 125, cat: Audio/Video, desc: "Musik - Video"}
+      - {id: 113, cat: PC, desc: "Programme - Linux"}
+      - {id: 114, cat: PC/Mac, desc: "Programme - Mac"}
+      - {id: 115, cat: PC, desc: "Programme - Windows"}
+      - {id: 117, cat: TV, desc: "Allgemein - Serien"}
+      - {id: 116, cat: TV/Documentary, desc: "Serien - Dokus"}
+      - {id: 118, cat: TV/Sport, desc: "Serien - Sport"}
+      - {id: 119, cat: Other, desc: "Bilder"}
+      - {id: 120, cat: Books, desc: "Ebook"}
+      - {id: 127, cat: Other, desc: "Für Unsere kleinsten"}
+      - {id: 121, cat: Other, desc: "Handy Stuff"}
+      - {id: 129, cat: Other, desc: "Sonstiges"}
+      - {id: 109, cat: Other, desc: "Spiele - Handy"}
+      - {id: 112, cat: Console, desc: "Spiele - Konsolen"}
+      - {id: 111, cat: PC/Games, desc: "Spiele - Mac / Linux"}
+      - {id: 110, cat: PC/Games, desc: "Spiele - PC"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      returnto: "/"
+    error:
+    - selector: table.tableinborder:contains("Anmeldung Gescheitert!") > tbody > tr > td.tablea
+    test:
+      path: /usercp.php
+
+  ratio:
+    path: /usercp.php
+    selector: div#lmtd table > tbody > tr:contains("Ratio:") > td:nth-child(2)
+    filters:
+      - name: replace
+        args: [".", ""]
+      - name: replace
+        args: [",", "."]
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      showsearch: "1"
+      orderby: "added"
+      sort: "desc"
+      incldead: "1"
+
+    rows:
+      selector: table.tableinborder[summary] > tbody > tr
+      filters:
+        - name: andmatch
+    fields:
+      download:
+        selector: a[href^="download.php?torrent="]
+        attribute: href
+      title:
+        selector: a[href^="details.php?id="]:has(b)
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      comments:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(4) > a
+        attribute: href
+      size:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(1)
+      grabs:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(3) > b
+      files:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(1) > b:nth-child(2)
+      seeders:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(1)
+      leechers:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(2) > b:nth-child(3)
+      date:
+        selector: td.tablea > table > tbody > tr:nth-child(2) > td:nth-child(5)
+        filters:
+          - name: replace
+            args: ["\u00a0", " "]
+          - name: dateparse
+            args: "02.01.2006 15:04:05"
+      downloadvolumefactor:
+        case:
+          "font[color=\"red\"]:contains(\"Only Upload\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/ourbits.yml b/src/Jackett/Definitions/ourbits.yml
index 8c70b9cbd61af2d20e8c215f1e8962ac3b0c4342..16b5345dd6bd5c4c7dc04da93a03a77a249c9d7f 100644
--- a/src/Jackett/Definitions/ourbits.yml
+++ b/src/Jackett/Definitions/ourbits.yml
@@ -1,109 +1,109 @@
----
-  site: ourbits
-  name: Ourbits
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://ourbits.club/
-
-  caps:
-    categorymappings:
-      - {id: 401, cat: Movies/BluRay, desc: "Movies Blu-ray"}
-      - {id: 402, cat: Movies/HD, desc: "Movies REMUX"}
-      - {id: 419, cat: Movies/HD, desc: "Movies 1080p"}
-      - {id: 404, cat: Movies/HD, desc: "Movies 720p"}
-      - {id: 405, cat: Movies/3D, desc: "Movies 3D"}
-      - {id: 406, cat: Movies/DVD, desc: "Movies DVD"}
-      - {id: 407, cat: Movies/WEBDL, desc: "Movies WEB-DL"}
-      - {id: 408, cat: Movies/SD, desc: "Movies HDTV"}
-      - {id: 409, cat: Movies/Other, desc: "Movies iPad"}
-      - {id: 410, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 411, cat: TV/Anime, desc: "Animations"}
-      - {id: 412, cat: TV, desc: "TV Series"}
-      - {id: 413, cat: TV, desc: "TV Shows"}
-      - {id: 414, cat: Audio/Video, desc: "Music Videos"}
-      - {id: 415, cat: TV/Sport, desc: "Sports"}
-      - {id: 416, cat: Audio, desc: "Music"}
-      - {id: 420, cat: Other, desc: "Other"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [imdbid]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("登录失败"))
-    test:
-      path: /torrents.php
-
-  search:
-    path: /torrents.php
-    method: get
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "1"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      title|optional:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      imdb|optional:
-        selector: div.imdb_100 > a
-        attribute: href
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      date:
-        selector: td:nth-child(4) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a, img
+---
+  site: ourbits
+  name: Ourbits
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://ourbits.club/
+
+  caps:
+    categorymappings:
+      - {id: 401, cat: Movies/BluRay, desc: "Movies Blu-ray"}
+      - {id: 402, cat: Movies/HD, desc: "Movies REMUX"}
+      - {id: 419, cat: Movies/HD, desc: "Movies 1080p"}
+      - {id: 404, cat: Movies/HD, desc: "Movies 720p"}
+      - {id: 405, cat: Movies/3D, desc: "Movies 3D"}
+      - {id: 406, cat: Movies/DVD, desc: "Movies DVD"}
+      - {id: 407, cat: Movies/WEBDL, desc: "Movies WEB-DL"}
+      - {id: 408, cat: Movies/SD, desc: "Movies HDTV"}
+      - {id: 409, cat: Movies/Other, desc: "Movies iPad"}
+      - {id: 410, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 411, cat: TV/Anime, desc: "Animations"}
+      - {id: 412, cat: TV, desc: "TV Series"}
+      - {id: 413, cat: TV, desc: "TV Shows"}
+      - {id: 414, cat: Audio/Video, desc: "Music Videos"}
+      - {id: 415, cat: TV/Sport, desc: "Sports"}
+      - {id: 416, cat: Audio, desc: "Music"}
+      - {id: 420, cat: Other, desc: "Other"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [imdbid]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("登录失败"))
+    test:
+      path: /torrents.php
+
+  search:
+    path: /torrents.php
+    method: get
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "1"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      title|optional:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      imdb|optional:
+        selector: div.imdb_100 > a
+        attribute: href
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      date:
+        selector: td:nth-child(4) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a, img
diff --git a/src/Jackett/Definitions/passionetorrent.yml b/src/Jackett/Definitions/passionetorrent.yml
index 212fbe784b8187cfcaa8b8cd93c003616fcd35df..0d1da6c93cd19d77f9e4874e5125dd448f82f526 100644
--- a/src/Jackett/Definitions/passionetorrent.yml
+++ b/src/Jackett/Definitions/passionetorrent.yml
@@ -1,158 +1,158 @@
----
-  site: passionetorrent
-  name: Passione Torrent
-  language: it-it
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.passionetorrent.info/
-
-  caps:
-    categorymappings:
-      # VIDEO
-      - {id: 1, cat: Movies, desc: "News Cinema"}
-      - {id: 2, cat: Movies/SD, desc: "BDRip"}
-      - {id: 17, cat: Movies/SD, desc: "DVDRip"}
-      - {id: 21, cat: TV, desc: "TV"}
-      - {id: 22, cat: Movies/HD, desc: "720p/1080p"}
-      - {id: 23, cat: Movies/HD, desc: "1080p HRS x265 HEVC"}
-      - {id: 42, cat: Movies/HD, desc: "2160p 4k UltraHD HRS"}
-      - {id: 30, cat: TV/Anime, desc: "Cartoons"}
-      - {id: 38, cat: Movies/SD, desc: "BD-BR-DvdRip sub ita"}
-      - {id: 39, cat: Movies/SD, desc: "Introvabili"}
-      - {id: 40, cat: TV/Documentary, desc: "documentaries"}
-      - {id: 24, cat: Movies/SD, desc: "Filmografie"}
-
-      # MUSICA
-      - {id: 32, cat: Audio, desc: "Italian music"}
-      - {id: 41, cat: Audio, desc: "Discography"}
-      - {id: 33, cat: Audio, desc: "MusicaInternazionale"}
-      - {id: 34, cat: Audio, desc: "Compilation"}
-
-      # PDF
-      - {id: 28, cat: Books, desc: "Ebook"}
-
-      # GAMES
-      - {id: 14, cat: PC/Games, desc: "PC Games"}
-
-      # SOFTWARE
-      - {id: 7, cat: PC/ISO, desc: "Sistemi operativi"}
-      - {id: 36, cat: PC/ISO, desc: "Windows APP"}
-      - {id: 9, cat: PC/Phone-IOS, desc: "Apple APP"}
-      - {id: 37, cat: PC/Phone-Android, desc: "Android APP"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: index.php?page=login
-    method: post
-    inputs:
-      uid: "{{ .Config.username }}"
-      pwd: "{{ .Config.password }}"
-    error:
-      - selector: body[onLoad^="makeAlert('"]
-        message:
-          selector: body[onLoad^="makeAlert('"]
-          attribute: onLoad
-          filters:
-            - name: replace
-              args: ["makeAlert('Error' , '", ""]
-            - name: replace
-              args: ["');", ""]
-    test:
-      path: index.php
-
-  download:
-    before:
-      path: "thanks.php"
-      method: "post"
-      inputs:
-        infohash: "{{ .DownloadUri.Query.id }}"
-        thanks: "1"
-        rndval: "1487013827343"
-    selector: a[href^="download.php?id="]
-
-  search:
-    path: index.php
-    keywordsfilters:
-      # most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
-      - name: re_replace
-        args: ["S0?(\\d{1,2})", " $1 "]
-      - name: re_replace
-        args: ["E(\\d{2,3})", " $1 "]
-      - name: replace
-        args: ["-", ""]
-    inputs:
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
-      page: "torrents"
-      category: "{{range .Categories}}{{.}};{{end}}"
-      options: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      active: "0"
-    rows:
-      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
-    fields:
-      download:
-        selector: a[href^="index.php?page=downloadcheck&id="]
-        attribute: href
-      title:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        filters:
-          # normalize to SXXEYY format
-          - name: re_replace
-            args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
-          - name: re_replace
-            args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
-      banner:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "src=(.*?) "
-      category:
-        selector: a[href^="index.php?page=torrents&category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
-        attribute: href
-      size:
-        selector: td:nth-last-child(4)
-      date:
-        selector: td:nth-last-child(8)
-        filters:
-          - name: append
-            args: " +01:00"
-          - name: dateparse
-            args: "02/01/2006 -07:00"
-      grabs:
-        selector: td:nth-last-child(7)
-        filters:
-          - name: replace
-            args: ["---", "0"]
-      seeders:
-        selector: td:nth-last-child(5)
-      leechers:
-        selector: td:nth-last-child(6)
-      downloadvolumefactor:
-        case:
-          img[alt="Gold 100% Free"]: "0"
-          img[alt="Silver 50% Free"]: "0.5"
-          img[alt="Bronze 25% Free"]: "0.75"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[alt="2x Upload Multiplier"]: "2"
-          img[alt="3x Upload Multiplier"]: "3"
-          img[alt="4x Upload Multiplier"]: "4"
-          img[alt="5x Upload Multiplier"]: "5"
-          img[alt="6x Upload Multiplier"]: "6"
-          img[alt="7x Upload Multiplier"]: "7"
-          img[alt="8x Upload Multiplier"]: "8"
-          img[alt="9x Upload Multiplier"]: "9"
-          img[alt="10x Upload Multiplier"]: "10"
+---
+  site: passionetorrent
+  name: Passione Torrent
+  language: it-it
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.passionetorrent.info/
+
+  caps:
+    categorymappings:
+      # VIDEO
+      - {id: 1, cat: Movies, desc: "News Cinema"}
+      - {id: 2, cat: Movies/SD, desc: "BDRip"}
+      - {id: 17, cat: Movies/SD, desc: "DVDRip"}
+      - {id: 21, cat: TV, desc: "TV"}
+      - {id: 22, cat: Movies/HD, desc: "720p/1080p"}
+      - {id: 23, cat: Movies/HD, desc: "1080p HRS x265 HEVC"}
+      - {id: 42, cat: Movies/HD, desc: "2160p 4k UltraHD HRS"}
+      - {id: 30, cat: TV/Anime, desc: "Cartoons"}
+      - {id: 38, cat: Movies/SD, desc: "BD-BR-DvdRip sub ita"}
+      - {id: 39, cat: Movies/SD, desc: "Introvabili"}
+      - {id: 40, cat: TV/Documentary, desc: "documentaries"}
+      - {id: 24, cat: Movies/SD, desc: "Filmografie"}
+
+      # MUSICA
+      - {id: 32, cat: Audio, desc: "Italian music"}
+      - {id: 41, cat: Audio, desc: "Discography"}
+      - {id: 33, cat: Audio, desc: "MusicaInternazionale"}
+      - {id: 34, cat: Audio, desc: "Compilation"}
+
+      # PDF
+      - {id: 28, cat: Books, desc: "Ebook"}
+
+      # GAMES
+      - {id: 14, cat: PC/Games, desc: "PC Games"}
+
+      # SOFTWARE
+      - {id: 7, cat: PC/ISO, desc: "Sistemi operativi"}
+      - {id: 36, cat: PC/ISO, desc: "Windows APP"}
+      - {id: 9, cat: PC/Phone-IOS, desc: "Apple APP"}
+      - {id: 37, cat: PC/Phone-Android, desc: "Android APP"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: index.php?page=login
+    method: post
+    inputs:
+      uid: "{{ .Config.username }}"
+      pwd: "{{ .Config.password }}"
+    error:
+      - selector: body[onLoad^="makeAlert('"]
+        message:
+          selector: body[onLoad^="makeAlert('"]
+          attribute: onLoad
+          filters:
+            - name: replace
+              args: ["makeAlert('Error' , '", ""]
+            - name: replace
+              args: ["');", ""]
+    test:
+      path: index.php
+
+  download:
+    before:
+      path: "thanks.php"
+      method: "post"
+      inputs:
+        infohash: "{{ .DownloadUri.Query.id }}"
+        thanks: "1"
+        rndval: "1487013827343"
+    selector: a[href^="download.php?id="]
+
+  search:
+    path: index.php
+    keywordsfilters:
+      # most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
+      - name: re_replace
+        args: ["S0?(\\d{1,2})", " $1 "]
+      - name: re_replace
+        args: ["E(\\d{2,3})", " $1 "]
+      - name: replace
+        args: ["-", ""]
+    inputs:
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBIDShort }}{{else}}{{ .Keywords }}{{end}}"
+      page: "torrents"
+      category: "{{range .Categories}}{{.}};{{end}}"
+      options: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      active: "0"
+    rows:
+      selector: table > tbody > tr > td > table.lista > tbody > tr:has(a[href^="index.php?page=torrent-details&id="])
+    fields:
+      download:
+        selector: a[href^="index.php?page=downloadcheck&id="]
+        attribute: href
+      title:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        filters:
+          # normalize to SXXEYY format
+          - name: re_replace
+            args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
+          - name: re_replace
+            args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
+      banner:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "src=(.*?) "
+      category:
+        selector: a[href^="index.php?page=torrents&category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: a[onmouseover][href^="index.php?page=torrent-details&id="]
+        attribute: href
+      size:
+        selector: td:nth-last-child(4)
+      date:
+        selector: td:nth-last-child(8)
+        filters:
+          - name: append
+            args: " +01:00"
+          - name: dateparse
+            args: "02/01/2006 -07:00"
+      grabs:
+        selector: td:nth-last-child(7)
+        filters:
+          - name: replace
+            args: ["---", "0"]
+      seeders:
+        selector: td:nth-last-child(5)
+      leechers:
+        selector: td:nth-last-child(6)
+      downloadvolumefactor:
+        case:
+          img[alt="Gold 100% Free"]: "0"
+          img[alt="Silver 50% Free"]: "0.5"
+          img[alt="Bronze 25% Free"]: "0.75"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[alt="2x Upload Multiplier"]: "2"
+          img[alt="3x Upload Multiplier"]: "3"
+          img[alt="4x Upload Multiplier"]: "4"
+          img[alt="5x Upload Multiplier"]: "5"
+          img[alt="6x Upload Multiplier"]: "6"
+          img[alt="7x Upload Multiplier"]: "7"
+          img[alt="8x Upload Multiplier"]: "8"
+          img[alt="9x Upload Multiplier"]: "9"
+          img[alt="10x Upload Multiplier"]: "10"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/polishsource.yml b/src/Jackett/Definitions/polishsource.yml
index dbe0ad409509ccc02abc638a68bcf39408e110d8..8c6824702c191898f1f4a13a85135a892213600b 100644
--- a/src/Jackett/Definitions/polishsource.yml
+++ b/src/Jackett/Definitions/polishsource.yml
@@ -1,115 +1,115 @@
----
-  site: polishsource
-  name: PolishSource
-  language: pl-pl
-  type: private
-  encoding: ISO-8859-2
-  links:
-    - https://polishsource.cz/
-
-  caps:
-    categorymappings:
-      - {id: 12, cat: Movies/SD, desc: "Movies/SD"}
-      - {id: 11, cat: Movies/HD, desc: "Movies/HD"}
-      - {id: 45, cat: Movies/3D, desc: "Movies/3D"}
-      - {id: 4, cat: Movies/DVD, desc: "Movies/DVD"}
-      - {id: 43, cat: Movies/BluRay, desc: "Movies/BD"}
-      - {id: 10, cat: TV/SD, desc: "TV/SD"}
-      - {id: 39, cat: TV/HD, desc: "TV/HD"}
-      - {id: 8, cat: PC/Games, desc: "Games/PC"}
-      - {id: 3, cat: Console, desc: "Games/Consoles"}
-      - {id: 5, cat: Books, desc: "E-Books"}
-      - {id: 42, cat: Audio, desc: "Music"}
-      - {id: 18, cat: PC/0day, desc: "Apps"}
-      - {id: 13, cat: XXX, desc: "XXX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    captcha:
-      type: image
-      image: img[src="img.php"]
-      input: vImageCodP
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-      - selector: td.embedded:has(h2:contains("Error"))
-    test:
-      path: /browse.php
-        
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      scene: "0"
-      pl: "0"
-      sub: ""
-      search_in: "title"
-    rows:
-      selector: table#restable > tbody > tr:has(a[href^="details.php?id="])
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="downloadssl.php?id="]
-        attribute: href
-      description|optional:
-        selector: td:nth-child(2) > small
-        filters:
-          - name: prepend
-            args: "Genre: "
-          - name: append
-            args: "\n<br>"
-      description|optional|append|1:
-        selector: img[src="pic/pl.png"]
-        filters:
-          - name: append
-            args: "Language: polish\n<br>"
-      description|optional|append|2:
-        selector: img[src="pic/napisy.png"]
-        filters:
-          - name: append
-            args: "Subbed\n<br>"
-      imdb|optional:
-        selector: a[href^="http://www.imdb.com/title/tt"]
-      grabs:
-        selector: td:nth-child(6)
-        filters:
-          - name: regexp
-            args: (\d+)
-      size:
-        selector: td:nth-child(5)
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "2006-01-0215:04:05 -07:00"
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
-        text: "1"
+---
+  site: polishsource
+  name: PolishSource
+  language: pl-pl
+  type: private
+  encoding: ISO-8859-2
+  links:
+    - https://polishsource.cz/
+
+  caps:
+    categorymappings:
+      - {id: 12, cat: Movies/SD, desc: "Movies/SD"}
+      - {id: 11, cat: Movies/HD, desc: "Movies/HD"}
+      - {id: 45, cat: Movies/3D, desc: "Movies/3D"}
+      - {id: 4, cat: Movies/DVD, desc: "Movies/DVD"}
+      - {id: 43, cat: Movies/BluRay, desc: "Movies/BD"}
+      - {id: 10, cat: TV/SD, desc: "TV/SD"}
+      - {id: 39, cat: TV/HD, desc: "TV/HD"}
+      - {id: 8, cat: PC/Games, desc: "Games/PC"}
+      - {id: 3, cat: Console, desc: "Games/Consoles"}
+      - {id: 5, cat: Books, desc: "E-Books"}
+      - {id: 42, cat: Audio, desc: "Music"}
+      - {id: 18, cat: PC/0day, desc: "Apps"}
+      - {id: 13, cat: XXX, desc: "XXX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    captcha:
+      type: image
+      image: img[src="img.php"]
+      input: vImageCodP
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+      - selector: td.embedded:has(h2:contains("Error"))
+    test:
+      path: /browse.php
+        
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      scene: "0"
+      pl: "0"
+      sub: ""
+      search_in: "title"
+    rows:
+      selector: table#restable > tbody > tr:has(a[href^="details.php?id="])
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="downloadssl.php?id="]
+        attribute: href
+      description|optional:
+        selector: td:nth-child(2) > small
+        filters:
+          - name: prepend
+            args: "Genre: "
+          - name: append
+            args: "\n<br>"
+      description|optional|append|1:
+        selector: img[src="pic/pl.png"]
+        filters:
+          - name: append
+            args: "Language: polish\n<br>"
+      description|optional|append|2:
+        selector: img[src="pic/napisy.png"]
+        filters:
+          - name: append
+            args: "Subbed\n<br>"
+      imdb|optional:
+        selector: a[href^="http://www.imdb.com/title/tt"]
+      grabs:
+        selector: td:nth-child(6)
+        filters:
+          - name: regexp
+            args: (\d+)
+      size:
+        selector: td:nth-child(5)
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "2006-01-0215:04:05 -07:00"
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
+        text: "1"
diff --git a/src/Jackett/Definitions/qctorrent.yml b/src/Jackett/Definitions/qctorrent.yml
index 130ddfc23069c2cae99ee69d79eb2071ff4e3cef..0f99ae43f4d9049d9789effa2a70ada1521cfff8 100644
--- a/src/Jackett/Definitions/qctorrent.yml
+++ b/src/Jackett/Definitions/qctorrent.yml
@@ -1,107 +1,107 @@
----
-  site: qctorrent
-  name: QcTorrent
-  description: "A French gerneral tracker"
-  language: fr-fr
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.qctorrent.net/
-
-  caps:
-    categorymappings:
-      - {id: 30, cat: PC, desc: "++ Applications"}
-      - {id: 1, cat: PC, desc: "Applications/Divers"}
-      - {id: 2, cat: PC, desc: "Applications/PC ISO"}
-      - {id: 3, cat: PC, desc: "Applications/Portable"}
-      - {id: 31, cat: Movies, desc: "++ Films"}
-      - {id: 4, cat: Movies/BluRay, desc: "Films/Bluray"}
-      - {id: 5, cat: Movies/DVD, desc: "Films/DVDr"}
-      - {id: 6, cat: Movies/HD, desc: "Films/HD Rip"}
-      - {id: 7, cat: Movies/SD, desc: "Films/SD Rip"}
-      - {id: 8, cat: Movies/SD, desc: "Films/VCD"}
-      - {id: 32, cat: Console, desc: "++ Jeux"}
-      - {id: 9, cat: PC/Games, desc: "Jeux/PC"}
-      - {id: 10, cat: Console, desc: "Jeux/Portable"}
-      - {id: 11, cat: Console/PS4, desc: "Jeux/PS"}
-      - {id: 12, cat: Console/Wii, desc: "Jeux/Wii"}
-      - {id: 13, cat: Console/Xbox, desc: "Jeux/Xbox"}
-      - {id: 33, cat: Audio, desc: "++ Musique"}
-      - {id: 14, cat: Audio, desc: "Musique"}
-      - {id: 15, cat: Audio/Video, desc: "Musique/Video"}
-      - {id: 34, cat: TV, desc: "++ Série-Télé"}
-      - {id: 16, cat: TV/HD, desc: "Série-Télé/Bluray"}
-      - {id: 17, cat: TV/SD, desc: "Série-Télé/DVDr"}
-      - {id: 18, cat: TV/HD, desc: "Série-Télé/HD Rip"}
-      - {id: 19, cat: TV/SD, desc: "Série-Télé/SD Rip"}
-      - {id: 20, cat: Books, desc: "E-Books"}
-      - {id: 21, cat: XXX, desc: "XXX"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      login-username: "{{ .Config.username }}"
-      login-password: "{{ .Config.password }}"
-      login-remember-me: "on"
-      login: ""
-    error:
-      - selector: "script[type=\"text/javascript\"]:contains(\"$.ambiance({message: \")"
-    test:
-      path: search.php
-      selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
-
-  ratio:
-    path: search.php
-    selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
-
-  search:
-    path: search.php
-    inputs:
-      category: "{{range .Categories}}{{.}};{{end}}"
-      title: "{{ .Query.Keywords }}"
-      search: "Recherche"
-    rows:
-      selector: tr[data-snatches]
-    fields:
-      download:
-        selector: td.name > a
-        attribute: href
-        filters:
-          - name: replace
-            args: ["/torrent/", "/dl/"]
-      title:
-        selector: td.name > a
-      category:
-        selector: td.coll-0 > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: td.name > a
-        attribute: href
-      grabs:
-        attribute: data-snatches
-      seeders:
-        selector: td.seeds
-      leechers:
-        selector: td.leeches
-      date:
-        selector: td[data-date]
-        attribute: data-date
-      downloadvolumefactor:
-        case:
-          span[title^="Freeleech:"]: "0"
-          span[title^="Half Freeleech:"]: "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      size:
-        selector: td.size
+---
+  site: qctorrent
+  name: QcTorrent
+  description: "A French gerneral tracker"
+  language: fr-fr
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.qctorrent.net/
+
+  caps:
+    categorymappings:
+      - {id: 30, cat: PC, desc: "++ Applications"}
+      - {id: 1, cat: PC, desc: "Applications/Divers"}
+      - {id: 2, cat: PC, desc: "Applications/PC ISO"}
+      - {id: 3, cat: PC, desc: "Applications/Portable"}
+      - {id: 31, cat: Movies, desc: "++ Films"}
+      - {id: 4, cat: Movies/BluRay, desc: "Films/Bluray"}
+      - {id: 5, cat: Movies/DVD, desc: "Films/DVDr"}
+      - {id: 6, cat: Movies/HD, desc: "Films/HD Rip"}
+      - {id: 7, cat: Movies/SD, desc: "Films/SD Rip"}
+      - {id: 8, cat: Movies/SD, desc: "Films/VCD"}
+      - {id: 32, cat: Console, desc: "++ Jeux"}
+      - {id: 9, cat: PC/Games, desc: "Jeux/PC"}
+      - {id: 10, cat: Console, desc: "Jeux/Portable"}
+      - {id: 11, cat: Console/PS4, desc: "Jeux/PS"}
+      - {id: 12, cat: Console/Wii, desc: "Jeux/Wii"}
+      - {id: 13, cat: Console/Xbox, desc: "Jeux/Xbox"}
+      - {id: 33, cat: Audio, desc: "++ Musique"}
+      - {id: 14, cat: Audio, desc: "Musique"}
+      - {id: 15, cat: Audio/Video, desc: "Musique/Video"}
+      - {id: 34, cat: TV, desc: "++ Série-Télé"}
+      - {id: 16, cat: TV/HD, desc: "Série-Télé/Bluray"}
+      - {id: 17, cat: TV/SD, desc: "Série-Télé/DVDr"}
+      - {id: 18, cat: TV/HD, desc: "Série-Télé/HD Rip"}
+      - {id: 19, cat: TV/SD, desc: "Série-Télé/SD Rip"}
+      - {id: 20, cat: Books, desc: "E-Books"}
+      - {id: 21, cat: XXX, desc: "XXX"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      login-username: "{{ .Config.username }}"
+      login-password: "{{ .Config.password }}"
+      login-remember-me: "on"
+      login: ""
+    error:
+      - selector: "script[type=\"text/javascript\"]:contains(\"$.ambiance({message: \")"
+    test:
+      path: search.php
+      selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
+
+  ratio:
+    path: search.php
+    selector: div.top-bar > div.container > div.textleft > div.hidden-sm > font:contains("Ratio:") > font
+
+  search:
+    path: search.php
+    inputs:
+      category: "{{range .Categories}}{{.}};{{end}}"
+      title: "{{ .Query.Keywords }}"
+      search: "Recherche"
+    rows:
+      selector: tr[data-snatches]
+    fields:
+      download:
+        selector: td.name > a
+        attribute: href
+        filters:
+          - name: replace
+            args: ["/torrent/", "/dl/"]
+      title:
+        selector: td.name > a
+      category:
+        selector: td.coll-0 > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: td.name > a
+        attribute: href
+      grabs:
+        attribute: data-snatches
+      seeders:
+        selector: td.seeds
+      leechers:
+        selector: td.leeches
+      date:
+        selector: td[data-date]
+        attribute: data-date
+      downloadvolumefactor:
+        case:
+          span[title^="Freeleech:"]: "0"
+          span[title^="Half Freeleech:"]: "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      size:
+        selector: td.size
         remove: span
\ No newline at end of file
diff --git a/src/Jackett/Definitions/redacted-scrape.yml b/src/Jackett/Definitions/redacted-scrape.yml
index 448ff591fe9032b1028f5a1d6f5c2673f272247b..166d0d22cc1bda3959ee4e379bfa3f39c9fcad98 100644
--- a/src/Jackett/Definitions/redacted-scrape.yml
+++ b/src/Jackett/Definitions/redacted-scrape.yml
@@ -1,103 +1,103 @@
----
-  site: redacted-scrape
-  name: Redacted (scrape)
-  description: "A music tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://redacted.ch/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Audio, desc: "Music"}
-      - {id: 2, cat: PC, desc: "Applications"}
-      - {id: 3, cat: Books, desc: "E-Books"}
-      - {id: 4, cat: Audio/Audiobook, desc: "Audiobooks"}
-      - {id: 5, cat: Movies, desc: "E-Learning Videos"}
-      - {id: 6, cat: TV, desc: "Comedy"}
-      - {id: 7, cat: Books/Comics, desc: "Comics"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: 1
-      login: "Log in"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: torrents.php
-
-  ratio:
-    path: torrents.php
-    selector: li#stats_ratio > span
-
-  search:
-    path: torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{ .Query.Keywords }}"
-      order_by: time
-      order_way: desc
-      action: basic
-      searchsubmit: 1
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      download:
-        selector: a[href^="torrents.php?action=download&id="]
-        attribute: href
-      description:
-        selector: div.group_info
-        remove: span
-      title:
-        selector: div.group_info
-        remove: span, div.tags
-        filters:
-          - name: replace
-            args: [" / Neutral Leech!", ""]
-          - name: replace
-            args: [" / Freeleech!", ""]
-      category:
-        selector: td.cats_col
-        case:
-          div.cats_music: 1
-          div.cats_applications: 2
-          div.cats_ebooks: 3
-          div.cats_audiobooks: 4
-          div.cats_elearningvideos: 5
-          div.cats_comedy: 6
-          div.cats_comics: 7
-      comments:
-        selector: a[href^="torrents.php?id="]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          "strong.tl_free": "0"
-          "strong.tl_neutral": "0"
-          ":root div.alertbar:contains(\"freeleech\")": "0"
-          ":root div.alertbar:contains(\"FREELEECH\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "strong.tl_neutral": "0"
+---
+  site: redacted-scrape
+  name: Redacted (scrape)
+  description: "A music tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://redacted.ch/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Audio, desc: "Music"}
+      - {id: 2, cat: PC, desc: "Applications"}
+      - {id: 3, cat: Books, desc: "E-Books"}
+      - {id: 4, cat: Audio/Audiobook, desc: "Audiobooks"}
+      - {id: 5, cat: Movies, desc: "E-Learning Videos"}
+      - {id: 6, cat: TV, desc: "Comedy"}
+      - {id: 7, cat: Books/Comics, desc: "Comics"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: 1
+      login: "Log in"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: torrents.php
+
+  ratio:
+    path: torrents.php
+    selector: li#stats_ratio > span
+
+  search:
+    path: torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{ .Query.Keywords }}"
+      order_by: time
+      order_way: desc
+      action: basic
+      searchsubmit: 1
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      download:
+        selector: a[href^="torrents.php?action=download&id="]
+        attribute: href
+      description:
+        selector: div.group_info
+        remove: span
+      title:
+        selector: div.group_info
+        remove: span, div.tags
+        filters:
+          - name: replace
+            args: [" / Neutral Leech!", ""]
+          - name: replace
+            args: [" / Freeleech!", ""]
+      category:
+        selector: td.cats_col
+        case:
+          div.cats_music: 1
+          div.cats_applications: 2
+          div.cats_ebooks: 3
+          div.cats_audiobooks: 4
+          div.cats_elearningvideos: 5
+          div.cats_comedy: 6
+          div.cats_comics: 7
+      comments:
+        selector: a[href^="torrents.php?id="]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          "strong.tl_free": "0"
+          "strong.tl_neutral": "0"
+          ":root div.alertbar:contains(\"freeleech\")": "0"
+          ":root div.alertbar:contains(\"FREELEECH\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "strong.tl_neutral": "0"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/rockhardlossless.yml b/src/Jackett/Definitions/rockhardlossless.yml
index 51ecee8abc795bfa82a3abf8c7b0efc98f5a57d1..2420eb1c9be03b24a51183a62f1c9d4d6149bdc6 100644
--- a/src/Jackett/Definitions/rockhardlossless.yml
+++ b/src/Jackett/Definitions/rockhardlossless.yml
@@ -1,80 +1,80 @@
----
-  site: rockhardlossless
-  name: Rockhard Lossless
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://rockhard-lossless.org
-
-  caps:
-    categories:
-      1: Audio
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: tbody:has(td.colhead > span:contains("Error"))
-      - selector: tbody:has(td.colhead > span:contains("failed"))
-    test:
-      path: /browse.php
-
-  search:
-    path: /browse.php
-    method: post
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      searchin: "title"
-    rows:
-      selector: table > tbody tr.tt
-      filters:
-        - name: andmatch
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      category:
-        text: "1"
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?torrent="]
-        attribute: href
-      banner:
-        selector: td:nth-child(2) > img
-        attribute: src
-      size:
-        selector: td:nth-child(8)
-      files:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(9)
-        filters:
-          - name: regexp
-            args: ([\d\.]+)
-      seeders:
-        selector: td:nth-child(10)
-      leechers:
-        selector: td:nth-child(11)
-      date:
-        selector: td:nth-child(7)
-      downloadvolumefactor:
-        case:
-          "a.info > b:contains(\"Free\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(3)
-        remove: a, div, font:contains("NEW!")
+---
+  site: rockhardlossless
+  name: Rockhard Lossless
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://rockhard-lossless.org
+
+  caps:
+    categories:
+      1: Audio
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: tbody:has(td.colhead > span:contains("Error"))
+      - selector: tbody:has(td.colhead > span:contains("failed"))
+    test:
+      path: /browse.php
+
+  search:
+    path: /browse.php
+    method: post
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      searchin: "title"
+    rows:
+      selector: table > tbody tr.tt
+      filters:
+        - name: andmatch
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      category:
+        text: "1"
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?torrent="]
+        attribute: href
+      banner:
+        selector: td:nth-child(2) > img
+        attribute: src
+      size:
+        selector: td:nth-child(8)
+      files:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(9)
+        filters:
+          - name: regexp
+            args: ([\d\.]+)
+      seeders:
+        selector: td:nth-child(10)
+      leechers:
+        selector: td:nth-child(11)
+      date:
+        selector: td:nth-child(7)
+      downloadvolumefactor:
+        case:
+          "a.info > b:contains(\"Free\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(3)
+        remove: a, div, font:contains("NEW!")
diff --git a/src/Jackett/Definitions/rodvd.yml b/src/Jackett/Definitions/rodvd.yml
index ce01ea8636ed7c1cc6e0a649ba5dfbe429e3073c..526b314c14039fdf1024691d35696e1d577df680 100644
--- a/src/Jackett/Definitions/rodvd.yml
+++ b/src/Jackett/Definitions/rodvd.yml
@@ -1,125 +1,125 @@
----
-  site: rodvd
-  name: RoDVD
-  language: ro-ro
-  type: private
-  encoding: windows-1252
-  links:
-    - http://rodvd.net/
-
-  caps:
-    categorymappings:
-      - {id: 48, cat: Movies/3D, desc: "3D"}
-      - {id: 1, cat: PC/0day, desc: "Appz"}
-      - {id: 3, cat: Other, desc: "Cartoons"}
-      - {id: 42, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 6, cat: Books, desc: "eBooks"}
-      - {id: 11, cat: PC/Games, desc: "Games | PC"}
-      - {id: 12, cat: Console/PS3, desc: "Games | PS2"}
-      - {id: 36, cat: Console/PS3, desc: "Games | PS3"}
-      - {id: 40, cat: Console/PSP, desc: "Games | PSP"}
-      - {id: 25, cat: Console/Wii, desc: "Games | Wii"}
-      - {id: 16, cat: Console/Xbox, desc: "Games | XBOX"}
-      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 43, cat: Movies/BluRay, desc: "Movies | Blu-Ray"}
-      - {id: 49, cat: Movies/BluRay, desc: "Movies | Blu-Ray-RO"}
-      - {id: 7, cat: Movies/DVD, desc: "Movies | DVD-R"}
-      - {id: 2, cat: Movies/DVD, desc: "Movies | DVD-RO"}
-      - {id: 17, cat: Movies/HD, desc: "Movies | HD"}
-      - {id: 45, cat: Movies/HD, desc: "Movies | HD-RO"}
-      - {id: 21, cat: Movies, desc: "Movies | Oldies"}
-      - {id: 38, cat: Movies, desc: "Movies | Packs"}
-      - {id: 8, cat: Movies/SD, desc: "Movies | x264"}
-      - {id: 4, cat: Movies/SD, desc: "Movies | x264-RO"}
-      - {id: 10, cat: Movies/SD, desc: "Movies | XviD"}
-      - {id: 44, cat: Movies/SD, desc: "Movies | XviD-RO"}
-      - {id: 5, cat: Audio/MP3, desc: "Music | Mp3"}
-      - {id: 39, cat: Audio, desc: "Music | Packs"}
-      - {id: 23, cat: Audio/Video, desc: "Music | Videos"}
-      - {id: 18, cat: Other, desc: "Pictures"}
-      - {id: 46, cat: XXX/Imageset, desc: "Pictures | xxx"}
-      - {id: 22, cat: TV/Sport, desc: "Sport"}
-      - {id: 50, cat: TV, desc: "STAR"}
-      - {id: 20, cat: TV/SD, desc: "TV | Episodes"}
-      - {id: 47, cat: TV/HD, desc: "TV | Episodes HD"}
-      - {id: 41, cat: TV, desc: "TV | Packs"}
-      - {id: 15, cat: XXX, desc: "xXx"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q, imdbid]
-
-  login:
-    path: login.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.loginerr
-    test:
-      path: browse.php
-      
-  ratio:
-    path: browse.php
-    selector: a#link14
-
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
-      key: 9
-    rows:
-      selector: table.torrents > tbody > tr:has(a[href^="details.php?id="])
-      filters:
-        - name: andmatch
-      dateheaders:
-        selector: "td.days > font > b"
-        filters:
-          - name: replace
-            args: ["Torrents Added: ", ""]
-          - name: dateparse
-            args: "2.1.2006"
-    fields:
-      title:
-        selector: a[href^="details.php?id="] font
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      imdb|optional:
-        selector: a[href*="http://www.imdb.com/title/tt"]
-        attribute: href
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        text: 9999
-      leechers:
-        text: 0
-      banner:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "src=\"([^\"]+)"
-      downloadvolumefactor:
-        case:
-          "font.small[color]:contains(\"Free\")": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a[href^="details.php?id="]
+---
+  site: rodvd
+  name: RoDVD
+  language: ro-ro
+  type: private
+  encoding: windows-1252
+  links:
+    - http://rodvd.net/
+
+  caps:
+    categorymappings:
+      - {id: 48, cat: Movies/3D, desc: "3D"}
+      - {id: 1, cat: PC/0day, desc: "Appz"}
+      - {id: 3, cat: Other, desc: "Cartoons"}
+      - {id: 42, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 6, cat: Books, desc: "eBooks"}
+      - {id: 11, cat: PC/Games, desc: "Games | PC"}
+      - {id: 12, cat: Console/PS3, desc: "Games | PS2"}
+      - {id: 36, cat: Console/PS3, desc: "Games | PS3"}
+      - {id: 40, cat: Console/PSP, desc: "Games | PSP"}
+      - {id: 25, cat: Console/Wii, desc: "Games | Wii"}
+      - {id: 16, cat: Console/Xbox, desc: "Games | XBOX"}
+      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 43, cat: Movies/BluRay, desc: "Movies | Blu-Ray"}
+      - {id: 49, cat: Movies/BluRay, desc: "Movies | Blu-Ray-RO"}
+      - {id: 7, cat: Movies/DVD, desc: "Movies | DVD-R"}
+      - {id: 2, cat: Movies/DVD, desc: "Movies | DVD-RO"}
+      - {id: 17, cat: Movies/HD, desc: "Movies | HD"}
+      - {id: 45, cat: Movies/HD, desc: "Movies | HD-RO"}
+      - {id: 21, cat: Movies, desc: "Movies | Oldies"}
+      - {id: 38, cat: Movies, desc: "Movies | Packs"}
+      - {id: 8, cat: Movies/SD, desc: "Movies | x264"}
+      - {id: 4, cat: Movies/SD, desc: "Movies | x264-RO"}
+      - {id: 10, cat: Movies/SD, desc: "Movies | XviD"}
+      - {id: 44, cat: Movies/SD, desc: "Movies | XviD-RO"}
+      - {id: 5, cat: Audio/MP3, desc: "Music | Mp3"}
+      - {id: 39, cat: Audio, desc: "Music | Packs"}
+      - {id: 23, cat: Audio/Video, desc: "Music | Videos"}
+      - {id: 18, cat: Other, desc: "Pictures"}
+      - {id: 46, cat: XXX/Imageset, desc: "Pictures | xxx"}
+      - {id: 22, cat: TV/Sport, desc: "Sport"}
+      - {id: 50, cat: TV, desc: "STAR"}
+      - {id: 20, cat: TV/SD, desc: "TV | Episodes"}
+      - {id: 47, cat: TV/HD, desc: "TV | Episodes HD"}
+      - {id: 41, cat: TV, desc: "TV | Packs"}
+      - {id: 15, cat: XXX, desc: "xXx"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q, imdbid]
+
+  login:
+    path: login.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.loginerr
+    test:
+      path: browse.php
+      
+  ratio:
+    path: browse.php
+    selector: a#link14
+
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Query.Keywords }}{{end}}"
+      key: 9
+    rows:
+      selector: table.torrents > tbody > tr:has(a[href^="details.php?id="])
+      filters:
+        - name: andmatch
+      dateheaders:
+        selector: "td.days > font > b"
+        filters:
+          - name: replace
+            args: ["Torrents Added: ", ""]
+          - name: dateparse
+            args: "2.1.2006"
+    fields:
+      title:
+        selector: a[href^="details.php?id="] font
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      imdb|optional:
+        selector: a[href*="http://www.imdb.com/title/tt"]
+        attribute: href
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        text: 9999
+      leechers:
+        text: 0
+      banner:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "src=\"([^\"]+)"
+      downloadvolumefactor:
+        case:
+          "font.small[color]:contains(\"Free\")": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a[href^="details.php?id="]
diff --git a/src/Jackett/Definitions/sdbits.yml b/src/Jackett/Definitions/sdbits.yml
index c7c3922859c5db86efbc967f4c445c30b7f0eef3..150f9d39342c87a2cfa3164e6ab5225ee2ca7606 100644
--- a/src/Jackett/Definitions/sdbits.yml
+++ b/src/Jackett/Definitions/sdbits.yml
@@ -1,94 +1,94 @@
----
-  site: sdbits
-  name: SDBits
-  description: "SDBits is a small tracker that focuses on SD movies and tv."
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://sdbits.org
-
-  caps:
-    categorymappings:
-      - {id: 6, cat: Audio, desc: "Audio"}
-      - {id: 3, cat: TV/Documentary, desc: "Documentary"}
-      - {id: 1, cat: Movies, desc: "Movies"}
-      - {id: 4, cat: Audio, desc: "Music"}
-      - {id: 5, cat: TV/Sport, desc: "Sports"}
-      - {id: 2, cat: TV, desc: "TV"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takeloginn3.php
-    method: post
-    inputs:
-      uname: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      returnto: "/"
-    error:
-      - selector: td.embedded:has(h2:contains("failed")+table)
-    test:
-      path: /browse.php
-      selector: span.smallfont:has(a[href="logout.php"])
-
-  ratio:
-    path: /browse.php
-    selector: span.smallfont:has(a[href="logout.php"])
-    filters:
-      - name: regexp
-        args: "Ratio:[ \u00a0](.*?)\u00a0"
-
-  search:
-    path: /browse.php
-    method: post
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      descriptions: "0"
-    rows:
-      selector: table#torrent-list > tbody > tr[id]
-    fields:
-      title:
-        selector: td:nth-child(3) > b > a
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: td:nth-child(3) > b > a
-        attribute: href      
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      size:
-        selector: td:nth-child(6)
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-        - name: regexp
-          args: "(\\d+)"
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " ago"
-      imdb:
-        selector: a[href^="http://www.imdb.com/"]
-        attribute: href
-      downloadvolumefactor:
-        case:
-          "a[style=\"color:#000099\"][href^=\"details.php?\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: sdbits
+  name: SDBits
+  description: "SDBits is a small tracker that focuses on SD movies and tv."
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://sdbits.org
+
+  caps:
+    categorymappings:
+      - {id: 6, cat: Audio, desc: "Audio"}
+      - {id: 3, cat: TV/Documentary, desc: "Documentary"}
+      - {id: 1, cat: Movies, desc: "Movies"}
+      - {id: 4, cat: Audio, desc: "Music"}
+      - {id: 5, cat: TV/Sport, desc: "Sports"}
+      - {id: 2, cat: TV, desc: "TV"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takeloginn3.php
+    method: post
+    inputs:
+      uname: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      returnto: "/"
+    error:
+      - selector: td.embedded:has(h2:contains("failed")+table)
+    test:
+      path: /browse.php
+      selector: span.smallfont:has(a[href="logout.php"])
+
+  ratio:
+    path: /browse.php
+    selector: span.smallfont:has(a[href="logout.php"])
+    filters:
+      - name: regexp
+        args: "Ratio:[ \u00a0](.*?)\u00a0"
+
+  search:
+    path: /browse.php
+    method: post
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      descriptions: "0"
+    rows:
+      selector: table#torrent-list > tbody > tr[id]
+    fields:
+      title:
+        selector: td:nth-child(3) > b > a
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: td:nth-child(3) > b > a
+        attribute: href      
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      size:
+        selector: td:nth-child(6)
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+        - name: regexp
+          args: "(\\d+)"
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " ago"
+      imdb:
+        selector: a[href^="http://www.imdb.com/"]
+        attribute: href
+      downloadvolumefactor:
+        case:
+          "a[style=\"color:#000099\"][href^=\"details.php?\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/secretcinema.yml b/src/Jackett/Definitions/secretcinema.yml
index cfd546bd84e40cc722ea474406a60398cad62c41..be750a894825d018de01543a5b3ea4a0b438e7f7 100644
--- a/src/Jackett/Definitions/secretcinema.yml
+++ b/src/Jackett/Definitions/secretcinema.yml
@@ -1,130 +1,130 @@
----
-  site: secretcinema
-  name: Secret Cinema
-  description: "A tracker for rare movies."
-  language: en-us
-  type: private
-  encoding: "UTF-8"
-  links:
-    - http://www.secret-cinema.net
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: TV/Anime, desc: "Animation"}
-      - {id: 2, cat: Movies, desc: "Arthouse"}
-      - {id: 3, cat: Movies, desc: "Asian"}
-      - {id: 19, cat: Audio/Audiobook, desc: "Audiobooks"}
-      - {id: 29, cat: Movies, desc: "Badfilm"}
-      - {id: 18, cat: Books, desc: "Books"}
-      - {id: 4, cat: Movies, desc: "Classics"}
-      - {id: 5, cat: Movies, desc: "Comedy"}
-      - {id: 20, cat: Books/Comics, desc: "Comix"}
-      - {id: 6, cat: Movies, desc: "Cult"}
-      - {id: 7, cat: TV/Documentary, desc: "Documentary"}
-      - {id: 8, cat: Movies, desc: "Fantasy & SF"}
-      - {id: 9, cat: Movies, desc: "Horror"}
-      - {id: 22, cat: Movies, desc: "Noir"}
-      - {id: 17, cat: Audio, desc: "OST"}
-      - {id: 10, cat: Other, desc: "Other"}
-      - {id: 15, cat: TV, desc: "Other TV"}
-      - {id: 16, cat: Audio, desc: "Radio"}
-      - {id: 11, cat: Movies, desc: "Silent"}
-      - {id: 12, cat: TV, desc: "Talent Show!"}
-      - {id: 14, cat: Movies, desc: "TV Movies"}
-      - {id: 13, cat: TV, desc: "TV Series"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      returnto: "index.php"
-    test:
-      path: /browse.php
-      selector: div.Userstats
-
-  ratio:
-    path: /browse.php
-    selector: div.Userstats
-    filters:
-      - name: regexp
-        args: "\n\u00a0(.*) \u00a0"
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=on&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      tpp: "100"
-      dirty: "1"
-    rows:
-      selector: td > table[id="large"] > tbody > tr:has(div.browsing)
-      filters:
-        - name: andmatch
-      dateheaders:
-        selector: ":has(td.colhead[title] > b)"
-        filters:
-          - name: dateparse
-            args: "Mon 02 Jan"
-    fields:
-      title:
-        selector: a[href^="viewtopic.php?id="]
-      description:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(2)
-      category:
-        selector: a[href^="browse.php?cat"]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["browse.php?cat", ""]
-          - name: replace
-            args: ["=on", ""]
-      details:
-        selector: a[href^="viewtopic.php?id="]
-        attribute: href      
-      download:
-        selector: a[href^="download.php/"]
-        attribute: href
-      size:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(4)
-      files:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(3)
-        filters:
-        - name: regexp
-          args: "(\\d+)"
-      grabs:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(5)
-        filters:
-        - name: regexp
-          args: "(\\d+)"
-      seeders:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(6)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      leechers:
-        selector: table > tbody > tr:nth-child(2) > td:nth-child(7)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      date:
-        selector: td:nth-child(1) > div > table > tbody > tr:nth-child(2) > td:nth-child(1)
-        filters:
-          - name: replace
-            args: ["'", ""]
-          - name: replace
-            args: ["\xA0", ""]
-          - name: dateparse
-            args: "02 Jan 0615:04"
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: secretcinema
+  name: Secret Cinema
+  description: "A tracker for rare movies."
+  language: en-us
+  type: private
+  encoding: "UTF-8"
+  links:
+    - http://www.secret-cinema.net
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: TV/Anime, desc: "Animation"}
+      - {id: 2, cat: Movies, desc: "Arthouse"}
+      - {id: 3, cat: Movies, desc: "Asian"}
+      - {id: 19, cat: Audio/Audiobook, desc: "Audiobooks"}
+      - {id: 29, cat: Movies, desc: "Badfilm"}
+      - {id: 18, cat: Books, desc: "Books"}
+      - {id: 4, cat: Movies, desc: "Classics"}
+      - {id: 5, cat: Movies, desc: "Comedy"}
+      - {id: 20, cat: Books/Comics, desc: "Comix"}
+      - {id: 6, cat: Movies, desc: "Cult"}
+      - {id: 7, cat: TV/Documentary, desc: "Documentary"}
+      - {id: 8, cat: Movies, desc: "Fantasy & SF"}
+      - {id: 9, cat: Movies, desc: "Horror"}
+      - {id: 22, cat: Movies, desc: "Noir"}
+      - {id: 17, cat: Audio, desc: "OST"}
+      - {id: 10, cat: Other, desc: "Other"}
+      - {id: 15, cat: TV, desc: "Other TV"}
+      - {id: 16, cat: Audio, desc: "Radio"}
+      - {id: 11, cat: Movies, desc: "Silent"}
+      - {id: 12, cat: TV, desc: "Talent Show!"}
+      - {id: 14, cat: Movies, desc: "TV Movies"}
+      - {id: 13, cat: TV, desc: "TV Series"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      returnto: "index.php"
+    test:
+      path: /browse.php
+      selector: div.Userstats
+
+  ratio:
+    path: /browse.php
+    selector: div.Userstats
+    filters:
+      - name: regexp
+        args: "\n\u00a0(.*) \u00a0"
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=on&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      tpp: "100"
+      dirty: "1"
+    rows:
+      selector: td > table[id="large"] > tbody > tr:has(div.browsing)
+      filters:
+        - name: andmatch
+      dateheaders:
+        selector: ":has(td.colhead[title] > b)"
+        filters:
+          - name: dateparse
+            args: "Mon 02 Jan"
+    fields:
+      title:
+        selector: a[href^="viewtopic.php?id="]
+      description:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(2)
+      category:
+        selector: a[href^="browse.php?cat"]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["browse.php?cat", ""]
+          - name: replace
+            args: ["=on", ""]
+      details:
+        selector: a[href^="viewtopic.php?id="]
+        attribute: href      
+      download:
+        selector: a[href^="download.php/"]
+        attribute: href
+      size:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(4)
+      files:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(3)
+        filters:
+        - name: regexp
+          args: "(\\d+)"
+      grabs:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(5)
+        filters:
+        - name: regexp
+          args: "(\\d+)"
+      seeders:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(6)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      leechers:
+        selector: table > tbody > tr:nth-child(2) > td:nth-child(7)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      date:
+        selector: td:nth-child(1) > div > table > tbody > tr:nth-child(2) > td:nth-child(1)
+        filters:
+          - name: replace
+            args: ["'", ""]
+          - name: replace
+            args: ["\xA0", ""]
+          - name: dateparse
+            args: "02 Jan 0615:04"
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/shareisland.yml b/src/Jackett/Definitions/shareisland.yml
index c251b16c9db929e86369604906e9377792eaa758..8f79bbcd892866b6bd309f8c314180576067edb1 100644
--- a/src/Jackett/Definitions/shareisland.yml
+++ b/src/Jackett/Definitions/shareisland.yml
@@ -1,170 +1,170 @@
----
-  site: shareisland
-  name: Shareisland
-  description: "A general italian tracker"
-  language: it-it
-  type: private
-  encoding: UTF-8
-  links:
-    - http://shareisland.org
-
-  caps:
-    categorymappings:
-       - {id: 32, cat: Other, desc: "Vip"}
-       - {id: 45, cat: XXX, desc: "Vip XXX"}
-       - {id: 33, cat: Other, desc: "ex Vip"}
-       - {id: 1, cat: Movies, desc: "Movies"}
-       - {id: 49, cat: Movies/HD, desc: "H-264"}
-       - {id: 51, cat: Movies/HD, desc: "H-265"}
-       - {id: 41, cat: Movies/Other, desc: "Cartoons"}
-       - {id: 14, cat: Movies/SD, desc: "DivX"}
-       - {id: 16, cat: Movies/Other, desc: "Cine News"}
-       - {id: 39, cat: Movies/HD, desc: "720p"}
-       - {id: 40, cat: Movies/HD, desc: "1080p"}
-       - {id: 46, cat: Movies/BluRay, desc: "Blu Ray Disk"}
-       - {id: 31, cat: Movies/HD, desc: "BDRip"}
-       - {id: 17, cat: Movies/DVD, desc: "DVD"}
-       - {id: 43, cat: Movies/SD, desc: "DVDRip"}
-       - {id: 6, cat: PC, desc: "Applications"}
-       - {id: 18, cat: PC/0day, desc: "PC Applications"}
-       - {id: 19, cat: PC/Mac, desc: "Macintosh Applications"}
-       - {id: 44, cat: PC/Phone-Android, desc: "Android applications"}
-       - {id: 7, cat: Audio, desc: "Music"}
-       - {id: 20, cat: Audio/Video, desc: "Video"}
-       - {id: 21, cat: Audio/MP3, desc: "Mp3"}
-       - {id: 2, cat: Console, desc: "Games"}
-       - {id: 3, cat: Console/PS4, desc: "Sony PS"}
-       - {id: 4, cat: Console/Wii, desc: "Wii"}
-       - {id: 26, cat: Console/Xbox, desc: "XboX"}
-       - {id: 27, cat: PC/Games, desc: "PC"}
-       - {id: 28, cat: Console/NDS, desc: "Nintendo"}
-       - {id: 34, cat: Books, desc: "Edicola"}
-       - {id: 52, cat: Books, desc: "Quotidiani"}
-       - {id: 53, cat: Books, desc: "Libreria"}
-       - {id: 35, cat: TV, desc: "SerieTV"}
-       - {id: 55, cat: TV/HD, desc: "Serie Tv HD"}
-       - {id: 36, cat: Other, desc: "Rip By ShareIsland"}
-       - {id: 47, cat: Other, desc: "Disclaimer"}
-       - {id: 48, cat: Other, desc: "P2P network "}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /ajax/login.php
-    method: post
-    form: form
-    inputs:
-      loginbox_membername: "{{ .Config.username }}"
-      loginbox_password: "{{ .Config.password }}"
-      action: "login"
-      loginbox_remember: "true"
-    error:
-      - selector: div.error
-    test:
-      path: /?p=home&pid=1
-      selector: div#member_info_bar
-
-  ratio:
-    path: /?p=home&pid=1
-    selector: img[title="Ratio"] + span
-
-  search:
-    path: /
-    keywordsfilters:
-      # most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
-      - name: re_replace
-        args: ["S0?(\\d{1,2})", " $1 "]
-      - name: re_replace
-        args: ["E(\\d{2,3})", " $1 "]
-      - name: re_replace
-        args: ["[^a-zA-Z0-9]+", "%25"]
-    inputs:
-      p: "torrents"
-      pid: "32"
-      $raw: "{{range .Categories}}cid[]={{.}}&{{end}}"
-      keywords: "{{ .Keywords }}"
-      search_type: "name"
-      searchin: "title"
-
-    rows:
-      selector: table#torrents_table_classic > tbody > tr:not([id="torrents_table_classic_head"])
-      filters:
-        - name: andmatch
-    fields:
-      title:
-        selector: td.torrent_name > a
-        filters:
-          # normalize to SXXEYY format
-          - name: re_replace
-            args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
-          - name: re_replace
-            args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
-      category:
-        selector: div.category_image > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: cid
-      comments:
-        selector: td.torrent_name > a
-        attribute: href
-      download:
-        selector: a:has(img[title="Download Torrent"])
-        attribute: href
-      size:
-        selector: td.size
-      seeders:
-        selector: td.seeders
-      leechers:
-        selector: td.leechers
-      grabs:
-        selector: td.completed
-      downloadvolumefactor:
-        case:
-          "img[title=\"FREE!\"]": "0"
-          "img[title=\"Download Multiplier: 0.5\"]": "0.5"
-          "img[title=\"Moltiplicatore Download: 0.5\"]": "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "img[title=\"Upload Multiplier: 3\"]": "3"
-          "img[title=\"Upload Multiplier: 2\"]": "2"
-          "img[title=\"Upload Multiplier: 1.5\"]": "1.5"
-          "img[title=\"Moltiplicatore Upload: 3\"]": "3"
-          "img[title=\"Moltiplicatore Upload: 2\"]": "2"
-          "img[title=\"Moltiplicatore Upload: 1.5\"]": "1.5"
-          "*": "1"
-      date:
-        selector: td.torrent_name
-        remove: a, span, div, br
-        filters:
-          - name: replace
-            args: ["Uploaded ", ""]
-          - name: replace
-            args: [" by", ""]
-          - name: replace
-            args: [" at", ""]
-          - name: replace
-            args: ["Oggi", "Today"]
-          - name: replace
-            args: ["Ieri", "Yesterday"]
-          - name: replace
-            args: ["lunedì", "Monday"]
-          - name: replace
-            args: ["martedì", "Tuesday"]
-          - name: replace
-            args: ["Mercoledì", "Wednesday"]
-          - name: replace
-            args: ["Giovedì", "Thursday"]
-          - name: replace
-            args: ["Venerdì", "Friday"]
-          - name: replace
-            args: ["Sabato", "Saturday"]
-          - name: replace
-            args: ["Domenica", "Sunday"]
-          - name: replace
-            args: [" alle", ""]
-          - name: dateparse
-            args: "02-01-2006 15:04"
+---
+  site: shareisland
+  name: Shareisland
+  description: "A general italian tracker"
+  language: it-it
+  type: private
+  encoding: UTF-8
+  links:
+    - http://shareisland.org
+
+  caps:
+    categorymappings:
+       - {id: 32, cat: Other, desc: "Vip"}
+       - {id: 45, cat: XXX, desc: "Vip XXX"}
+       - {id: 33, cat: Other, desc: "ex Vip"}
+       - {id: 1, cat: Movies, desc: "Movies"}
+       - {id: 49, cat: Movies/HD, desc: "H-264"}
+       - {id: 51, cat: Movies/HD, desc: "H-265"}
+       - {id: 41, cat: Movies/Other, desc: "Cartoons"}
+       - {id: 14, cat: Movies/SD, desc: "DivX"}
+       - {id: 16, cat: Movies/Other, desc: "Cine News"}
+       - {id: 39, cat: Movies/HD, desc: "720p"}
+       - {id: 40, cat: Movies/HD, desc: "1080p"}
+       - {id: 46, cat: Movies/BluRay, desc: "Blu Ray Disk"}
+       - {id: 31, cat: Movies/HD, desc: "BDRip"}
+       - {id: 17, cat: Movies/DVD, desc: "DVD"}
+       - {id: 43, cat: Movies/SD, desc: "DVDRip"}
+       - {id: 6, cat: PC, desc: "Applications"}
+       - {id: 18, cat: PC/0day, desc: "PC Applications"}
+       - {id: 19, cat: PC/Mac, desc: "Macintosh Applications"}
+       - {id: 44, cat: PC/Phone-Android, desc: "Android applications"}
+       - {id: 7, cat: Audio, desc: "Music"}
+       - {id: 20, cat: Audio/Video, desc: "Video"}
+       - {id: 21, cat: Audio/MP3, desc: "Mp3"}
+       - {id: 2, cat: Console, desc: "Games"}
+       - {id: 3, cat: Console/PS4, desc: "Sony PS"}
+       - {id: 4, cat: Console/Wii, desc: "Wii"}
+       - {id: 26, cat: Console/Xbox, desc: "XboX"}
+       - {id: 27, cat: PC/Games, desc: "PC"}
+       - {id: 28, cat: Console/NDS, desc: "Nintendo"}
+       - {id: 34, cat: Books, desc: "Edicola"}
+       - {id: 52, cat: Books, desc: "Quotidiani"}
+       - {id: 53, cat: Books, desc: "Libreria"}
+       - {id: 35, cat: TV, desc: "SerieTV"}
+       - {id: 55, cat: TV/HD, desc: "Serie Tv HD"}
+       - {id: 36, cat: Other, desc: "Rip By ShareIsland"}
+       - {id: 47, cat: Other, desc: "Disclaimer"}
+       - {id: 48, cat: Other, desc: "P2P network "}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /ajax/login.php
+    method: post
+    form: form
+    inputs:
+      loginbox_membername: "{{ .Config.username }}"
+      loginbox_password: "{{ .Config.password }}"
+      action: "login"
+      loginbox_remember: "true"
+    error:
+      - selector: div.error
+    test:
+      path: /?p=home&pid=1
+      selector: div#member_info_bar
+
+  ratio:
+    path: /?p=home&pid=1
+    selector: img[title="Ratio"] + span
+
+  search:
+    path: /
+    keywordsfilters:
+      # most ITA TV torrents are in XXxYY format, so we search without S/E prefixes and filter later
+      - name: re_replace
+        args: ["S0?(\\d{1,2})", " $1 "]
+      - name: re_replace
+        args: ["E(\\d{2,3})", " $1 "]
+      - name: re_replace
+        args: ["[^a-zA-Z0-9]+", "%25"]
+    inputs:
+      p: "torrents"
+      pid: "32"
+      $raw: "{{range .Categories}}cid[]={{.}}&{{end}}"
+      keywords: "{{ .Keywords }}"
+      search_type: "name"
+      searchin: "title"
+
+    rows:
+      selector: table#torrents_table_classic > tbody > tr:not([id="torrents_table_classic_head"])
+      filters:
+        - name: andmatch
+    fields:
+      title:
+        selector: td.torrent_name > a
+        filters:
+          # normalize to SXXEYY format
+          - name: re_replace
+            args: ["(\\d{2})x(\\d{2})", "S$1E$2"]
+          - name: re_replace
+            args: ["(\\d{1})x(\\d{2})", "S0$1E$2"]
+      category:
+        selector: div.category_image > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: cid
+      comments:
+        selector: td.torrent_name > a
+        attribute: href
+      download:
+        selector: a:has(img[title="Download Torrent"])
+        attribute: href
+      size:
+        selector: td.size
+      seeders:
+        selector: td.seeders
+      leechers:
+        selector: td.leechers
+      grabs:
+        selector: td.completed
+      downloadvolumefactor:
+        case:
+          "img[title=\"FREE!\"]": "0"
+          "img[title=\"Download Multiplier: 0.5\"]": "0.5"
+          "img[title=\"Moltiplicatore Download: 0.5\"]": "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "img[title=\"Upload Multiplier: 3\"]": "3"
+          "img[title=\"Upload Multiplier: 2\"]": "2"
+          "img[title=\"Upload Multiplier: 1.5\"]": "1.5"
+          "img[title=\"Moltiplicatore Upload: 3\"]": "3"
+          "img[title=\"Moltiplicatore Upload: 2\"]": "2"
+          "img[title=\"Moltiplicatore Upload: 1.5\"]": "1.5"
+          "*": "1"
+      date:
+        selector: td.torrent_name
+        remove: a, span, div, br
+        filters:
+          - name: replace
+            args: ["Uploaded ", ""]
+          - name: replace
+            args: [" by", ""]
+          - name: replace
+            args: [" at", ""]
+          - name: replace
+            args: ["Oggi", "Today"]
+          - name: replace
+            args: ["Ieri", "Yesterday"]
+          - name: replace
+            args: ["lunedì", "Monday"]
+          - name: replace
+            args: ["martedì", "Tuesday"]
+          - name: replace
+            args: ["Mercoledì", "Wednesday"]
+          - name: replace
+            args: ["Giovedì", "Thursday"]
+          - name: replace
+            args: ["Venerdì", "Friday"]
+          - name: replace
+            args: ["Sabato", "Saturday"]
+          - name: replace
+            args: ["Domenica", "Sunday"]
+          - name: replace
+            args: [" alle", ""]
+          - name: dateparse
+            args: "02-01-2006 15:04"
diff --git a/src/Jackett/Definitions/sharespacedb.yml b/src/Jackett/Definitions/sharespacedb.yml
index c86af3f0a28e28da490e2f10df34271bb3f997ba..5039424b701949fee2943f11facca1816a45e08b 100644
--- a/src/Jackett/Definitions/sharespacedb.yml
+++ b/src/Jackett/Definitions/sharespacedb.yml
@@ -1,156 +1,156 @@
----
-  site: sharespacedb
-  name: ShareSpaceDB
-  description: "A French gerneral tracker"
-  language: fr-fr
-  type: private
-  encoding: UTF-8
-  links:
-    - https://ssdb.me/
-
-  caps:
-    categorymappings:
-      - {id: 50, cat: TV/Anime, desc: "Anime: Tout"}
-      - {id: 40, cat: PC, desc: "Apps: Windows"}
-      - {id: 41, cat: PC/Mac, desc: "Apps: Mac"}
-      - {id: 42, cat: PC/Phone-Android, desc: "Apps: Android"}
-      - {id: 43, cat: PC/Phone-IOS, desc: "Apps: Ipod/Iphone"}
-      - {id: 44, cat: PC, desc: "Apps: Autres"}
-      - {id: 45, cat: PC, desc: "Apps: Linux"}
-      - {id: 27, cat: Books, desc: "E-Books: Livres"}
-      - {id: 28, cat: Books, desc: "E-Books: Audio"}
-      - {id: 29, cat: Books/Comics, desc: "E-Books: Comics"}
-      - {id: 30, cat: Books, desc: "E-Books: Mangas"}
-      - {id: 32, cat: Books, desc: "E-Books: Bds"}
-      - {id: 31, cat: Books, desc: "E-Books: Presse"}
-      - {id: 63, cat: Books, desc: "E-Books: ePUB"}
-      - {id: 1, cat: Movies/SD, desc: "Films: DVDRip"}
-      - {id: 2, cat: Movies/SD, desc: "Films: DVDRip VOSTFR"}
-      - {id: 3, cat: Movies/DVD, desc: "Films: DVD-R"}
-      - {id: 4, cat: Movies/HD, desc: "Films: 720p"}
-      - {id: 5, cat: Movies/HD, desc: "Films: 1080p"}
-      - {id: 6, cat: Movies/BluRay, desc: "Films: BluRay x264 et x265"}
-      - {id: 7, cat: Movies/3D, desc: "Films: BluRay-3D"}
-      - {id: 11, cat: Movies/HD, desc: "Films: BDRip"}
-      - {id: 9, cat: Movies/DVD, desc: "Films: R5"}
-      - {id: 10, cat: Movies/SD, desc: "Films: DVDSCR"}
-      - {id: 56, cat: Movies/HD, desc: "Films: mHD"}
-      - {id: 12, cat: Movies/HD, desc: "Films: BRRip"}
-      - {id: 13, cat: Movies/HD, desc: "Films: WEBRip"}
-      - {id: 58, cat: Movies/HD, desc: "Films: WEBRip 720p"}
-      - {id: 59, cat: Movies/HD, desc: "Films: WEBRip 1080p"}
-      - {id: 8, cat: Movies/SD, desc: "Films: Cam / TS"}
-      - {id: 62, cat: Movies/HD, desc: "Films: Uhd4k"}
-      - {id: 35, cat: Console/Xbox, desc: "Jeux: XBOX"}
-      - {id: 36, cat: Console/Wii, desc: "Jeux: WII"}
-      - {id: 37, cat: Console/PSP, desc: "Jeux: PSP"}
-      - {id: 38, cat: Console/NDS, desc: "Jeux: DS"}
-      - {id: 39, cat: PC/Phone-Android, desc: "Jeux: Android"}
-      - {id: 34, cat: Console/PS3, desc: "Jeux: PS3"}
-      - {id: 55, cat: PC/Mac, desc: "Jeux: Mac"}
-      - {id: 33, cat: PC/Games, desc: "Jeux: PC"}
-      - {id: 46, cat: Audio/MP3, desc: "Musiques: MP3"}
-      - {id: 47, cat: Audio/Lossless, desc: "Musiques: FLAC"}
-      - {id: 48, cat: Audio, desc: "Musiques: WMA"}
-      - {id: 49, cat: Audio, desc: "Musiques: Autres"}
-      - {id: 14, cat: TV/SD, desc: "Series: HDTV"}
-      - {id: 15, cat: TV, desc: "Series: TV VOSTFR"}
-      - {id: 16, cat: TV, desc: "Series: TV VOSTA"}
-      - {id: 17, cat: TV, desc: "Series: TV PACK"}
-      - {id: 18, cat: TV/HD, desc: "Series: HDTV 1080p"}
-      - {id: 57, cat: TV/HD, desc: "Series: TVHD VOSTFR"}
-      - {id: 20, cat: TV, desc: "Series: TV VO"}
-      - {id: 19, cat: TV/HD, desc: "Series: HDTV 720p"}
-      - {id: 64, cat: TV/SD, desc: "Series: WEBRip"}
-      - {id: 60, cat: TV/HD, desc: "Series: WEBRip 720p"}
-      - {id: 61, cat: TV/HD, desc: "Series: WEBRip 1080p"}
-      - {id: 21, cat: TV/SD, desc: "Series: DVD-R TV"}
-      - {id: 26, cat: TV, desc: "Television: Television"}
-      - {id: 24, cat: TV, desc: "Television: Spectacles"}
-      - {id: 23, cat: TV/Sport, desc: "Television: Sports"}
-      - {id: 25, cat: TV/Anime, desc: "Television: Animes"}
-      - {id: 22, cat: TV/Documentary, desc: "Television: Documentaires"}
-      - {id: 51, cat: XXX, desc: "XXX: Tous"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: account-login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      remember: "yes"
-      returnto: "/"
-    error:
-    - selector: div#nfobar > p#msgError
-    test:
-      path: torrents-search.php
-
-  ratio:
-    path: torrents-search.php
-    selector: div#infobar0 > ul > li:nth-child(1) > font:last-child
-
-  search:
-    path: torrents-search.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-
-    rows:
-      selector: table.ttable_headinner > tbody > tr.t-row
-      filters:
-        - name: andmatch
-      after: 1
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="torrents.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-      comments:
-        selector: a[href^="comments.php"]
-        attribute: href
-      banner:
-        selector: a[onmouseover][href^="torrents-details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: <td align=left><img src=(.*?) width
-      size:
-        selector: td:nth-child(7)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      date:
-        selector: small > i
-        filters:
-          - name: replace
-            args: ["Date: ", ""]
-          - name: replace
-            args: ["le ", ""]
-          - name: dateparse
-            args: "15:04:05 02-01-2006"
-      downloadvolumefactor:
-        case:
-          img[src="images/free.gif"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: sharespacedb
+  name: ShareSpaceDB
+  description: "A French gerneral tracker"
+  language: fr-fr
+  type: private
+  encoding: UTF-8
+  links:
+    - https://ssdb.me/
+
+  caps:
+    categorymappings:
+      - {id: 50, cat: TV/Anime, desc: "Anime: Tout"}
+      - {id: 40, cat: PC, desc: "Apps: Windows"}
+      - {id: 41, cat: PC/Mac, desc: "Apps: Mac"}
+      - {id: 42, cat: PC/Phone-Android, desc: "Apps: Android"}
+      - {id: 43, cat: PC/Phone-IOS, desc: "Apps: Ipod/Iphone"}
+      - {id: 44, cat: PC, desc: "Apps: Autres"}
+      - {id: 45, cat: PC, desc: "Apps: Linux"}
+      - {id: 27, cat: Books, desc: "E-Books: Livres"}
+      - {id: 28, cat: Books, desc: "E-Books: Audio"}
+      - {id: 29, cat: Books/Comics, desc: "E-Books: Comics"}
+      - {id: 30, cat: Books, desc: "E-Books: Mangas"}
+      - {id: 32, cat: Books, desc: "E-Books: Bds"}
+      - {id: 31, cat: Books, desc: "E-Books: Presse"}
+      - {id: 63, cat: Books, desc: "E-Books: ePUB"}
+      - {id: 1, cat: Movies/SD, desc: "Films: DVDRip"}
+      - {id: 2, cat: Movies/SD, desc: "Films: DVDRip VOSTFR"}
+      - {id: 3, cat: Movies/DVD, desc: "Films: DVD-R"}
+      - {id: 4, cat: Movies/HD, desc: "Films: 720p"}
+      - {id: 5, cat: Movies/HD, desc: "Films: 1080p"}
+      - {id: 6, cat: Movies/BluRay, desc: "Films: BluRay x264 et x265"}
+      - {id: 7, cat: Movies/3D, desc: "Films: BluRay-3D"}
+      - {id: 11, cat: Movies/HD, desc: "Films: BDRip"}
+      - {id: 9, cat: Movies/DVD, desc: "Films: R5"}
+      - {id: 10, cat: Movies/SD, desc: "Films: DVDSCR"}
+      - {id: 56, cat: Movies/HD, desc: "Films: mHD"}
+      - {id: 12, cat: Movies/HD, desc: "Films: BRRip"}
+      - {id: 13, cat: Movies/HD, desc: "Films: WEBRip"}
+      - {id: 58, cat: Movies/HD, desc: "Films: WEBRip 720p"}
+      - {id: 59, cat: Movies/HD, desc: "Films: WEBRip 1080p"}
+      - {id: 8, cat: Movies/SD, desc: "Films: Cam / TS"}
+      - {id: 62, cat: Movies/HD, desc: "Films: Uhd4k"}
+      - {id: 35, cat: Console/Xbox, desc: "Jeux: XBOX"}
+      - {id: 36, cat: Console/Wii, desc: "Jeux: WII"}
+      - {id: 37, cat: Console/PSP, desc: "Jeux: PSP"}
+      - {id: 38, cat: Console/NDS, desc: "Jeux: DS"}
+      - {id: 39, cat: PC/Phone-Android, desc: "Jeux: Android"}
+      - {id: 34, cat: Console/PS3, desc: "Jeux: PS3"}
+      - {id: 55, cat: PC/Mac, desc: "Jeux: Mac"}
+      - {id: 33, cat: PC/Games, desc: "Jeux: PC"}
+      - {id: 46, cat: Audio/MP3, desc: "Musiques: MP3"}
+      - {id: 47, cat: Audio/Lossless, desc: "Musiques: FLAC"}
+      - {id: 48, cat: Audio, desc: "Musiques: WMA"}
+      - {id: 49, cat: Audio, desc: "Musiques: Autres"}
+      - {id: 14, cat: TV/SD, desc: "Series: HDTV"}
+      - {id: 15, cat: TV, desc: "Series: TV VOSTFR"}
+      - {id: 16, cat: TV, desc: "Series: TV VOSTA"}
+      - {id: 17, cat: TV, desc: "Series: TV PACK"}
+      - {id: 18, cat: TV/HD, desc: "Series: HDTV 1080p"}
+      - {id: 57, cat: TV/HD, desc: "Series: TVHD VOSTFR"}
+      - {id: 20, cat: TV, desc: "Series: TV VO"}
+      - {id: 19, cat: TV/HD, desc: "Series: HDTV 720p"}
+      - {id: 64, cat: TV/SD, desc: "Series: WEBRip"}
+      - {id: 60, cat: TV/HD, desc: "Series: WEBRip 720p"}
+      - {id: 61, cat: TV/HD, desc: "Series: WEBRip 1080p"}
+      - {id: 21, cat: TV/SD, desc: "Series: DVD-R TV"}
+      - {id: 26, cat: TV, desc: "Television: Television"}
+      - {id: 24, cat: TV, desc: "Television: Spectacles"}
+      - {id: 23, cat: TV/Sport, desc: "Television: Sports"}
+      - {id: 25, cat: TV/Anime, desc: "Television: Animes"}
+      - {id: 22, cat: TV/Documentary, desc: "Television: Documentaires"}
+      - {id: 51, cat: XXX, desc: "XXX: Tous"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: account-login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      remember: "yes"
+      returnto: "/"
+    error:
+    - selector: div#nfobar > p#msgError
+    test:
+      path: torrents-search.php
+
+  ratio:
+    path: torrents-search.php
+    selector: div#infobar0 > ul > li:nth-child(1) > font:last-child
+
+  search:
+    path: torrents-search.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+
+    rows:
+      selector: table.ttable_headinner > tbody > tr.t-row
+      filters:
+        - name: andmatch
+      after: 1
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="torrents.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+      comments:
+        selector: a[href^="comments.php"]
+        attribute: href
+      banner:
+        selector: a[onmouseover][href^="torrents-details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: <td align=left><img src=(.*?) width
+      size:
+        selector: td:nth-child(7)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      date:
+        selector: small > i
+        filters:
+          - name: replace
+            args: ["Date: ", ""]
+          - name: replace
+            args: ["le ", ""]
+          - name: dateparse
+            args: "15:04:05 02-01-2006"
+      downloadvolumefactor:
+        case:
+          img[src="images/free.gif"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/shellife.yml b/src/Jackett/Definitions/shellife.yml
index 4f49e7fab2caf3110336890cf2a264564a17fbe0..0b091e93f27d1409aafcd7d911d5f10fa17de2be 100644
--- a/src/Jackett/Definitions/shellife.yml
+++ b/src/Jackett/Definitions/shellife.yml
@@ -1,81 +1,81 @@
----
-  site: shellife
-  name: Shellife
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://shellife.eu/
-
-  caps:
-    categories:
-      1: Audio
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td:has(h2:contains("failed"))
-    test:
-      path: browse.php
-
-  search:
-    path: browse.php
-    inputs:
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: table#ct > tbody > tr.torrent_row
-      filters:
-        - name: andmatch
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: a.altlink
-      title|append|1:
-        text: " - "
-      title|append|2:
-        selector: a[name]
-      details:
-        selector: a[name]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["#", "/details.php?id="]
-      category:
-        text: 1
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      grabs:
-        selector: td:nth-child(6)
-      size:
-        selector: td:nth-child(5)
-      downloadvolumefactor:
-        case:
-          img[alt="Freeleech"]: "0"
-          img[alt="Free"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a.altlink, a[name], div[id^="news"]
-        filters:
-          - name: trim
-            args: "-"
-          - name: trim
-            args: " "
-          
+---
+  site: shellife
+  name: Shellife
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://shellife.eu/
+
+  caps:
+    categories:
+      1: Audio
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td:has(h2:contains("failed"))
+    test:
+      path: browse.php
+
+  search:
+    path: browse.php
+    inputs:
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: table#ct > tbody > tr.torrent_row
+      filters:
+        - name: andmatch
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: a.altlink
+      title|append|1:
+        text: " - "
+      title|append|2:
+        selector: a[name]
+      details:
+        selector: a[name]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["#", "/details.php?id="]
+      category:
+        text: 1
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      grabs:
+        selector: td:nth-child(6)
+      size:
+        selector: td:nth-child(5)
+      downloadvolumefactor:
+        case:
+          img[alt="Freeleech"]: "0"
+          img[alt="Free"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a.altlink, a[name], div[id^="news"]
+        filters:
+          - name: trim
+            args: "-"
+          - name: trim
+            args: " "
+          
       
\ No newline at end of file
diff --git a/src/Jackett/Definitions/skytorrents.yml b/src/Jackett/Definitions/skytorrents.yml
index d038155d979dd56e5c84d84474fb2a7ee5da8a32..c422dd4e12bb4bfa8f7bd66817ad107e390f23cb 100644
--- a/src/Jackett/Definitions/skytorrents.yml
+++ b/src/Jackett/Definitions/skytorrents.yml
@@ -1,58 +1,58 @@
----
-  site: skytorrents
-  name: Sky torrents
-  language: en-us
-  type: public
-  encoding: UTF-8
-  links:
-    - https://www.skytorrents.in/
-
-  caps:
-    categories:
-      TV: TV
-      Movies: Movies
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  settings: []
-  
-  search:
-    path: "search/all/{{if .Query.Keywords}}ed{{else}}ad{{end}}/1/{{ .Query.Keywords}}"
-    rows:
-      selector: "table > tbody > tr"
-      filters:
-        - name: andmatch
-    fields:
-      title:
-        selector: td:nth-child(1) > a:first-child[title]
-        attribute: title
-      details:
-        selector: td:nth-child(1) > a:first-child
-        attribute: href
-      size:
-        selector: td:nth-child(2)
-      files:
-        selector: td:nth-child(3)
-      seeders:
-        selector: td:nth-child(5)
-      leechers:
-        selector: td:nth-child(6)
-      description:
-        selector: td:nth-child(1)
-        case:
-          img[title="Verified and marked"]: "Verified and marked"
-          "*": ""
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: dateparse
-            args: "01-02-2006"
-      download:
-        selector: td > a[href^="/file"]
-        attribute: href
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
+---
+  site: skytorrents
+  name: Sky torrents
+  language: en-us
+  type: public
+  encoding: UTF-8
+  links:
+    - https://www.skytorrents.in/
+
+  caps:
+    categories:
+      TV: TV
+      Movies: Movies
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  settings: []
+  
+  search:
+    path: "search/all/{{if .Query.Keywords}}ed{{else}}ad{{end}}/1/{{ .Query.Keywords}}"
+    rows:
+      selector: "table > tbody > tr"
+      filters:
+        - name: andmatch
+    fields:
+      title:
+        selector: td:nth-child(1) > a:first-child[title]
+        attribute: title
+      details:
+        selector: td:nth-child(1) > a:first-child
+        attribute: href
+      size:
+        selector: td:nth-child(2)
+      files:
+        selector: td:nth-child(3)
+      seeders:
+        selector: td:nth-child(5)
+      leechers:
+        selector: td:nth-child(6)
+      description:
+        selector: td:nth-child(1)
+        case:
+          img[title="Verified and marked"]: "Verified and marked"
+          "*": ""
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: dateparse
+            args: "01-02-2006"
+      download:
+        selector: td > a[href^="/file"]
+        attribute: href
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
         text: "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/tasmanit.yml b/src/Jackett/Definitions/tasmanit.yml
index 3f615056de30c6c48fbb2155f75111806623d6fb..87e7df866e1ed6cbec6c789ed1d33df834d8e780 100755
--- a/src/Jackett/Definitions/tasmanit.yml
+++ b/src/Jackett/Definitions/tasmanit.yml
@@ -1,109 +1,109 @@
----
-  site: tasmanit
-  name: Tasmanit
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://tasmanit.es
-
-  caps:
-    categorymappings:
-      - {id: 72, cat: TV, desc: "All Australian TV"}
-      - {id: 23, cat: TV, desc: "AU-AUTOGEN"}
-      - {id: 8, cat: TV, desc: "Australian Comedy"}
-      - {id: 18, cat: TV, desc: "Australian Crime Shows"}
-      - {id: 14, cat: TV, desc: "Australian Documentaries"}
-      - {id: 9, cat: TV, desc: "Australian Dramas"}
-      - {id: 10, cat: TV, desc: "Australian Game/Quiz Shows"}
-      - {id: 12, cat: TV, desc: "Australian Kids Shows"}
-      - {id: 21, cat: TV, desc: "Australian Lifestyle TV"}
-      - {id: 11, cat: TV, desc: "Aussie News and Current Affairs"}
-      - {id: 76, cat: TV/Other, desc: "Australian TV Other"}
-      - {id: 15, cat: TV, desc: "Australian Real Crime"}
-      - {id: 13, cat: TV, desc: "Australian Reality TV"}
-      - {id: 17, cat: TV, desc: "Australian Science Shows"}
-      - {id: 80, cat: TV, desc: "Australian Soaps"}
-      - {id: 16, cat: TV, desc: "Australian Talkshows"}
-      - {id: 22, cat: TV, desc: "Australian Movies"}
-      - {id: 73, cat: TV, desc: "New Zealand TV"}
-      - {id: 61, cat: TV, desc: "NZ-AUTOGEN"}
-      - {id: 47, cat: TV, desc: "New Zealand Comedy"}
-      - {id: 58, cat: TV, desc: "New Zealand Crime Shows"}
-      - {id: 53, cat: TV, desc: "New Zealand Documentaries"}
-      - {id: 48, cat: TV, desc: "New Zealand Dramas"}
-      - {id: 49, cat: TV, desc: "New Zealand Game/Quiz Shows"}
-      - {id: 51, cat: TV, desc: "New Zealand Kids Shows"}
-      - {id: 56, cat: TV, desc: "New Zealand Lifestyle TV"}
-      - {id: 50, cat: TV, desc: "New Zealand News and Current Affairs"}
-      - {id: 60, cat: TV, desc: "New Zealand Real Crime"}
-      - {id: 52, cat: TV, desc: "New Zealand Reality TV"}
-      - {id: 54, cat: TV, desc: "New Zealand Science Shows"}
-      - {id: 81, cat: TV, desc: "New Zealand Soaps"}
-      - {id: 57, cat: TV, desc: "New Zealand Talkshows"}
-      - {id: 59, cat: TV, desc: "New Zealand Movies"}
-      - {id: 36, cat: TV, desc: "New Zealand TV"}
-      - {id: 55, cat: TV, desc: "SATV - All"}
-      - {id: 55, cat: TV, desc: "South African TV"}
-      - {id: 7, cat: TV/Other, desc: "New Zealand TV Other"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: form
-    form: form[action="takelogin.php"]
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div#content:has(h2:contains("Login Failed"))
-    test:
-      path: browse.php
-
-  search:
-    path: browse.php
-    method: post
-    inputs:
-      do: "search"
-      keywords: "{{ .Keywords }}"
-      search_type: "t_name"
-      include_dead_torrents: "yes"
-    rows:
-      selector: table#sortabletable > tbody > tr:has(a[href])
-    fields:
-      title:
-        selector: td:nth-child(2) a
-      category:
-        selector: a[href^="https://tasmanit.es/browse.php?category="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: category
-      details:
-        selector: a[href^="https://tasmanit.es/details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="https://tasmanit.es/details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php", "download.php"]
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      date:
-        selector: td:nth-child(2)
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: tasmanit
+  name: Tasmanit
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://tasmanit.es
+
+  caps:
+    categorymappings:
+      - {id: 72, cat: TV, desc: "All Australian TV"}
+      - {id: 23, cat: TV, desc: "AU-AUTOGEN"}
+      - {id: 8, cat: TV, desc: "Australian Comedy"}
+      - {id: 18, cat: TV, desc: "Australian Crime Shows"}
+      - {id: 14, cat: TV, desc: "Australian Documentaries"}
+      - {id: 9, cat: TV, desc: "Australian Dramas"}
+      - {id: 10, cat: TV, desc: "Australian Game/Quiz Shows"}
+      - {id: 12, cat: TV, desc: "Australian Kids Shows"}
+      - {id: 21, cat: TV, desc: "Australian Lifestyle TV"}
+      - {id: 11, cat: TV, desc: "Aussie News and Current Affairs"}
+      - {id: 76, cat: TV/Other, desc: "Australian TV Other"}
+      - {id: 15, cat: TV, desc: "Australian Real Crime"}
+      - {id: 13, cat: TV, desc: "Australian Reality TV"}
+      - {id: 17, cat: TV, desc: "Australian Science Shows"}
+      - {id: 80, cat: TV, desc: "Australian Soaps"}
+      - {id: 16, cat: TV, desc: "Australian Talkshows"}
+      - {id: 22, cat: TV, desc: "Australian Movies"}
+      - {id: 73, cat: TV, desc: "New Zealand TV"}
+      - {id: 61, cat: TV, desc: "NZ-AUTOGEN"}
+      - {id: 47, cat: TV, desc: "New Zealand Comedy"}
+      - {id: 58, cat: TV, desc: "New Zealand Crime Shows"}
+      - {id: 53, cat: TV, desc: "New Zealand Documentaries"}
+      - {id: 48, cat: TV, desc: "New Zealand Dramas"}
+      - {id: 49, cat: TV, desc: "New Zealand Game/Quiz Shows"}
+      - {id: 51, cat: TV, desc: "New Zealand Kids Shows"}
+      - {id: 56, cat: TV, desc: "New Zealand Lifestyle TV"}
+      - {id: 50, cat: TV, desc: "New Zealand News and Current Affairs"}
+      - {id: 60, cat: TV, desc: "New Zealand Real Crime"}
+      - {id: 52, cat: TV, desc: "New Zealand Reality TV"}
+      - {id: 54, cat: TV, desc: "New Zealand Science Shows"}
+      - {id: 81, cat: TV, desc: "New Zealand Soaps"}
+      - {id: 57, cat: TV, desc: "New Zealand Talkshows"}
+      - {id: 59, cat: TV, desc: "New Zealand Movies"}
+      - {id: 36, cat: TV, desc: "New Zealand TV"}
+      - {id: 55, cat: TV, desc: "SATV - All"}
+      - {id: 55, cat: TV, desc: "South African TV"}
+      - {id: 7, cat: TV/Other, desc: "New Zealand TV Other"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: form
+    form: form[action="takelogin.php"]
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div#content:has(h2:contains("Login Failed"))
+    test:
+      path: browse.php
+
+  search:
+    path: browse.php
+    method: post
+    inputs:
+      do: "search"
+      keywords: "{{ .Keywords }}"
+      search_type: "t_name"
+      include_dead_torrents: "yes"
+    rows:
+      selector: table#sortabletable > tbody > tr:has(a[href])
+    fields:
+      title:
+        selector: td:nth-child(2) a
+      category:
+        selector: a[href^="https://tasmanit.es/browse.php?category="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: category
+      details:
+        selector: a[href^="https://tasmanit.es/details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="https://tasmanit.es/details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php", "download.php"]
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      date:
+        selector: td:nth-child(2)
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/tenyardtracker.yml b/src/Jackett/Definitions/tenyardtracker.yml
index 07ff6f7136e1c84089b001a818505e80f8546849..ebbdcd3a7d11e6a100ee4d250a741d7fe40bb389 100644
--- a/src/Jackett/Definitions/tenyardtracker.yml
+++ b/src/Jackett/Definitions/tenyardtracker.yml
@@ -1,74 +1,74 @@
----
-  site: tenyardtracker
-  name: TenYardTracker
-  description: "An American football tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://tenyardtracker.com/
-
-  caps:
-    categories:
-      1: TV # Sports
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: members.php?action=takelogin
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div:contains("Login Failed")
-    test:
-      path: my.php
-    #error:
-      #- path: members.php?action=takelogin
-    test:
-      path: my.php
-      #selector: a[href="members.php?action=logout"]
-      
-  ratio:
-    path: browse.php
-    selector: #status_bar
-
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table[border="1"] tr:not(:first-child)
-    fields:
-      category:
-        text: 1
-      title:
-        selector: td:nth-child(2)
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?torrent="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(5)
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: tenyardtracker
+  name: TenYardTracker
+  description: "An American football tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://tenyardtracker.com/
+
+  caps:
+    categories:
+      1: TV # Sports
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: members.php?action=takelogin
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div:contains("Login Failed")
+    test:
+      path: my.php
+    #error:
+      #- path: members.php?action=takelogin
+    test:
+      path: my.php
+      #selector: a[href="members.php?action=logout"]
+      
+  ratio:
+    path: browse.php
+    selector: #status_bar
+
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table[border="1"] tr:not(:first-child)
+    fields:
+      category:
+        text: 1
+      title:
+        selector: td:nth-child(2)
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?torrent="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(5)
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/theempire.yml b/src/Jackett/Definitions/theempire.yml
index 35310c0c543cad2dba4aa6f4ea0e1ffef085f15a..2dbc5c2c36ec7584e5e7f5c8a354a7b6fdadb6c8 100644
--- a/src/Jackett/Definitions/theempire.yml
+++ b/src/Jackett/Definitions/theempire.yml
@@ -1,121 +1,121 @@
----
-  site: theempire
-  name: The Empire
-  description: "Commonwealth television"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.theempire.bz/
-
-  caps:
-    categorymappings:
-      - {id: 55, cat: TV, desc: "Adverts"}
-      - {id: 60, cat: TV, desc: "Educational"}
-      - {id: 63, cat: TV, desc: "Game Shows"}
-      - {id: 67, cat: TV, desc: "Music"}
-      - {id: 72, cat: TV, desc: "QuizComedy"}
-      - {id: 77, cat: TV, desc: "Special Events"}
-      - {id: 81, cat: TV, desc: "Trains & Planes"}
-      - {id: 54, cat: TV, desc: "Arts & Culture"}
-      - {id: 61, cat: TV, desc: "Entertainment"}
-      - {id: 53, cat: TV, desc: "Gardening"}
-      - {id: 68, cat: TV, desc: "Mystery & Crime Fiction"}
-      - {id: 73, cat: TV, desc: "Radio"}
-      - {id: 78, cat: TV, desc: "Special Interest"}
-      - {id: 82, cat: TV, desc: "Travel"}
-      - {id: 56, cat: TV, desc: "Comedy"}
-      - {id: 85, cat: TV, desc: "Euro-Noir"}
-      - {id: 64, cat: TV, desc: "Kids"}
-      - {id: 69, cat: TV, desc: "News"}
-      - {id: 74, cat: TV, desc: "Reality"}
-      - {id: 79, cat: TV, desc: "Sport"}
-      - {id: 83, cat: TV, desc: "Wildlife & Nature"}
-      - {id: 58, cat: TV, desc: "Documentary"}
-      - {id: 57, cat: TV, desc: "Fly on the Wall/Lifestyle"}
-      - {id: 65, cat: TV, desc: "Magazine"}
-      - {id: 70, cat: TV, desc: "Occult & Horror"}
-      - {id: 75, cat: TV, desc: "Sci-Fi"}
-      - {id: 84, cat: TV, desc: "Style & Fashion"}
-      - {id: 62, cat: TV, desc: "Food Drink & Cooking"}
-      - {id: 66, cat: TV, desc: "Motoring"}
-      - {id: 71, cat: TV, desc: "Property"}
-      - {id: 76, cat: TV, desc: "Soaps"}
-      - {id: 80, cat: TV, desc: "Talkshow"}
-      - {id: 59, cat: TV, desc: "Drama"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: /login.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    captcha:
-      type: image
-      image: img#freecap
-      input: word
-    error:
-      - selector: table:contains("Login failed!")
-    test:
-      path: main.php
-
-  download:
-    selector: a[href^="download.php"]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-    rows:
-      selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
-    fields:
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      title:
-        filters:
-        selector: td:nth-child(2) b
-      download:
-        selector: a[href^="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php?id=", "download.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(8)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      files:
-        selector: td:nth-child(4)
-      size:
-        selector: td:nth-child(7)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      date:
-        selector: td:nth-child(6)
-        filters:
-          - name: regexp
-            args: (\d{4}-\d{2}-\d{2})
-      downloadvolumefactor:
-        case:
-          "font[color=\"green\"]": "0"
-          "font[color=\"blue\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "font[color=\"green\"]": "0"
+---
+  site: theempire
+  name: The Empire
+  description: "Commonwealth television"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.theempire.bz/
+
+  caps:
+    categorymappings:
+      - {id: 55, cat: TV, desc: "Adverts"}
+      - {id: 60, cat: TV, desc: "Educational"}
+      - {id: 63, cat: TV, desc: "Game Shows"}
+      - {id: 67, cat: TV, desc: "Music"}
+      - {id: 72, cat: TV, desc: "QuizComedy"}
+      - {id: 77, cat: TV, desc: "Special Events"}
+      - {id: 81, cat: TV, desc: "Trains & Planes"}
+      - {id: 54, cat: TV, desc: "Arts & Culture"}
+      - {id: 61, cat: TV, desc: "Entertainment"}
+      - {id: 53, cat: TV, desc: "Gardening"}
+      - {id: 68, cat: TV, desc: "Mystery & Crime Fiction"}
+      - {id: 73, cat: TV, desc: "Radio"}
+      - {id: 78, cat: TV, desc: "Special Interest"}
+      - {id: 82, cat: TV, desc: "Travel"}
+      - {id: 56, cat: TV, desc: "Comedy"}
+      - {id: 85, cat: TV, desc: "Euro-Noir"}
+      - {id: 64, cat: TV, desc: "Kids"}
+      - {id: 69, cat: TV, desc: "News"}
+      - {id: 74, cat: TV, desc: "Reality"}
+      - {id: 79, cat: TV, desc: "Sport"}
+      - {id: 83, cat: TV, desc: "Wildlife & Nature"}
+      - {id: 58, cat: TV, desc: "Documentary"}
+      - {id: 57, cat: TV, desc: "Fly on the Wall/Lifestyle"}
+      - {id: 65, cat: TV, desc: "Magazine"}
+      - {id: 70, cat: TV, desc: "Occult & Horror"}
+      - {id: 75, cat: TV, desc: "Sci-Fi"}
+      - {id: 84, cat: TV, desc: "Style & Fashion"}
+      - {id: 62, cat: TV, desc: "Food Drink & Cooking"}
+      - {id: 66, cat: TV, desc: "Motoring"}
+      - {id: 71, cat: TV, desc: "Property"}
+      - {id: 76, cat: TV, desc: "Soaps"}
+      - {id: 80, cat: TV, desc: "Talkshow"}
+      - {id: 59, cat: TV, desc: "Drama"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: /login.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    captcha:
+      type: image
+      image: img#freecap
+      input: word
+    error:
+      - selector: table:contains("Login failed!")
+    test:
+      path: main.php
+
+  download:
+    selector: a[href^="download.php"]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+    rows:
+      selector: table[border="0"] > tbody > tr.ttable:has(a[href^="browse.php?cat="])
+    fields:
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      title:
+        filters:
+        selector: td:nth-child(2) b
+      download:
+        selector: a[href^="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php?id=", "download.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(8)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      files:
+        selector: td:nth-child(4)
+      size:
+        selector: td:nth-child(7)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      date:
+        selector: td:nth-child(6)
+        filters:
+          - name: regexp
+            args: (\d{4}-\d{2}-\d{2})
+      downloadvolumefactor:
+        case:
+          "font[color=\"green\"]": "0"
+          "font[color=\"blue\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "font[color=\"green\"]": "0"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/thehorrorcharnel.yml b/src/Jackett/Definitions/thehorrorcharnel.yml
index 42257409fbab9e790da525dda3be35965b49ba96..d59bded669cf67c95af3c16d163d0574770bd1e9 100644
--- a/src/Jackett/Definitions/thehorrorcharnel.yml
+++ b/src/Jackett/Definitions/thehorrorcharnel.yml
@@ -1,105 +1,105 @@
----
-  site: thehorrorcharnel
-  name: The Horror Charnel
-  description: "A Horror, Cult, Sleaze, Sci-Fi & more tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://horrorcharnel.org
-
-  caps:
-    categories:
-      1: Movies
-      2: TV
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  settings:
-    - name: username
-      type: text
-      label: Username
-    - name: password
-      type: password
-      label: Password
-
-  login:
-    path: loginto.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      use_sslvalue=: "on"
-      perm_ssl: "1"
-      returnto: "/"
-    error:
-      - selector: "div#base_content > table.mainouter > tbody > tr > td.outer > table.main > tbody > tr > td:has(h2)"
-    test:
-      path: usercp.php
-      
-  ratio:
-    path: /my.php
-    selector: td.navi_top:contains("Deine Ratio:")
-    filters:
-      - name: replace
-        args: ["Deine Ratio: ", ""]
-      - name: replace
-        args: [".", ""]
-      - name: replace
-        args: [",", "."]
-
-  search:
-    path: /browse.php
-    inputs:
-      #$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-
-    rows:
-      selector: p + table > tbody > tr:has(a[href^="details.php?id="]), p + table > tbody > tr[id^="kdescr"]
-      filters:
-        - name: andmatch
-      after: 1
-    fields:
-      title:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: <b>(.*?)</b>
-      description:
-        selector: td[colspan="13"]
-        remove: a
-      category:
-        text: 1
-      comments:
-        selector: a[onmouseover][href^="details.php"]
-        attribute: href
-      download:
-        selector: a[href^="download.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(6)
-      size:
-        selector: td:nth-child(9)
-      seeders:
-        selector: td:nth-child(11)
-      leechers:
-        selector: td:nth-child(12)
-      date:
-        selector: td:nth-child(8)
-      grabs:
-        selector: td:nth-child(10)
-        filters:
-          - name: regexp
-            args: (\d+)
-      downloadvolumefactor:
-        case:
-          img[src="free.gif"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: thehorrorcharnel
+  name: The Horror Charnel
+  description: "A Horror, Cult, Sleaze, Sci-Fi & more tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://horrorcharnel.org
+
+  caps:
+    categories:
+      1: Movies
+      2: TV
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  settings:
+    - name: username
+      type: text
+      label: Username
+    - name: password
+      type: password
+      label: Password
+
+  login:
+    path: loginto.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      use_sslvalue=: "on"
+      perm_ssl: "1"
+      returnto: "/"
+    error:
+      - selector: "div#base_content > table.mainouter > tbody > tr > td.outer > table.main > tbody > tr > td:has(h2)"
+    test:
+      path: usercp.php
+      
+  ratio:
+    path: /my.php
+    selector: td.navi_top:contains("Deine Ratio:")
+    filters:
+      - name: replace
+        args: ["Deine Ratio: ", ""]
+      - name: replace
+        args: [".", ""]
+      - name: replace
+        args: [",", "."]
+
+  search:
+    path: /browse.php
+    inputs:
+      #$raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+
+    rows:
+      selector: p + table > tbody > tr:has(a[href^="details.php?id="]), p + table > tbody > tr[id^="kdescr"]
+      filters:
+        - name: andmatch
+      after: 1
+    fields:
+      title:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: <b>(.*?)</b>
+      description:
+        selector: td[colspan="13"]
+        remove: a
+      category:
+        text: 1
+      comments:
+        selector: a[onmouseover][href^="details.php"]
+        attribute: href
+      download:
+        selector: a[href^="download.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(6)
+      size:
+        selector: td:nth-child(9)
+      seeders:
+        selector: td:nth-child(11)
+      leechers:
+        selector: td:nth-child(12)
+      date:
+        selector: td:nth-child(8)
+      grabs:
+        selector: td:nth-child(10)
+        filters:
+          - name: regexp
+            args: (\d+)
+      downloadvolumefactor:
+        case:
+          img[src="free.gif"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/theshinning.yml b/src/Jackett/Definitions/theshinning.yml
index 1843c9fa2e8736b35f3531659336afa876262c63..57bd3f83c45ef91ed49c269fb75265bc27b0e0d2 100644
--- a/src/Jackett/Definitions/theshinning.yml
+++ b/src/Jackett/Definitions/theshinning.yml
@@ -1,157 +1,157 @@
----
-  site: theshinning
-  name: The Shinning
-  description: "A German gerneral tracker"
-  language: de-de
-  type: private
-  encoding: windows-1252
-  links:
-    - https://theshinning.org
-
-  caps:
-    categorymappings:
-      # Filme
-      - {id: 28, cat: Movies/SD, desc: "HORROR"}
-      - {id: 25, cat: Movies/DVD, desc: "SD|DVD"}
-      - {id: 99, cat: Movies/SD, desc: "SD|SPORT"}
-      - {id: 24, cat: Movies/SD, desc: "SD|x264"}
-      - {id: 22, cat: Movies/SD, desc: "SD|XVID"}
-      - {id: 26, cat: XXX, desc: "SD|XxX"}
-
-      # High Definition
-      - {id: 29, cat: Movies/BluRay, desc: "BLURAY"}
-      - {id: 19, cat: Movies/HD, desc: "HD|1080p"}
-      - {id: 21, cat: Movies/3D, desc: "HD|3D"}
-      - {id: 107, cat: Movies/HD, desc: "HD|4K"}
-      - {id: 20, cat: Movies/HD, desc: "HD|720p"}
-      - {id: 101, cat: Movies/HD, desc: "HD|REMUX"}
-      - {id: 100, cat: Movies/HD, desc: "HD|SPORT"}
-      - {id: 27, cat: XXX, desc: "HD|XxX"}
-      - {id: 102, cat: Movies/HD, desc: "SMALL|HD"}
-
-      # Musik
-      - {id: 13, cat: Audio, desc: "CHARTS"}
-      - {id: 31, cat: Audio/Lossless, desc: "FLAC"}
-      - {id: 97, cat: Audio/Audiobook, desc: "HOERSPIELE"}
-      - {id: 30, cat: Audio/MP3, desc: "MP3"}
-      - {id: 106, cat: Audio, desc: "SAMPLER"}
-
-      # Releaser
-      - {id: 18, cat: Movies, desc: "CR3WHD"}
-      - {id: 16, cat: Movies, desc: "ONKEL JENS"}
-      - {id: 17, cat: Movies, desc: "xTM|XviD"}
-
-      # Serie
-      - {id: 11, cat: TV/SD, desc: "DVD|SERIEN"}
-      - {id: 9, cat: TV/HD, desc: "HD|SERIEN"}
-      - {id: 32, cat: TV, desc: "MIXED|SERIEN"}
-      - {id: 10, cat: TV, desc: "PACK|SERIEN"}
-      - {id: 8, cat: TV/SD, desc: "SD|SERIEN"}
-      - {id: 105, cat: TV, desc: "SMALL|SERIE"}
-      - {id: 12, cat: TV, desc: "US|SERIEN"}
-
-      # Sonstige
-      - {id: 98, cat: PC, desc: "APPS"}
-      - {id: 90, cat: TV/Documentary, desc: "DOKUS"}
-      - {id: 91, cat: Books, desc: "EBOOKS"}
-      - {id: 14, cat: Movies, desc: "KINOHITS"}
-      - {id: 15, cat: Other, desc: "REQUEST"}
-      - {id: 23, cat: Other , desc: "SONSTIGES"}
-      - {id: 104, cat: XXX/Imageset, desc: "XXX|IMAGE"}
-
-      # Spiele
-      - {id: 96, cat: Console/NDS, desc: "GAMES|NDS"}
-      - {id: 92, cat: PC/Games, desc: "GAMES|PC"}
-      - {id: 94, cat: Console/PS4, desc: "GAMES|PS"}
-      - {id: 95, cat: Console/Wii, desc: "GAMES|WII"}
-      - {id: 93, cat: Console/Xbox, desc: "GAMES|XBOX"}
-
-      # Wrestling
-      - {id: 3, cat: TV/Sport, desc: "HD|RAW"}
-      - {id: 1, cat: TV/Sport, desc: "HD|SMACKD"}
-      - {id: 6, cat: TV/Sport, desc: "NXT"}
-      - {id: 7, cat: TV/Sport, desc: "PPV"}
-      - {id: 4, cat: TV/Sport, desc: "SD|RAW"}
-      - {id: 2, cat: TV/Sport, desc: "SD|SMACKD"}
-      - {id: 5, cat: TV/Sport, desc: "TNA"}
-
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /login.php
-    method: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.stderr_info_wrap
-    test:
-      path: /browse.php
-      selector: img[title="Ratio"] + i
-
-  ratio:
-    path: /browse.php
-    selector: img[title="Ratio"] + i
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      showsearch: "1"
-      incldead: "1"
-      orderby: "added"
-      sort: "desc"
-    rows:
-      selector: table.main > tbody > tr:contains("Alle Torrents") + tr > td > table.tableinborder > tbody > tr
-      filters:
-        - name: andmatch
-    fields:
-      download:
-        selector: a[href^="download-ssl.php?torrent="]
-        attribute: href
-      title:
-        selector: div.title_wrap
-        attribute: title
-        filters:
-          - name: replace
-            args: ["[TsH]", ""]
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: div.title_wrap > a
-        attribute: href
-      size:
-        selector: div.bro_right_ad > b
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      grabs:
-        selector: div.bro_right_ae > b
-      seeders:
-        selector: div.bro_box1_aa > b
-      leechers:
-        selector: div.bro_box_aaa > b
-      date:
-        selector: div.bro_box_date > span
-        filters:
-          - name: replace
-            args: ["\u00a0", " "]
-          - name: dateparse
-            args: "02.01.2006 15:04:05"
-      downloadvolumefactor:
-        case:
-          span[title="OnlyUp"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: theshinning
+  name: The Shinning
+  description: "A German gerneral tracker"
+  language: de-de
+  type: private
+  encoding: windows-1252
+  links:
+    - https://theshinning.org
+
+  caps:
+    categorymappings:
+      # Filme
+      - {id: 28, cat: Movies/SD, desc: "HORROR"}
+      - {id: 25, cat: Movies/DVD, desc: "SD|DVD"}
+      - {id: 99, cat: Movies/SD, desc: "SD|SPORT"}
+      - {id: 24, cat: Movies/SD, desc: "SD|x264"}
+      - {id: 22, cat: Movies/SD, desc: "SD|XVID"}
+      - {id: 26, cat: XXX, desc: "SD|XxX"}
+
+      # High Definition
+      - {id: 29, cat: Movies/BluRay, desc: "BLURAY"}
+      - {id: 19, cat: Movies/HD, desc: "HD|1080p"}
+      - {id: 21, cat: Movies/3D, desc: "HD|3D"}
+      - {id: 107, cat: Movies/HD, desc: "HD|4K"}
+      - {id: 20, cat: Movies/HD, desc: "HD|720p"}
+      - {id: 101, cat: Movies/HD, desc: "HD|REMUX"}
+      - {id: 100, cat: Movies/HD, desc: "HD|SPORT"}
+      - {id: 27, cat: XXX, desc: "HD|XxX"}
+      - {id: 102, cat: Movies/HD, desc: "SMALL|HD"}
+
+      # Musik
+      - {id: 13, cat: Audio, desc: "CHARTS"}
+      - {id: 31, cat: Audio/Lossless, desc: "FLAC"}
+      - {id: 97, cat: Audio/Audiobook, desc: "HOERSPIELE"}
+      - {id: 30, cat: Audio/MP3, desc: "MP3"}
+      - {id: 106, cat: Audio, desc: "SAMPLER"}
+
+      # Releaser
+      - {id: 18, cat: Movies, desc: "CR3WHD"}
+      - {id: 16, cat: Movies, desc: "ONKEL JENS"}
+      - {id: 17, cat: Movies, desc: "xTM|XviD"}
+
+      # Serie
+      - {id: 11, cat: TV/SD, desc: "DVD|SERIEN"}
+      - {id: 9, cat: TV/HD, desc: "HD|SERIEN"}
+      - {id: 32, cat: TV, desc: "MIXED|SERIEN"}
+      - {id: 10, cat: TV, desc: "PACK|SERIEN"}
+      - {id: 8, cat: TV/SD, desc: "SD|SERIEN"}
+      - {id: 105, cat: TV, desc: "SMALL|SERIE"}
+      - {id: 12, cat: TV, desc: "US|SERIEN"}
+
+      # Sonstige
+      - {id: 98, cat: PC, desc: "APPS"}
+      - {id: 90, cat: TV/Documentary, desc: "DOKUS"}
+      - {id: 91, cat: Books, desc: "EBOOKS"}
+      - {id: 14, cat: Movies, desc: "KINOHITS"}
+      - {id: 15, cat: Other, desc: "REQUEST"}
+      - {id: 23, cat: Other , desc: "SONSTIGES"}
+      - {id: 104, cat: XXX/Imageset, desc: "XXX|IMAGE"}
+
+      # Spiele
+      - {id: 96, cat: Console/NDS, desc: "GAMES|NDS"}
+      - {id: 92, cat: PC/Games, desc: "GAMES|PC"}
+      - {id: 94, cat: Console/PS4, desc: "GAMES|PS"}
+      - {id: 95, cat: Console/Wii, desc: "GAMES|WII"}
+      - {id: 93, cat: Console/Xbox, desc: "GAMES|XBOX"}
+
+      # Wrestling
+      - {id: 3, cat: TV/Sport, desc: "HD|RAW"}
+      - {id: 1, cat: TV/Sport, desc: "HD|SMACKD"}
+      - {id: 6, cat: TV/Sport, desc: "NXT"}
+      - {id: 7, cat: TV/Sport, desc: "PPV"}
+      - {id: 4, cat: TV/Sport, desc: "SD|RAW"}
+      - {id: 2, cat: TV/Sport, desc: "SD|SMACKD"}
+      - {id: 5, cat: TV/Sport, desc: "TNA"}
+
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /login.php
+    method: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.stderr_info_wrap
+    test:
+      path: /browse.php
+      selector: img[title="Ratio"] + i
+
+  ratio:
+    path: /browse.php
+    selector: img[title="Ratio"] + i
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      showsearch: "1"
+      incldead: "1"
+      orderby: "added"
+      sort: "desc"
+    rows:
+      selector: table.main > tbody > tr:contains("Alle Torrents") + tr > td > table.tableinborder > tbody > tr
+      filters:
+        - name: andmatch
+    fields:
+      download:
+        selector: a[href^="download-ssl.php?torrent="]
+        attribute: href
+      title:
+        selector: div.title_wrap
+        attribute: title
+        filters:
+          - name: replace
+            args: ["[TsH]", ""]
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: div.title_wrap > a
+        attribute: href
+      size:
+        selector: div.bro_right_ad > b
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      grabs:
+        selector: div.bro_right_ae > b
+      seeders:
+        selector: div.bro_box1_aa > b
+      leechers:
+        selector: div.bro_box_aaa > b
+      date:
+        selector: div.bro_box_date > span
+        filters:
+          - name: replace
+            args: ["\u00a0", " "]
+          - name: dateparse
+            args: "02.01.2006 15:04:05"
+      downloadvolumefactor:
+        case:
+          span[title="OnlyUp"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/tntvillage.yml b/src/Jackett/Definitions/tntvillage.yml
index 1dde5014a902ced850ce8bcc76b8eb6d03fedeb4..d41019611b6b2cb67ed8541a37b4a739a67a7f1f 100644
--- a/src/Jackett/Definitions/tntvillage.yml
+++ b/src/Jackett/Definitions/tntvillage.yml
@@ -1,69 +1,69 @@
----
-  site: tntvillage
-  name: TNTVillage
-  language: it-it
-  type: public
-  encoding: UTF-8
-  links:
-    - http://www.tntvillage.scambioetico.org/
-
-  caps:
-    categorymappings:
-      - {id: 4, cat: Movies, desc: "Movies category"}
-      - {id: 2, cat: Audio, desc: "Music videos"}
-      - {id: 29, cat: TV, desc: "TV Series"}
-      - {id: 7, cat: TV/Anime, desc: "Animes"}
-      - {id: 8, cat: TV/Anime, desc: "Cartoons"}
-      - {id: 14, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 30, cat: Books/Comics, desc: "Comics"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-
-  settings: []
-
-  search:
-    paths:
-      - path: /src/releaselist.php
-        method: post
-    inputs:
-      cat: 0
-      page: 1
-      srcrel: "{{ .Keywords }}"
-    rows:
-      selector: div.showrelease_tb table tbody tr:not(tr:nth-child(1))
-    fields:
-      title:
-        selector: td:nth-child(7)
-      category:
-        selector: td:nth-child(3) a
-        attribute: href
-        filters:
-          - name: split
-            args: ["=", "-1"]
-      details:
-        selector: td:nth-child(7) a
-        attribute: href
-      download:
-        selector: td:nth-child(1) a
-        attribute: href
-      magnet:
-        selector: td:nth-child(2) a
-        attribute: href
-      seeders:
-        selector: td:nth-child(5)
-      leechers:
-        selector: td:nth-child(4)
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
-        text: "1"
-      size:
-        selector: td:nth-child(3) a
-        case:
-          a[href*="&cat=4"]: "5GB"
-          a[href*="&cat=2"]: "100MB"
-          a[href*="&cat=30"]: "100MB"
-          "*": "2GB"
+---
+  site: tntvillage
+  name: TNTVillage
+  language: it-it
+  type: public
+  encoding: UTF-8
+  links:
+    - http://www.tntvillage.scambioetico.org/
+
+  caps:
+    categorymappings:
+      - {id: 4, cat: Movies, desc: "Movies category"}
+      - {id: 2, cat: Audio, desc: "Music videos"}
+      - {id: 29, cat: TV, desc: "TV Series"}
+      - {id: 7, cat: TV/Anime, desc: "Animes"}
+      - {id: 8, cat: TV/Anime, desc: "Cartoons"}
+      - {id: 14, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 30, cat: Books/Comics, desc: "Comics"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+
+  settings: []
+
+  search:
+    paths:
+      - path: /src/releaselist.php
+        method: post
+    inputs:
+      cat: 0
+      page: 1
+      srcrel: "{{ .Keywords }}"
+    rows:
+      selector: div.showrelease_tb table tbody tr:not(tr:nth-child(1))
+    fields:
+      title:
+        selector: td:nth-child(7)
+      category:
+        selector: td:nth-child(3) a
+        attribute: href
+        filters:
+          - name: split
+            args: ["=", "-1"]
+      details:
+        selector: td:nth-child(7) a
+        attribute: href
+      download:
+        selector: td:nth-child(1) a
+        attribute: href
+      magnet:
+        selector: td:nth-child(2) a
+        attribute: href
+      seeders:
+        selector: td:nth-child(5)
+      leechers:
+        selector: td:nth-child(4)
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
+        text: "1"
+      size:
+        selector: td:nth-child(3) a
+        case:
+          a[href*="&cat=4"]: "5GB"
+          a[href*="&cat=2"]: "100MB"
+          a[href*="&cat=30"]: "100MB"
+          "*": "2GB"
diff --git a/src/Jackett/Definitions/torrent9.yml b/src/Jackett/Definitions/torrent9.yml
index 98f0c083bdbe4bb93f3dc4457d1d74aee95dc153..ba1a1a00f25cdd1c7f29cde1f385c655be718d1f 100644
--- a/src/Jackett/Definitions/torrent9.yml
+++ b/src/Jackett/Definitions/torrent9.yml
@@ -1,76 +1,76 @@
----
-  site: torrent9
-  name: Torrent9
-  language: fr-fr
-  type: public
-  encoding: UTF-8
-  links:
-    - http://www.torrent9.biz/
-
-  caps:
-    categorymappings:
-      - {id: films, cat: Movies, desc: "Movies"}
-      - {id: series, cat: TV, desc: "TV"}
-      - {id: musique, cat: Audio, desc: "Music"}
-      - {id: ebook, cat: Books, desc: "Books"}
-      - {id: logiciels, cat: PC, desc: "Software"}
-      - {id: jeux-pc, cat: PC/Games, desc: "PC Games"}
-      - {id: jeux-consoles, cat: Console/Xbox360, desc: "Console Games"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  search:
-    path: "{{if .Query.Keywords}}/search_torrent/{{range .Categories }}{{.}}/{{end}}{{ .Query.Keywords }}/page-0,trie-seeds-d{{else}}/top_torrent.php{{end}}"
-    rows:
-      selector: div.table-responsive > table tbody tr
-    fields:
-      title:
-        selector: td:nth-child(1) a
-      details:
-        selector: td:nth-child(1) a
-        attribute: href
-      download:
-        selector: td:nth-child(1) a
-        attribute: href
-        filters:
-          - name: replace
-            args: [ "/torrent", "/get_torrent"]
-          - name: append
-            args: ".torrent"
-      size:
-        selector: td:nth-child(2)
-        filters:
-          - name: re_replace
-            args: [ "\\.(\\d) Ko", "$1X00"]
-          - name: re_replace
-            args: [ " Ko", "000"]
-          - name: re_replace
-            args: [ "\\.(\\d) Mo", "$1X00000"]
-          - name: re_replace
-            args: [ " Mo", "000000"]
-          - name: re_replace
-            args: [ "\\.(\\d) Go", "$1X00000000"]
-          - name: re_replace
-            args: [ " Go", "000000000"]
-          - name: re_replace
-            args: [ "\\.(\\d) To", "$1X00000000000"]
-          - name: re_replace
-            args: [ " To", "000000000000"]
-          - name: replace
-            args: [ "X", "" ]
-      seeders:
-        text: 0
-      seeders:
-        selector: td:nth-child(3) span.seed_ok
-        optional: true
-      leechers:
-        text: 0
-      leechers:
-        selector: td:nth-child(4)
-        optional: true
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
+---
+  site: torrent9
+  name: Torrent9
+  language: fr-fr
+  type: public
+  encoding: UTF-8
+  links:
+    - http://www.torrent9.biz/
+
+  caps:
+    categorymappings:
+      - {id: films, cat: Movies, desc: "Movies"}
+      - {id: series, cat: TV, desc: "TV"}
+      - {id: musique, cat: Audio, desc: "Music"}
+      - {id: ebook, cat: Books, desc: "Books"}
+      - {id: logiciels, cat: PC, desc: "Software"}
+      - {id: jeux-pc, cat: PC/Games, desc: "PC Games"}
+      - {id: jeux-consoles, cat: Console/Xbox360, desc: "Console Games"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  search:
+    path: "{{if .Query.Keywords}}/search_torrent/{{range .Categories }}{{.}}/{{end}}{{ .Query.Keywords }}/page-0,trie-seeds-d{{else}}/top_torrent.php{{end}}"
+    rows:
+      selector: div.table-responsive > table tbody tr
+    fields:
+      title:
+        selector: td:nth-child(1) a
+      details:
+        selector: td:nth-child(1) a
+        attribute: href
+      download:
+        selector: td:nth-child(1) a
+        attribute: href
+        filters:
+          - name: replace
+            args: [ "/torrent", "/get_torrent"]
+          - name: append
+            args: ".torrent"
+      size:
+        selector: td:nth-child(2)
+        filters:
+          - name: re_replace
+            args: [ "\\.(\\d) Ko", "$1X00"]
+          - name: re_replace
+            args: [ " Ko", "000"]
+          - name: re_replace
+            args: [ "\\.(\\d) Mo", "$1X00000"]
+          - name: re_replace
+            args: [ " Mo", "000000"]
+          - name: re_replace
+            args: [ "\\.(\\d) Go", "$1X00000000"]
+          - name: re_replace
+            args: [ " Go", "000000000"]
+          - name: re_replace
+            args: [ "\\.(\\d) To", "$1X00000000000"]
+          - name: re_replace
+            args: [ " To", "000000000000"]
+          - name: replace
+            args: [ "X", "" ]
+      seeders:
+        text: 0
+      seeders:
+        selector: td:nth-child(3) span.seed_ok
+        optional: true
+      leechers:
+        text: 0
+      leechers:
+        selector: td:nth-child(4)
+        optional: true
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
         text: "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/torrentbd.yml b/src/Jackett/Definitions/torrentbd.yml
index 9d7888721191a58eb314006f9d4e5f44cd5924a0..1e3fbb2e018c4413ecd16185aec2c5417fa08480 100644
--- a/src/Jackett/Definitions/torrentbd.yml
+++ b/src/Jackett/Definitions/torrentbd.yml
@@ -1,151 +1,151 @@
----
-  site: torrentbd
-  name: TorrentBD
-  description: "A general tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - http://www.torrentbd.com/torrent
-
-  caps:
-    categorymappings:
-      - {id: 28, cat: TV/Anime, desc: "Anime - All"}
-      - {id: 65, cat: PC/Phone-Android, desc: "Apps - Android"}
-      - {id: 20, cat: PC, desc: "Apps - Linux"}
-      - {id: 19, cat: PC/Mac, desc: "Apps - Mac"}
-      - {id: 18, cat: PC, desc: "Apps - PC"}
-      - {id: 21, cat: Audio, desc: "Bangla - Audio"}
-      - {id: 7, cat: Movies, desc: "Bangla - Movies | Natok"}
-      - {id: 49, cat: TV, desc: "Cartoons - All"}
-      - {id: 9, cat: TV/Documentary, desc: "Documentaries - All"}
-      - {id: 73, cat: Books/Comics, desc: "E-Books - Comics"}
-      - {id: 77, cat: Books, desc: "E-Books - Manga"}
-      - {id: 60, cat: PC/Games, desc: "Games - Cracks | Patches"}
-      - {id: 17, cat: Console, desc: "Games - Other"}
-      - {id: 10, cat: PC, desc: "Games - PC"}
-      - {id: 11, cat: Console/PS3, desc: "Games - PS2"}
-      - {id: 43, cat: Console/PS3, desc: "Games - PS3"}
-      - {id: 12, cat: Console/PSP, desc: "Games - PSP"}
-      - {id: 52, cat: PC/Games, desc: "Games - Updates | DLC"}
-      - {id: 13, cat: Console/Xbox, desc: "Games - Xbox"}
-      - {id: 14, cat: Console/Xbox360, desc: "Games - Xbox360"}
-      - {id: 23, cat: Movies/BluRay, desc: "Hindi - Blu-ray"}
-      - {id: 51, cat: Movies/SD, desc: "Hindi - CAM | TS | TC"}
-      - {id: 27, cat: Movies/DVD, desc: "Hindi - DVDRip"}
-      - {id: 58, cat: Movies/SD, desc: "Hindi - DVDScr | Pre-DVD"}
-      - {id: 68, cat: Movies/SD, desc: "Hindi - HD-Rip"}
-      - {id: 59, cat: Movies, desc: "Hindi - Web-Rip"}
-      - {id: 47, cat: Movies/HD, desc: "Movies - 1080p BluRay"}
-      - {id: 67, cat: Movies/3D, desc: "Movies - 3D"}
-      - {id: 42, cat: Movies/BluRay, desc: "Movies - 720p BluRay"}
-      - {id: 57, cat: Movies, desc: "Movies - Animation"}
-      - {id: 4, cat: Movies/SD, desc: "Movies - CAM | TS | TC"}
-      - {id: 69, cat: Movies, desc: "Movies - Dual Audio"}
-      - {id: 1, cat: Movies/SD, desc: "Movies - DVDRip"}
-      - {id: 56, cat: Movies/SD, desc: "Movies - DVDSCR | R5 | R6"}
-      - {id: 46, cat: Movies/SD, desc: "Movies - HD-Rip"}
-      - {id: 76, cat: Movies/BluRay, desc: "Movies - Lossless BluRay"}
-      - {id: 2, cat: Movies, desc: "Movies - Packs"}
-      - {id: 24, cat: Movies/SD, desc: "Movies - SD BluRay"}
-      - {id: 34, cat: Movies, desc: "Movies - Tamil"}
-      - {id: 3, cat: Movies, desc: "Movies - Unrated"}
-      - {id: 72, cat: Movies, desc: "Movies - WEB Rip"}
-      - {id: 55, cat: Movies, desc: "Movies - WEB-DL"}
-      - {id: 22, cat: Audio, desc: "Music - Audio"}
-      - {id: 64, cat: Audio, desc: "Music - Concerts | Live Shows"}
-      - {id: 71, cat: Audio/Lossless, desc: "Music - FLAC"}
-      - {id: 50, cat: Audio, desc: "Music - OST"}
-      - {id: 26, cat: Audio, desc: "Music - Radio"}
-      - {id: 25, cat: Audio, desc: "Music - Video"}
-      - {id: 78, cat: Audio, desc: "Music - Video 4K"}
-      - {id: 36, cat: Books, desc: "Other - E-Books"}
-      - {id: 37, cat: Other, desc: "Other - Images"}
-      - {id: 38, cat: PC/Phone-Other, desc: "Other - Mobile Phone"}
-      - {id: 40, cat: Other, desc: "Other - Other | Misc"}
-      - {id: 39, cat: Other, desc: "Other - Tutorial"}
-      - {id: 44, cat: Other, desc: "Religious  - Islam"}
-      - {id: 48, cat: TV/Sport, desc: "Sports - All"}
-      - {id: 70, cat: TV/Sport, desc: "Sports - Football"}
-      - {id: 6, cat: TV/Sport, desc: "Sports - Pro Wrestling"}
-      - {id: 33, cat: Other, desc: "Trailers - Movie | Games"}
-      - {id: 66, cat: TV, desc: "TV - Awards | Ceremonies"}
-      - {id: 5, cat: TV/SD, desc: "TV - Episodes"}
-      - {id: 61, cat: TV/HD, desc: "TV - Episodes - 720p | 1080p"}
-      - {id: 41, cat: TV/SD, desc: "TV - Packs"}
-      - {id: 62, cat: TV/HD, desc: "TV - Packs - HD | BRRip"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: account-login.php
-    method: form
-    form: form[action="account-login.php"]
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.myFrame:has(div.myF-caption > font.error)
-    test:
-      path: torrents-search.php
-      selector: div.myB-content:contains("Ratio:")
-
-  ratio:
-    path: torrents-search.php
-    selector: div.myB-content:contains("Ratio:")
-    filters:
-      - name: regexp
-        args: "Ratio: (.*?)$"
-
-  search:
-    path: torrents-search.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-    rows:
-      selector: tr.t-row
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: span.torrname
-        attribute: title
-      category:
-        selector: a[href^="torrents.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[onmouseover][href^="torrents-details.php?id="]
-        attribute: href
-      comments:
-        selector: a[href*="#comments"]
-        attribute: href
-      size:
-        selector: td:nth-child(6)
-      grabs:
-        selector: td:nth-child(9)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      date:
-        selector: a[onmouseover][href^="torrents-details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: "Date Added: </b>(\\d+-\\d+-\\d+)<br />"
-          - name: dateparse
-            args: "02-01-2006"
-      downloadvolumefactor:
-        case:
-          img[title^="FreeLeech "]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: torrentbd
+  name: TorrentBD
+  description: "A general tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - http://www.torrentbd.com/torrent
+
+  caps:
+    categorymappings:
+      - {id: 28, cat: TV/Anime, desc: "Anime - All"}
+      - {id: 65, cat: PC/Phone-Android, desc: "Apps - Android"}
+      - {id: 20, cat: PC, desc: "Apps - Linux"}
+      - {id: 19, cat: PC/Mac, desc: "Apps - Mac"}
+      - {id: 18, cat: PC, desc: "Apps - PC"}
+      - {id: 21, cat: Audio, desc: "Bangla - Audio"}
+      - {id: 7, cat: Movies, desc: "Bangla - Movies | Natok"}
+      - {id: 49, cat: TV, desc: "Cartoons - All"}
+      - {id: 9, cat: TV/Documentary, desc: "Documentaries - All"}
+      - {id: 73, cat: Books/Comics, desc: "E-Books - Comics"}
+      - {id: 77, cat: Books, desc: "E-Books - Manga"}
+      - {id: 60, cat: PC/Games, desc: "Games - Cracks | Patches"}
+      - {id: 17, cat: Console, desc: "Games - Other"}
+      - {id: 10, cat: PC, desc: "Games - PC"}
+      - {id: 11, cat: Console/PS3, desc: "Games - PS2"}
+      - {id: 43, cat: Console/PS3, desc: "Games - PS3"}
+      - {id: 12, cat: Console/PSP, desc: "Games - PSP"}
+      - {id: 52, cat: PC/Games, desc: "Games - Updates | DLC"}
+      - {id: 13, cat: Console/Xbox, desc: "Games - Xbox"}
+      - {id: 14, cat: Console/Xbox360, desc: "Games - Xbox360"}
+      - {id: 23, cat: Movies/BluRay, desc: "Hindi - Blu-ray"}
+      - {id: 51, cat: Movies/SD, desc: "Hindi - CAM | TS | TC"}
+      - {id: 27, cat: Movies/DVD, desc: "Hindi - DVDRip"}
+      - {id: 58, cat: Movies/SD, desc: "Hindi - DVDScr | Pre-DVD"}
+      - {id: 68, cat: Movies/SD, desc: "Hindi - HD-Rip"}
+      - {id: 59, cat: Movies, desc: "Hindi - Web-Rip"}
+      - {id: 47, cat: Movies/HD, desc: "Movies - 1080p BluRay"}
+      - {id: 67, cat: Movies/3D, desc: "Movies - 3D"}
+      - {id: 42, cat: Movies/BluRay, desc: "Movies - 720p BluRay"}
+      - {id: 57, cat: Movies, desc: "Movies - Animation"}
+      - {id: 4, cat: Movies/SD, desc: "Movies - CAM | TS | TC"}
+      - {id: 69, cat: Movies, desc: "Movies - Dual Audio"}
+      - {id: 1, cat: Movies/SD, desc: "Movies - DVDRip"}
+      - {id: 56, cat: Movies/SD, desc: "Movies - DVDSCR | R5 | R6"}
+      - {id: 46, cat: Movies/SD, desc: "Movies - HD-Rip"}
+      - {id: 76, cat: Movies/BluRay, desc: "Movies - Lossless BluRay"}
+      - {id: 2, cat: Movies, desc: "Movies - Packs"}
+      - {id: 24, cat: Movies/SD, desc: "Movies - SD BluRay"}
+      - {id: 34, cat: Movies, desc: "Movies - Tamil"}
+      - {id: 3, cat: Movies, desc: "Movies - Unrated"}
+      - {id: 72, cat: Movies, desc: "Movies - WEB Rip"}
+      - {id: 55, cat: Movies, desc: "Movies - WEB-DL"}
+      - {id: 22, cat: Audio, desc: "Music - Audio"}
+      - {id: 64, cat: Audio, desc: "Music - Concerts | Live Shows"}
+      - {id: 71, cat: Audio/Lossless, desc: "Music - FLAC"}
+      - {id: 50, cat: Audio, desc: "Music - OST"}
+      - {id: 26, cat: Audio, desc: "Music - Radio"}
+      - {id: 25, cat: Audio, desc: "Music - Video"}
+      - {id: 78, cat: Audio, desc: "Music - Video 4K"}
+      - {id: 36, cat: Books, desc: "Other - E-Books"}
+      - {id: 37, cat: Other, desc: "Other - Images"}
+      - {id: 38, cat: PC/Phone-Other, desc: "Other - Mobile Phone"}
+      - {id: 40, cat: Other, desc: "Other - Other | Misc"}
+      - {id: 39, cat: Other, desc: "Other - Tutorial"}
+      - {id: 44, cat: Other, desc: "Religious  - Islam"}
+      - {id: 48, cat: TV/Sport, desc: "Sports - All"}
+      - {id: 70, cat: TV/Sport, desc: "Sports - Football"}
+      - {id: 6, cat: TV/Sport, desc: "Sports - Pro Wrestling"}
+      - {id: 33, cat: Other, desc: "Trailers - Movie | Games"}
+      - {id: 66, cat: TV, desc: "TV - Awards | Ceremonies"}
+      - {id: 5, cat: TV/SD, desc: "TV - Episodes"}
+      - {id: 61, cat: TV/HD, desc: "TV - Episodes - 720p | 1080p"}
+      - {id: 41, cat: TV/SD, desc: "TV - Packs"}
+      - {id: 62, cat: TV/HD, desc: "TV - Packs - HD | BRRip"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: account-login.php
+    method: form
+    form: form[action="account-login.php"]
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.myFrame:has(div.myF-caption > font.error)
+    test:
+      path: torrents-search.php
+      selector: div.myB-content:contains("Ratio:")
+
+  ratio:
+    path: torrents-search.php
+    selector: div.myB-content:contains("Ratio:")
+    filters:
+      - name: regexp
+        args: "Ratio: (.*?)$"
+
+  search:
+    path: torrents-search.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+    rows:
+      selector: tr.t-row
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: span.torrname
+        attribute: title
+      category:
+        selector: a[href^="torrents.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[onmouseover][href^="torrents-details.php?id="]
+        attribute: href
+      comments:
+        selector: a[href*="#comments"]
+        attribute: href
+      size:
+        selector: td:nth-child(6)
+      grabs:
+        selector: td:nth-child(9)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      date:
+        selector: a[onmouseover][href^="torrents-details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: "Date Added: </b>(\\d+-\\d+-\\d+)<br />"
+          - name: dateparse
+            args: "02-01-2006"
+      downloadvolumefactor:
+        case:
+          img[title^="FreeLeech "]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/torrentccf.yml b/src/Jackett/Definitions/torrentccf.yml
index f7bb3c2559249a8626473353ced2025b33a460e4..dce38c891d15671cc05f77782b9ccff17f0cb528 100644
--- a/src/Jackett/Definitions/torrentccf.yml
+++ b/src/Jackett/Definitions/torrentccf.yml
@@ -1,118 +1,118 @@
----
-  site: torrentccf
-  name: TorrentCCF
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://et8.org/
-
-  caps:
-    categorymappings:
-      - {id: 601, cat: Movies, desc: "Movies"}
-      - {id: 602, cat: TV/Anime, desc: "Animations"}
-      - {id: 603, cat: TV/Sport, desc: "Sports"}
-      - {id: 604, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 605, cat: Books, desc: "EDU"}
-      - {id: 606, cat: TV, desc: "TV/Cn"}
-      - {id: 607, cat: TV, desc: "TV/Western"}
-      - {id: 608, cat: TV, desc: "TV/hk_tw"}
-      - {id: 609, cat: TV, desc: "TV/Japan_korea"}
-      - {id: 610, cat: TV, desc: "TV Shows"}
-      - {id: 611, cat: Audio, desc: "Music/Cn"}
-      - {id: 612, cat: Audio, desc: "Music/Western"}
-      - {id: 613, cat: Audio, desc: "Music/Asia"}
-      - {id: 614, cat: Audio, desc: "Music/Classic"}
-      - {id: 615, cat: Audio/Video, desc: "MusicVideo"}
-      - {id: 616, cat: PC, desc: "Appz"}
-      - {id: 617, cat: PC/Games, desc: "PC Games"}
-      - {id: 618, cat: Console/PS4, desc: "Playstation"}
-      - {id: 619, cat: Console/Xbox, desc: "Xbox"}
-      - {id: 620, cat: Console/Wii, desc: "Wii"}
-      - {id: 621, cat: Other, desc: "Others"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [imdbid]
-
-  login:
-    path: /login.php
-    method: form
-    form: form[action="takelogin.php"]
-    captcha:
-      type: image
-      image: img[alt="CAPTCHA"]
-      input: imagestring
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("登录失败"))
-    test:
-      path: /torrents.php
-
-  search:
-    path: /torrents.php
-    method: get
-    inputs:
-      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      incldead: "1"
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-    rows:
-      selector: table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      title|optional:
-        selector: a[title][href^="details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href    
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      imdb|optional:
-        selector: div.imdb_100 > a
-        attribute: href
-      size:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      date:
-        selector: td:nth-child(4) > span[title]
-        attribute: title
-        filters:
-          - name: append
-            args: " +08:00"
-          - name: dateparse
-            args: "2006-01-02 15:04:05 -07:00"
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a, img
+---
+  site: torrentccf
+  name: TorrentCCF
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://et8.org/
+
+  caps:
+    categorymappings:
+      - {id: 601, cat: Movies, desc: "Movies"}
+      - {id: 602, cat: TV/Anime, desc: "Animations"}
+      - {id: 603, cat: TV/Sport, desc: "Sports"}
+      - {id: 604, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 605, cat: Books, desc: "EDU"}
+      - {id: 606, cat: TV, desc: "TV/Cn"}
+      - {id: 607, cat: TV, desc: "TV/Western"}
+      - {id: 608, cat: TV, desc: "TV/hk_tw"}
+      - {id: 609, cat: TV, desc: "TV/Japan_korea"}
+      - {id: 610, cat: TV, desc: "TV Shows"}
+      - {id: 611, cat: Audio, desc: "Music/Cn"}
+      - {id: 612, cat: Audio, desc: "Music/Western"}
+      - {id: 613, cat: Audio, desc: "Music/Asia"}
+      - {id: 614, cat: Audio, desc: "Music/Classic"}
+      - {id: 615, cat: Audio/Video, desc: "MusicVideo"}
+      - {id: 616, cat: PC, desc: "Appz"}
+      - {id: 617, cat: PC/Games, desc: "PC Games"}
+      - {id: 618, cat: Console/PS4, desc: "Playstation"}
+      - {id: 619, cat: Console/Xbox, desc: "Xbox"}
+      - {id: 620, cat: Console/Wii, desc: "Wii"}
+      - {id: 621, cat: Other, desc: "Others"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [imdbid]
+
+  login:
+    path: /login.php
+    method: form
+    form: form[action="takelogin.php"]
+    captcha:
+      type: image
+      image: img[alt="CAPTCHA"]
+      input: imagestring
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("登录失败"))
+    test:
+      path: /torrents.php
+
+  search:
+    path: /torrents.php
+    method: get
+    inputs:
+      $raw: "{{range .Categories}}cat{{.}}=1&{{end}}"
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      incldead: "1"
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+    rows:
+      selector: table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      title|optional:
+        selector: a[title][href^="details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href    
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      imdb|optional:
+        selector: div.imdb_100 > a
+        attribute: href
+      size:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      date:
+        selector: td:nth-child(4) > span[title]
+        attribute: title
+        filters:
+          - name: append
+            args: " +08:00"
+          - name: dateparse
+            args: "2006-01-02 15:04:05 -07:00"
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a, img
diff --git a/src/Jackett/Definitions/torrenthr.yml b/src/Jackett/Definitions/torrenthr.yml
index 3b722ece594a71ff684f8163b58f9565e6ffdc8f..7134d2f2d1fe257ce0ca318c6af4f70bf0ef28a9 100644
--- a/src/Jackett/Definitions/torrenthr.yml
+++ b/src/Jackett/Definitions/torrenthr.yml
@@ -1,129 +1,129 @@
----
-  site: torrenthr
-  name: TorrentHR
-  language: hr-hr
-  type: private
-  encoding: windows-1250
-  links:
-    - https://www.torrenthr.org/
-
-  caps:
-    categorymappings:
-      - {id: 31, cat: TV/Anime, desc: "Anime"}
-      - {id: 4, cat: Movies/SD, desc: "Filmovi/SD"}
-      - {id: 18, cat: Movies/Foreign, desc: "Crtani Filmovi"}
-      - {id: 5, cat: PC/Games, desc: "Igre/PC"}
-      - {id: 7, cat: TV/SD, desc: "Serije/SD"}
-      - {id: 1, cat: PC/0day, desc: "Aplikacije"}
-      - {id: 14, cat: Movies/DVD, desc: "Filmovi/DVD"}
-      - {id: 12, cat: TV/Documentary, desc: "Dokumentarni Filmovi"}
-      - {id: 27, cat: Console/PS4, desc: "Igre/PS"}
-      - {id: 34, cat: TV/HD, desc: "Serije/HD"}
-      - {id: 25, cat: Books, desc: "E-books"}
-      - {id: 17, cat: Movies/HD, desc: "Filmovi/HD"}
-      - {id: 11, cat: Audio, desc: "Koncerti/Spotovi"}
-      - {id: 28, cat: Console/Wii, desc: "Igre/Wii"}
-      - {id: 30, cat: Books/Comics, desc: "Stripovi"}
-      - {id: 38, cat: PC/Phone-Other, desc: "Smartphone"}
-      - {id: 40, cat: Movies/BluRay, desc: "Filmovi/BD"}
-      - {id: 3, cat: Audio/MP3, desc: "Glazba/MP3"}
-      - {id: 26, cat: Console/Xbox, desc: "Igre/Xbox"}
-      - {id: 10, cat: XXX, desc: "XXX/SD"}
-      - {id: 16, cat: TV, desc: "THR Packs"}
-      - {id: 15, cat: TV/Sport, desc: "Sport"}
-      - {id: 29, cat: Audio/Lossless, desc: "Glazba/FLAC"}
-      - {id: 13, cat: Other, desc: "Ostalo"}
-      - {id: 36, cat: XXX, desc: "XXX/HD"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      ssl: "yes"
-    error:
-      - selector: div.glavni:has(div.glavni_naslov:contains("Greška"))
-    test:
-      path: /browse.php
-      
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      sort: "4"
-      type: "desc"
-    rows:
-      selector: div.glavni_txt > table > tbody > tr[id^="record-"]
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      title|optional|1:
-        selector: a[href^="details.php?id="][title]
-        attribute: title
-      title|optional|2:
-        selector: a[href^="details.php?id="][onmousemove]
-        attribute: onmousemove
-        filters:
-          - name: regexp
-            args: "return overlibImage\\('(.*)','.*'\\);"
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: td.kategorije > a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      files:
-        selector: td:nth-child(5)
-      size:
-        selector: td:nth-child(7)
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-          - name: replace
-            args: [",", ""]
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      banner|optional:
-        selector: a[href^="details.php?id="][onmousemove]
-        attribute: onmousemove
-        filters:
-          - name: regexp
-            args: "return overlibImage\\('.*','(.*)'\\);"
-      downloadvolumefactor:
-        text: "0"
-      uploadvolumefactor:
-        text: "1"
-      date:
-        selector: td:nth-child(2) > small
-        filters:
-          - name: replace
-            args: [" u ", " "]
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "02.01.2006 15:04:05 -07:00"
-      description|optional:
-        selector: td:nth-child(2)
+---
+  site: torrenthr
+  name: TorrentHR
+  language: hr-hr
+  type: private
+  encoding: windows-1250
+  links:
+    - https://www.torrenthr.org/
+
+  caps:
+    categorymappings:
+      - {id: 31, cat: TV/Anime, desc: "Anime"}
+      - {id: 4, cat: Movies/SD, desc: "Filmovi/SD"}
+      - {id: 18, cat: Movies/Foreign, desc: "Crtani Filmovi"}
+      - {id: 5, cat: PC/Games, desc: "Igre/PC"}
+      - {id: 7, cat: TV/SD, desc: "Serije/SD"}
+      - {id: 1, cat: PC/0day, desc: "Aplikacije"}
+      - {id: 14, cat: Movies/DVD, desc: "Filmovi/DVD"}
+      - {id: 12, cat: TV/Documentary, desc: "Dokumentarni Filmovi"}
+      - {id: 27, cat: Console/PS4, desc: "Igre/PS"}
+      - {id: 34, cat: TV/HD, desc: "Serije/HD"}
+      - {id: 25, cat: Books, desc: "E-books"}
+      - {id: 17, cat: Movies/HD, desc: "Filmovi/HD"}
+      - {id: 11, cat: Audio, desc: "Koncerti/Spotovi"}
+      - {id: 28, cat: Console/Wii, desc: "Igre/Wii"}
+      - {id: 30, cat: Books/Comics, desc: "Stripovi"}
+      - {id: 38, cat: PC/Phone-Other, desc: "Smartphone"}
+      - {id: 40, cat: Movies/BluRay, desc: "Filmovi/BD"}
+      - {id: 3, cat: Audio/MP3, desc: "Glazba/MP3"}
+      - {id: 26, cat: Console/Xbox, desc: "Igre/Xbox"}
+      - {id: 10, cat: XXX, desc: "XXX/SD"}
+      - {id: 16, cat: TV, desc: "THR Packs"}
+      - {id: 15, cat: TV/Sport, desc: "Sport"}
+      - {id: 29, cat: Audio/Lossless, desc: "Glazba/FLAC"}
+      - {id: 13, cat: Other, desc: "Ostalo"}
+      - {id: 36, cat: XXX, desc: "XXX/HD"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      ssl: "yes"
+    error:
+      - selector: div.glavni:has(div.glavni_naslov:contains("Greška"))
+    test:
+      path: /browse.php
+      
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      sort: "4"
+      type: "desc"
+    rows:
+      selector: div.glavni_txt > table > tbody > tr[id^="record-"]
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      title|optional|1:
+        selector: a[href^="details.php?id="][title]
+        attribute: title
+      title|optional|2:
+        selector: a[href^="details.php?id="][onmousemove]
+        attribute: onmousemove
+        filters:
+          - name: regexp
+            args: "return overlibImage\\('(.*)','.*'\\);"
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: td.kategorije > a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      files:
+        selector: td:nth-child(5)
+      size:
+        selector: td:nth-child(7)
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+          - name: replace
+            args: [",", ""]
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      banner|optional:
+        selector: a[href^="details.php?id="][onmousemove]
+        attribute: onmousemove
+        filters:
+          - name: regexp
+            args: "return overlibImage\\('.*','(.*)'\\);"
+      downloadvolumefactor:
+        text: "0"
+      uploadvolumefactor:
+        text: "1"
+      date:
+        selector: td:nth-child(2) > small
+        filters:
+          - name: replace
+            args: [" u ", " "]
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "02.01.2006 15:04:05 -07:00"
+      description|optional:
+        selector: td:nth-child(2)
         remove: a, br, small
\ No newline at end of file
diff --git a/src/Jackett/Definitions/torrentsectorcrew.yml b/src/Jackett/Definitions/torrentsectorcrew.yml
index bda41cb6fafaec3d569fe799f29e988dc1527cf0..f7eb896e596f5e07ec9a611bcf7f433f823495dc 100644
--- a/src/Jackett/Definitions/torrentsectorcrew.yml
+++ b/src/Jackett/Definitions/torrentsectorcrew.yml
@@ -1,177 +1,177 @@
----
-  site: torrentsectorcrew
-  name: Torrent Sector Crew
-  description: "A German general tracker"
-  language: de-de
-  type: private
-  encoding: windows-1252
-  links:
-    - https://tsctracker.net/
-
-  caps:
-    categorymappings:
-      # Apps
-      - {id: 65, cat: PC/Phone-Android, desc: "Android"}
-      - {id: 83, cat: PC/Phone-IOS, desc: "iOS"}
-      - {id: 107, cat: PC/0day, desc: "Linux"}
-      - {id: 48, cat: PC/Mac, desc: "MAC"}
-      - {id: 109, cat: PC, desc: "Sonstige"}
-      - {id: 22, cat: PC/0day, desc: "Win"}
-
-      # Audio
-      - {id: 24, cat: Audio/Audiobook, desc: "aBooks"}
-      - {id: 104, cat: Audio, desc: "Disco's"}
-      - {id: 38, cat: Audio/Audiobook, desc: "Hörspiel"}
-      - {id: 6, cat: Audio, desc: "Musik"}
-      - {id: 82, cat: Audio, desc: "Tracks"}
-      - {id: 29, cat: Audio/Video, desc: "Videos"}
-
-      # Doku
-      - {id: 113, cat: TV/Documentary, desc: "3D"}
-      - {id: 76, cat: TV/Documentary, desc: "HD"}
-      - {id: 78, cat: TV/Documentary, desc: "Packs"}
-      - {id: 75, cat: TV/Documentary, desc: "SD"}
-      - {id: 114, cat: TV/Documentary, desc: "Sonstige"}
-      - {id: 77, cat: TV/Documentary, desc: "Untouched"}
-
-      # Filme
-      - {id: 54, cat: Movies/HD, desc: "1080p"}
-      - {id: 5, cat: Movies/3D, desc: "3D"}
-      - {id: 55, cat: Movies/HD, desc: "720p"}
-      - {id: 111, cat: Movies, desc: "Anime"}
-      - {id: 43, cat: Movies/BluRay, desc: "BluRay"}
-      - {id: 20, cat: Movies/DVD, desc: "DVDR"}
-      - {id: 120, cat: Movies/Foreign, desc: "Int."}
-      - {id: 119, cat: Movies, desc: "Remux"}
-      - {id: 121, cat: Movies/HD, desc: "UHD"}
-      - {id: 36, cat: Movies/HD, desc: "x264"}
-      - {id: 19, cat: Movies/SD, desc: "XviD"}
-
-      # Serien
-      - {id: 112, cat: TV/Anime, desc: "Anime"}
-      - {id: 69, cat: TV/HD, desc: "HD"}
-      - {id: 72, cat: TV/Foreign, desc: "Int."}
-      - {id: 68, cat: TV, desc: "Packs"}
-      - {id: 66, cat: TV/SD, desc: "SD"}
-      - {id: 108, cat: TV, desc: "TV-Shows"}
-
-      # Sonstige
-      - {id: 117, cat: Other, desc: "Diverses"}
-      - {id: 28, cat: Books, desc: "eBooks"}
-      - {id: 42, cat: TV/Sport, desc: "Sport"}
-      - {id: 103, cat: Other, desc: "Tutorials"}
-      - {id: 9, cat: Other, desc: "Wallpaper"}
-      - {id: 64, cat: XXX, desc: "XXX"}
-
-      # Spiele
-      - {id: 115, cat: PC/Mac, desc: "MAC"}
-      - {id: 37, cat: Console/NDS, desc: "Nintendo"}
-      - {id: 4, cat: PC/Games, desc: "PC"}
-      - {id: 58, cat: Console/PS4, desc: "PSX"}
-      - {id: 116, cat: Other, desc: "Sonstige"}
-      - {id: 50, cat: Console/Xbox, desc: "XBOX"}
-
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  settings:
-    - name: pin
-      type: text
-      label: Pin
-    - name: username
-      type: text
-      label: Username
-    - name: password
-      type: password
-      label: Password
-
-  login:
-    path: landing.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      pin: "{{ .Config.pin }}"
-    error:
-      - selector: "#login_box_desc"
-    test:
-      path: my.php
-      
-  ratio:
-    path: /my.php
-    selector: td.navi_top:contains("Deine Ratio:")
-    filters:
-      - name: replace
-        args: ["Deine Ratio: ", ""]
-      - name: replace
-        args: [".", ""]
-      - name: replace
-        args: [",", "."]
-
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      orderby: "added"
-      sort: desc
-    rows:
-      selector: "h2 +p + br + table.tablebrowse > tbody > tr[style=\"height: 45px;\"], tr:contains(\"Weiter\") > td > table.tablebrowse > tbody > tr[style=\"height: 45px;\"]"
-    fields:
-      title:
-        selector: a[title][href^="details.php"]
-        attribute: title
-      category:
-        selector: a[href*="cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      comments:
-        selector: a[href*="&tocomm="]
-        attribute: href
-      download:
-        selector: a[href^="download_ssl.php"]
-        attribute: href
-      files:
-        selector: td:nth-child(3)
-      grabs:
-        selector: td:nth-child(9)
-        filters:
-          - name: replace
-            args: ["-mal", ""]
-      size:
-        selector: td:nth-child(6)
-        filters:
-          - name: replace
-            args: [".", ""]
-          - name: replace
-            args: [",", "."]
-      seeders:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      leechers:
-        selector: td:nth-child(8)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      date:
-        selector: td:nth-child(5)
-        remove: br
-        filters:
-          - name: dateparse
-            args: "02.01.200615:04:05"
-      downloadvolumefactor:
-        case:
-          "font:contains(\"[OnlyUpload]\")": "0"
-          "font:contains(\"[-40 Download]\")": "0.6"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: torrentsectorcrew
+  name: Torrent Sector Crew
+  description: "A German general tracker"
+  language: de-de
+  type: private
+  encoding: windows-1252
+  links:
+    - https://tsctracker.net/
+
+  caps:
+    categorymappings:
+      # Apps
+      - {id: 65, cat: PC/Phone-Android, desc: "Android"}
+      - {id: 83, cat: PC/Phone-IOS, desc: "iOS"}
+      - {id: 107, cat: PC/0day, desc: "Linux"}
+      - {id: 48, cat: PC/Mac, desc: "MAC"}
+      - {id: 109, cat: PC, desc: "Sonstige"}
+      - {id: 22, cat: PC/0day, desc: "Win"}
+
+      # Audio
+      - {id: 24, cat: Audio/Audiobook, desc: "aBooks"}
+      - {id: 104, cat: Audio, desc: "Disco's"}
+      - {id: 38, cat: Audio/Audiobook, desc: "Hörspiel"}
+      - {id: 6, cat: Audio, desc: "Musik"}
+      - {id: 82, cat: Audio, desc: "Tracks"}
+      - {id: 29, cat: Audio/Video, desc: "Videos"}
+
+      # Doku
+      - {id: 113, cat: TV/Documentary, desc: "3D"}
+      - {id: 76, cat: TV/Documentary, desc: "HD"}
+      - {id: 78, cat: TV/Documentary, desc: "Packs"}
+      - {id: 75, cat: TV/Documentary, desc: "SD"}
+      - {id: 114, cat: TV/Documentary, desc: "Sonstige"}
+      - {id: 77, cat: TV/Documentary, desc: "Untouched"}
+
+      # Filme
+      - {id: 54, cat: Movies/HD, desc: "1080p"}
+      - {id: 5, cat: Movies/3D, desc: "3D"}
+      - {id: 55, cat: Movies/HD, desc: "720p"}
+      - {id: 111, cat: Movies, desc: "Anime"}
+      - {id: 43, cat: Movies/BluRay, desc: "BluRay"}
+      - {id: 20, cat: Movies/DVD, desc: "DVDR"}
+      - {id: 120, cat: Movies/Foreign, desc: "Int."}
+      - {id: 119, cat: Movies, desc: "Remux"}
+      - {id: 121, cat: Movies/HD, desc: "UHD"}
+      - {id: 36, cat: Movies/HD, desc: "x264"}
+      - {id: 19, cat: Movies/SD, desc: "XviD"}
+
+      # Serien
+      - {id: 112, cat: TV/Anime, desc: "Anime"}
+      - {id: 69, cat: TV/HD, desc: "HD"}
+      - {id: 72, cat: TV/Foreign, desc: "Int."}
+      - {id: 68, cat: TV, desc: "Packs"}
+      - {id: 66, cat: TV/SD, desc: "SD"}
+      - {id: 108, cat: TV, desc: "TV-Shows"}
+
+      # Sonstige
+      - {id: 117, cat: Other, desc: "Diverses"}
+      - {id: 28, cat: Books, desc: "eBooks"}
+      - {id: 42, cat: TV/Sport, desc: "Sport"}
+      - {id: 103, cat: Other, desc: "Tutorials"}
+      - {id: 9, cat: Other, desc: "Wallpaper"}
+      - {id: 64, cat: XXX, desc: "XXX"}
+
+      # Spiele
+      - {id: 115, cat: PC/Mac, desc: "MAC"}
+      - {id: 37, cat: Console/NDS, desc: "Nintendo"}
+      - {id: 4, cat: PC/Games, desc: "PC"}
+      - {id: 58, cat: Console/PS4, desc: "PSX"}
+      - {id: 116, cat: Other, desc: "Sonstige"}
+      - {id: 50, cat: Console/Xbox, desc: "XBOX"}
+
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  settings:
+    - name: pin
+      type: text
+      label: Pin
+    - name: username
+      type: text
+      label: Username
+    - name: password
+      type: password
+      label: Password
+
+  login:
+    path: landing.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      pin: "{{ .Config.pin }}"
+    error:
+      - selector: "#login_box_desc"
+    test:
+      path: my.php
+      
+  ratio:
+    path: /my.php
+    selector: td.navi_top:contains("Deine Ratio:")
+    filters:
+      - name: replace
+        args: ["Deine Ratio: ", ""]
+      - name: replace
+        args: [".", ""]
+      - name: replace
+        args: [",", "."]
+
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      orderby: "added"
+      sort: desc
+    rows:
+      selector: "h2 +p + br + table.tablebrowse > tbody > tr[style=\"height: 45px;\"], tr:contains(\"Weiter\") > td > table.tablebrowse > tbody > tr[style=\"height: 45px;\"]"
+    fields:
+      title:
+        selector: a[title][href^="details.php"]
+        attribute: title
+      category:
+        selector: a[href*="cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      comments:
+        selector: a[href*="&tocomm="]
+        attribute: href
+      download:
+        selector: a[href^="download_ssl.php"]
+        attribute: href
+      files:
+        selector: td:nth-child(3)
+      grabs:
+        selector: td:nth-child(9)
+        filters:
+          - name: replace
+            args: ["-mal", ""]
+      size:
+        selector: td:nth-child(6)
+        filters:
+          - name: replace
+            args: [".", ""]
+          - name: replace
+            args: [",", "."]
+      seeders:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      leechers:
+        selector: td:nth-child(8)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      date:
+        selector: td:nth-child(5)
+        remove: br
+        filters:
+          - name: dateparse
+            args: "02.01.200615:04:05"
+      downloadvolumefactor:
+        case:
+          "font:contains(\"[OnlyUpload]\")": "0"
+          "font:contains(\"[-40 Download]\")": "0.6"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/torrentsmd.yml b/src/Jackett/Definitions/torrentsmd.yml
index ad175c4de996ee10c7ec48e7e8122fe5d7039e2c..4d93772ad1910f4aedc244391ed277b3754ab2cb 100644
--- a/src/Jackett/Definitions/torrentsmd.yml
+++ b/src/Jackett/Definitions/torrentsmd.yml
@@ -1,94 +1,94 @@
----
-  site: torrentsmd
-  name: Torrents.Md
-  language: ru-mo
-  type: private
-  encoding: UTF-8
-  links:
-    - https://torrentsmd.com/
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Movies, desc: "Filme"}
-      - {id: 2, cat: Audio, desc: "Muzică"}
-      - {id: 3, cat: PC, desc: "Software"}
-      - {id: 4, cat: Console, desc: "Jocuri"}
-      - {id: 5, cat: TV, desc: "Tv"}
-      - {id: 7, cat: Other, desc: "Alte"}
-      - {id: 8, cat: Books, desc: "Cărţi"}
-      - {id: 9, cat: Audio/Video, desc: "Muzică video"}
-      - {id: 10, cat: TV/Anime, desc: "Anime"}
-      - {id: 11, cat: Movies, desc: "Filme animate"}
-      - {id: 12, cat: Movies/DVD, desc: "DVD"}
-      - {id: 13, cat: Movies, desc: "Filme documentare"}
-      - {id: 14, cat: Audio/Audiobook, desc: "Cărţi audio"}
-      - {id: 15, cat: Other, desc: "Lecţii video"}
-      - {id: 16, cat: Other, desc: "Fotografii"}
-      - {id: 17, cat: TV/Sport, desc: "Sport"}
-      - {id: 18, cat: TV/HD, desc: "HDTV"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: login.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("eşuată"))
-    test:
-      path: browse.php
-      
-  search:
-    path: "{{if .Query.Keywords}}search.php{{else}}browse.php{{end}}"
-    inputs:
-      search_str: "{{ .Query.Keywords }}"
-    rows:
-      selector: table.tableTorrents > tbody > tr:has(a[href^="/details.php?id="])
-    fields:
-      title:
-        selector: a[href^="/details.php?id="]
-      details:
-        selector: a[href^="/details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="/details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["/details.php", "/download.php"]
-      files:
-        selector: td:nth-child(3)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: replace
-            args: ["ore", "hours ago"]
-          - name: replace
-            args: ["minute", "minutes ago"]
-          - name: dateparse
-            args: "01-02 2006"
-          - name: dateparse
-            args: "01-02"
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: torrentsmd
+  name: Torrents.Md
+  language: ru-mo
+  type: private
+  encoding: UTF-8
+  links:
+    - https://torrentsmd.com/
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Movies, desc: "Filme"}
+      - {id: 2, cat: Audio, desc: "Muzică"}
+      - {id: 3, cat: PC, desc: "Software"}
+      - {id: 4, cat: Console, desc: "Jocuri"}
+      - {id: 5, cat: TV, desc: "Tv"}
+      - {id: 7, cat: Other, desc: "Alte"}
+      - {id: 8, cat: Books, desc: "Cărţi"}
+      - {id: 9, cat: Audio/Video, desc: "Muzică video"}
+      - {id: 10, cat: TV/Anime, desc: "Anime"}
+      - {id: 11, cat: Movies, desc: "Filme animate"}
+      - {id: 12, cat: Movies/DVD, desc: "DVD"}
+      - {id: 13, cat: Movies, desc: "Filme documentare"}
+      - {id: 14, cat: Audio/Audiobook, desc: "Cărţi audio"}
+      - {id: 15, cat: Other, desc: "Lecţii video"}
+      - {id: 16, cat: Other, desc: "Fotografii"}
+      - {id: 17, cat: TV/Sport, desc: "Sport"}
+      - {id: 18, cat: TV/HD, desc: "HDTV"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: login.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("eşuată"))
+    test:
+      path: browse.php
+      
+  search:
+    path: "{{if .Query.Keywords}}search.php{{else}}browse.php{{end}}"
+    inputs:
+      search_str: "{{ .Query.Keywords }}"
+    rows:
+      selector: table.tableTorrents > tbody > tr:has(a[href^="/details.php?id="])
+    fields:
+      title:
+        selector: a[href^="/details.php?id="]
+      details:
+        selector: a[href^="/details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="/details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["/details.php", "/download.php"]
+      files:
+        selector: td:nth-child(3)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: replace
+            args: ["ore", "hours ago"]
+          - name: replace
+            args: ["minute", "minutes ago"]
+          - name: dateparse
+            args: "01-02 2006"
+          - name: dateparse
+            args: "01-02"
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/torviet.yml b/src/Jackett/Definitions/torviet.yml
index f4e752430b29a48bb3f8606b90e518e22475674a..737f057567d613026768c2c432ddbbd0786d83f6 100644
--- a/src/Jackett/Definitions/torviet.yml
+++ b/src/Jackett/Definitions/torviet.yml
@@ -1,131 +1,131 @@
----
-  site: torviet
-  name: TorViet
-  language: vi-vn
-  type: private
-  encoding: UTF-8
-  links:
-    - http://torviet.com
-
-  caps:
-    categorymappings:
-      - {id: 1, cat: Console, desc: "Game"}
-      - {id: 7, cat: PC/Games, desc: "PC"}
-      - {id: 133, cat: PC/Phone-Other, desc: "Handheld"}
-      - {id: 132, cat: Console, desc: "Console"}
-
-      - {id: 2, cat: Movies, desc: "Movie"}
-      - {id: 23, cat: Movies/HD, desc: "mHD"}
-      - {id: 24, cat: Movies/SD, desc: "SD"}
-      - {id: 124, cat: Movies/HD, desc: "720p"}
-      - {id: 125, cat: Movies/HD, desc: "1080p"}
-      - {id: 127, cat: Movies/BluRay, desc: "Blu-ray"}
-
-      - {id: 3, cat: TV, desc: "TV"}
-      - {id: 128, cat: TV/HD, desc: "HD"}
-      - {id: 129, cat: TV/SD, desc: "SD"}
-
-      - {id: 4, cat: PC, desc: "Software"}
-      - {id: 76, cat: PC/0day, desc: "Windows"}
-      - {id: 77, cat: PC/Mac, desc: "MAC"}
-      - {id: 78, cat: PC, desc: "Linux"}
-      - {id: 79, cat: PC/Phone-Other, desc: "Handheld"}
-
-      - {id: 5, cat: Audio, desc: "Music"}
-      - {id: 92, cat: Audio/Video, desc: "Music Video"}
-      - {id: 126, cat: Audio/Lossless, desc: "Lossless"}
-      - {id: 130, cat: Audio/MP3, desc: "Lossy"}
-      - {id: 131, cat: Audio, desc: "Surround"}
-
-      - {id: 6, cat: Other, desc: "Misc"}
-      - {id: 112, cat: Books, desc: "Ebook"}
-      - {id: 113, cat: Other, desc: "Training Video"}
-      - {id: 117, cat: Audio/Audiobook, desc: "Audio book"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep, imdbid]
-      movie-search: [q, imdbid]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /torrents.php
-      
-  ratio:
-    path: /torrents.php
-    selector: table#info_block
-    filters:
-      - name: regexp
-        args: "Ratio:\\s(.*?)\\s\\s"
-
-  search:
-    path: /torrents.php
-    inputs:
-      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
-      sltCategory: 0
-      sltSubCategory: 0 # can't sepcify multiple categorys so we're useing all always
-      sltGenre: 0
-      incldead: 1
-      spstate: 0
-      inclbookmarked: 0
-      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
-      search_mode: 0
-
-    rows:
-      selector: div#idtorrent > table.torrents > tbody > tr:has(table.torrentname)
-    fields:
-      title:
-        selector: a[class][title]
-        attribute: title
-      details:
-        selector: a[class][title]
-        attribute: href
-      description:
-        selector: td.embedded:has(a[title])
-        remove: a[title]
-      category: 
-        selector: a[href^="/torrents.php?sltSubCategory="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: sltSubCategory
-      comments:
-        selector: td:nth-child(3) a
-        attribute: href
-      download:
-        selector: a[href^="/download.php?"]
-        attribute: href
-      size:
-        selector: td:nth-child(5)
-      seeders:
-        selector: td:nth-child(6)
-      leechers:
-        selector: td:nth-child(7)
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: append
-            args: " ago"
-      grabs:
-        selector: td:nth-child(8)
-      downloadvolumefactor:
-        case:
-          img.pro_free: "0"
-          img.pro_free2up: "0"
-          img.pro_50pctdown: "0.5"
-          img.pro_50pctdown2up: "0.5"
-          img.pro_30pctdown: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img.pro_50pctdown2up: "2"
-          img.pro_free2up: "2"
-          img.pro_2up: "2"
+---
+  site: torviet
+  name: TorViet
+  language: vi-vn
+  type: private
+  encoding: UTF-8
+  links:
+    - http://torviet.com
+
+  caps:
+    categorymappings:
+      - {id: 1, cat: Console, desc: "Game"}
+      - {id: 7, cat: PC/Games, desc: "PC"}
+      - {id: 133, cat: PC/Phone-Other, desc: "Handheld"}
+      - {id: 132, cat: Console, desc: "Console"}
+
+      - {id: 2, cat: Movies, desc: "Movie"}
+      - {id: 23, cat: Movies/HD, desc: "mHD"}
+      - {id: 24, cat: Movies/SD, desc: "SD"}
+      - {id: 124, cat: Movies/HD, desc: "720p"}
+      - {id: 125, cat: Movies/HD, desc: "1080p"}
+      - {id: 127, cat: Movies/BluRay, desc: "Blu-ray"}
+
+      - {id: 3, cat: TV, desc: "TV"}
+      - {id: 128, cat: TV/HD, desc: "HD"}
+      - {id: 129, cat: TV/SD, desc: "SD"}
+
+      - {id: 4, cat: PC, desc: "Software"}
+      - {id: 76, cat: PC/0day, desc: "Windows"}
+      - {id: 77, cat: PC/Mac, desc: "MAC"}
+      - {id: 78, cat: PC, desc: "Linux"}
+      - {id: 79, cat: PC/Phone-Other, desc: "Handheld"}
+
+      - {id: 5, cat: Audio, desc: "Music"}
+      - {id: 92, cat: Audio/Video, desc: "Music Video"}
+      - {id: 126, cat: Audio/Lossless, desc: "Lossless"}
+      - {id: 130, cat: Audio/MP3, desc: "Lossy"}
+      - {id: 131, cat: Audio, desc: "Surround"}
+
+      - {id: 6, cat: Other, desc: "Misc"}
+      - {id: 112, cat: Books, desc: "Ebook"}
+      - {id: 113, cat: Other, desc: "Training Video"}
+      - {id: 117, cat: Audio/Audiobook, desc: "Audio book"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep, imdbid]
+      movie-search: [q, imdbid]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /torrents.php
+      
+  ratio:
+    path: /torrents.php
+    selector: table#info_block
+    filters:
+      - name: regexp
+        args: "Ratio:\\s(.*?)\\s\\s"
+
+  search:
+    path: /torrents.php
+    inputs:
+      search: "{{if .Query.IMDBID}}{{ .Query.IMDBID }}{{else}}{{ .Keywords }}{{end}}"
+      sltCategory: 0
+      sltSubCategory: 0 # can't sepcify multiple categorys so we're useing all always
+      sltGenre: 0
+      incldead: 1
+      spstate: 0
+      inclbookmarked: 0
+      search_area: "{{ if .Query.IMDBID }}4{{else}}0{{end}}"
+      search_mode: 0
+
+    rows:
+      selector: div#idtorrent > table.torrents > tbody > tr:has(table.torrentname)
+    fields:
+      title:
+        selector: a[class][title]
+        attribute: title
+      details:
+        selector: a[class][title]
+        attribute: href
+      description:
+        selector: td.embedded:has(a[title])
+        remove: a[title]
+      category: 
+        selector: a[href^="/torrents.php?sltSubCategory="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: sltSubCategory
+      comments:
+        selector: td:nth-child(3) a
+        attribute: href
+      download:
+        selector: a[href^="/download.php?"]
+        attribute: href
+      size:
+        selector: td:nth-child(5)
+      seeders:
+        selector: td:nth-child(6)
+      leechers:
+        selector: td:nth-child(7)
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: append
+            args: " ago"
+      grabs:
+        selector: td:nth-child(8)
+      downloadvolumefactor:
+        case:
+          img.pro_free: "0"
+          img.pro_free2up: "0"
+          img.pro_50pctdown: "0.5"
+          img.pro_50pctdown2up: "0.5"
+          img.pro_30pctdown: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img.pro_50pctdown2up: "2"
+          img.pro_free2up: "2"
+          img.pro_2up: "2"
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/totheglory.yml b/src/Jackett/Definitions/totheglory.yml
index ac84a53bcddd63b6e71e6123df8a8a514ee68437..0bd0dc7ad7dba099cb6a261687b2e474860d5aa5 100644
--- a/src/Jackett/Definitions/totheglory.yml
+++ b/src/Jackett/Definitions/totheglory.yml
@@ -1,146 +1,146 @@
----
-  site: totheglory
-  name: ToTheGlory
-  description: "A chinese tracker"
-  language: zh-cn
-  type: private
-  encoding: UTF-8
-  links:
-    - https://totheglory.im/
-
-  caps:
-    categories:
-      # 电影
-      电影DVDRip: Movies/SD # Movie DVDRip
-      电影720p: Movies/HD # Movie 720p
-      电影1080i/p: Movies/HD # Movie 1080i / p
-      BluRay原盘: Movies/BluRay # BluRay original disc
-
-      # 纪录片
-      纪录片720p: Movies/HD # Documentary 720p
-      纪录片1080i/p: Movies/HD # Documentary 1080i / p
-      纪录片BluRay原盘: Movies/BluRay # Documentary BluRay Original
-
-      # 剧集
-      欧美剧720p: TV/HD # 欧美剧720p
-      欧美剧1080i/p: TV/HD # 欧美剧1080i/p
-      高清日剧: TV/HD # 高清日剧
-      大陆港台剧1080i/p: TV/HD # 大陆港台剧1080i/p
-      大陆港台剧720p: TV/HD # 大陆港台剧720p
-      高清韩剧: TV/HD # 高清韩剧
-
-      # 剧集包
-      欧美剧包: TV/HD # 欧美剧包
-      日剧包: TV/HD # 日剧包
-      韩剧包: TV/HD # 韩剧包
-      华语剧包: TV/HD # 华语剧包
-
-      # 音乐
-      (电影原声&Game)OST: Audio # (电影原声&Game)OST
-      无损音乐FLAC&APE: Audio/Lossless  # 无损音乐FLAC&APE
-      MV&amp;演唱会: Audio/Video # MV&演唱会
-
-      # 其他
-      高清体育节目: TV/Sport # High-definition sports programs
-      高清动漫: TV/Anime # HD animation
-      韩国综艺: TV/HD # South Korea Variety
-      日本综艺: TV/HD # Japanese variety
-      高清综艺: TV/HD # HD Variety
-      MiniVideo: Other # MiniVideo
-      补充音轨: Audio # Supplemental audio tracks
-      iPhone/iPad视频: PC/Phone-Other # IPhone / iPad video
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /login.php?returnto=
-    method: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: form#loginform > span.warning
-    test:
-      path: /my.php
-
-  ratio:
-    path: /my.php
-    selector: span.smallfont:has(span#sp_signed)
-    filters:
-      - name: regexp
-        args: "分享率 : (.*?)\u00a0\u00a0"
-
-  search:
-    path: /browse.php
-    inputs:
-      search_field: "{{range .Categories}}分类:`{{.}}` {{end}}{{ .Query.Keywords }}"
-      c: "M"
-    rows:
-      selector: table#torrent_table > tbody > tr[id]
-    fields:
-      description:
-        selector: div.name_left > a > b
-      title:
-        selector: div.name_left > a > b
-        remove: span
-      category:
-        selector: tr[id] td:nth-child(1) > a
-        attribute: href
-        filters:
-          - name: querystring
-            args: search_field
-          - name: replace
-            args: ["category:", ""]
-          - name: trim
-            args: "\""
-      details:
-        selector: div.name_left > a
-        attribute: href
-      download:
-        selector: a.dl_a
-        attribute: href
-        filters:
-          - name: regexp
-            args: "^(/download.php/\\d+/).*" # cut off download url after ID to avoid bad request errors with curl
-      files:
-        selector: td:nth-child(3)
-      size:
-        selector: td:nth-child(7)
-      seeders:
-        selector: td:nth-child(9)
-        filters:
-          - name: split
-            args: ["/", 0]
-      leechers:
-        selector: td:nth-child(9)
-        filters:
-          - name: split
-            args: ["/", 1]
-          - name: replace
-            args: ["\n", ""]
-      grabs:
-        selector: td:nth-child(8)
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " +0800"
-          - name: dateparse
-            args: "2006-01-0215:04:05 -0700"
-      imdb:
-        selector: span.imdb_rate > a
-        attribute: href
-      downloadvolumefactor:
-        case:
-          img[alt="free"]: "0"
-          img[alt="50%"]: "0.5"
-          img[alt="30%"]: "0.3"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: totheglory
+  name: ToTheGlory
+  description: "A chinese tracker"
+  language: zh-cn
+  type: private
+  encoding: UTF-8
+  links:
+    - https://totheglory.im/
+
+  caps:
+    categories:
+      # 电影
+      电影DVDRip: Movies/SD # Movie DVDRip
+      电影720p: Movies/HD # Movie 720p
+      电影1080i/p: Movies/HD # Movie 1080i / p
+      BluRay原盘: Movies/BluRay # BluRay original disc
+
+      # 纪录片
+      纪录片720p: Movies/HD # Documentary 720p
+      纪录片1080i/p: Movies/HD # Documentary 1080i / p
+      纪录片BluRay原盘: Movies/BluRay # Documentary BluRay Original
+
+      # 剧集
+      欧美剧720p: TV/HD # 欧美剧720p
+      欧美剧1080i/p: TV/HD # 欧美剧1080i/p
+      高清日剧: TV/HD # 高清日剧
+      大陆港台剧1080i/p: TV/HD # 大陆港台剧1080i/p
+      大陆港台剧720p: TV/HD # 大陆港台剧720p
+      高清韩剧: TV/HD # 高清韩剧
+
+      # 剧集包
+      欧美剧包: TV/HD # 欧美剧包
+      日剧包: TV/HD # 日剧包
+      韩剧包: TV/HD # 韩剧包
+      华语剧包: TV/HD # 华语剧包
+
+      # 音乐
+      (电影原声&Game)OST: Audio # (电影原声&Game)OST
+      无损音乐FLAC&APE: Audio/Lossless  # 无损音乐FLAC&APE
+      MV&amp;演唱会: Audio/Video # MV&演唱会
+
+      # 其他
+      高清体育节目: TV/Sport # High-definition sports programs
+      高清动漫: TV/Anime # HD animation
+      韩国综艺: TV/HD # South Korea Variety
+      日本综艺: TV/HD # Japanese variety
+      高清综艺: TV/HD # HD Variety
+      MiniVideo: Other # MiniVideo
+      补充音轨: Audio # Supplemental audio tracks
+      iPhone/iPad视频: PC/Phone-Other # IPhone / iPad video
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /login.php?returnto=
+    method: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: form#loginform > span.warning
+    test:
+      path: /my.php
+
+  ratio:
+    path: /my.php
+    selector: span.smallfont:has(span#sp_signed)
+    filters:
+      - name: regexp
+        args: "分享率 : (.*?)\u00a0\u00a0"
+
+  search:
+    path: /browse.php
+    inputs:
+      search_field: "{{range .Categories}}分类:`{{.}}` {{end}}{{ .Query.Keywords }}"
+      c: "M"
+    rows:
+      selector: table#torrent_table > tbody > tr[id]
+    fields:
+      description:
+        selector: div.name_left > a > b
+      title:
+        selector: div.name_left > a > b
+        remove: span
+      category:
+        selector: tr[id] td:nth-child(1) > a
+        attribute: href
+        filters:
+          - name: querystring
+            args: search_field
+          - name: replace
+            args: ["category:", ""]
+          - name: trim
+            args: "\""
+      details:
+        selector: div.name_left > a
+        attribute: href
+      download:
+        selector: a.dl_a
+        attribute: href
+        filters:
+          - name: regexp
+            args: "^(/download.php/\\d+/).*" # cut off download url after ID to avoid bad request errors with curl
+      files:
+        selector: td:nth-child(3)
+      size:
+        selector: td:nth-child(7)
+      seeders:
+        selector: td:nth-child(9)
+        filters:
+          - name: split
+            args: ["/", 0]
+      leechers:
+        selector: td:nth-child(9)
+        filters:
+          - name: split
+            args: ["/", 1]
+          - name: replace
+            args: ["\n", ""]
+      grabs:
+        selector: td:nth-child(8)
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " +0800"
+          - name: dateparse
+            args: "2006-01-0215:04:05 -0700"
+      imdb:
+        selector: span.imdb_rate > a
+        attribute: href
+      downloadvolumefactor:
+        case:
+          img[alt="free"]: "0"
+          img[alt="50%"]: "0.5"
+          img[alt="30%"]: "0.3"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/uhdbits.yml b/src/Jackett/Definitions/uhdbits.yml
index e399d47929132fa224d688bb79dacabbdcd5b757..daadb5048d83503adc9a122821fa4dbcbe44fd51 100644
--- a/src/Jackett/Definitions/uhdbits.yml
+++ b/src/Jackett/Definitions/uhdbits.yml
@@ -1,134 +1,134 @@
----
-  site: uhdbits
-  name: UHDBits
-  description: "A vietnamese general tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://uhdbits.org/
-
-  caps:
-    categories:
-      1: Movies
-      2: Audio
-      3: TV
-      4: Audio
-      5: PC
-      6: Other
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q, imdbid]
-
-  login:
-    path: /login.php
-    form: form.auth_form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      keeplogged: "1"
-    error:
-    - selector: .auth_form > .warning
-      message:
-        selector: ".auth_form > .warning"
-    test:
-      path: /top10.php
-
-  ratio:
-    path: /top10.php
-    selector: span.r99
-
-  search:
-    path: /torrents.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      searchstr: "{{if .Query.IMDBID}}{{else}}{{ .Query.Keywords }}{{end}}"
-      imdbid: "{{ .Query.IMDBIDShort }}"
-      tags_type: "1"
-      order_by: "time"
-      order_way: "desc"
-      action: "advanced"
-      searchsubmit: "1"
-
-    rows:
-      selector: table#torrent_table > tbody > tr.torrent
-    fields:
-      # note: there are optinal extra colums
-      download:
-        selector: a[title="Download"]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["\t", " "]
-      title:
-        selector: div.group_info
-        remove: span, div.tags
-        filters:
-          - name: replace
-            args: [" / Free", ""]
-          - name: replace
-            args: [" / ViE", ""]
-          - name: replace
-            args: [" / User", ""]
-          - name: replace
-            args: [" / Exclusive!", ""]
-          - name: replace
-            args: [" / ↓25%", ""]
-          - name: replace
-            args: [" / ↓50%", ""]
-          - name: replace
-            args: [" / ↓75%", ""]
-          - name: replace
-            args: [" / 2x 50%", ""]
-          - name: replace
-            args: [" / 2x Free", ""]
-          - name: replace
-            args: [" / 2x", ""]
-      downloadvolumefactor:
-        case:
-          "strong.blink_me:contains(\"Free\")": "0"
-          "strong.blink_me:contains(\"50\")": "0.5"
-          "strong.blink_me:contains(\"25\")": "0.75"
-          "strong.blink_me:contains(\"75\")": "0.25"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "strong.blink_me:contains(\"2x\")": "2"
-          "*": "1"
-      category:
-        selector: a[href^="torrents.php?filter_cat"]
-        attribute: href
-        filters:
-          - name: regexp
-            args: "\\[(\\d+?)\\]"
-      comments:
-        selector: a.torrent_name
-        attribute: href
-        filters:
-          - name: replace
-            args: ["\t", " "]
-      details:
-        selector: a.torrent_name
-        attribute: href
-        filters:
-          - name: replace
-            args: ["\t", " "]
-          - name: regexp
-            args: (.*)#torrent\d+$
-      size:
-        selector: td[class="number_column nobr"]
-      grabs:
-        selector: td[class="number_column nobr"] ~ td
-      files:
-        selector: td:nth-child(3)
-      seeders:
-        selector: td[class="number_column nobr"] ~ td ~ td
-      leechers:
-        selector: td[class="number_column nobr"] ~ td ~ td ~ td
-      date:
-        selector: td:nth-child(4)
-        filters:
-          - name: append
-            args: " ago"
+---
+  site: uhdbits
+  name: UHDBits
+  description: "A vietnamese general tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://uhdbits.org/
+
+  caps:
+    categories:
+      1: Movies
+      2: Audio
+      3: TV
+      4: Audio
+      5: PC
+      6: Other
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q, imdbid]
+
+  login:
+    path: /login.php
+    form: form.auth_form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      keeplogged: "1"
+    error:
+    - selector: .auth_form > .warning
+      message:
+        selector: ".auth_form > .warning"
+    test:
+      path: /top10.php
+
+  ratio:
+    path: /top10.php
+    selector: span.r99
+
+  search:
+    path: /torrents.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      searchstr: "{{if .Query.IMDBID}}{{else}}{{ .Query.Keywords }}{{end}}"
+      imdbid: "{{ .Query.IMDBIDShort }}"
+      tags_type: "1"
+      order_by: "time"
+      order_way: "desc"
+      action: "advanced"
+      searchsubmit: "1"
+
+    rows:
+      selector: table#torrent_table > tbody > tr.torrent
+    fields:
+      # note: there are optinal extra colums
+      download:
+        selector: a[title="Download"]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["\t", " "]
+      title:
+        selector: div.group_info
+        remove: span, div.tags
+        filters:
+          - name: replace
+            args: [" / Free", ""]
+          - name: replace
+            args: [" / ViE", ""]
+          - name: replace
+            args: [" / User", ""]
+          - name: replace
+            args: [" / Exclusive!", ""]
+          - name: replace
+            args: [" / ↓25%", ""]
+          - name: replace
+            args: [" / ↓50%", ""]
+          - name: replace
+            args: [" / ↓75%", ""]
+          - name: replace
+            args: [" / 2x 50%", ""]
+          - name: replace
+            args: [" / 2x Free", ""]
+          - name: replace
+            args: [" / 2x", ""]
+      downloadvolumefactor:
+        case:
+          "strong.blink_me:contains(\"Free\")": "0"
+          "strong.blink_me:contains(\"50\")": "0.5"
+          "strong.blink_me:contains(\"25\")": "0.75"
+          "strong.blink_me:contains(\"75\")": "0.25"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "strong.blink_me:contains(\"2x\")": "2"
+          "*": "1"
+      category:
+        selector: a[href^="torrents.php?filter_cat"]
+        attribute: href
+        filters:
+          - name: regexp
+            args: "\\[(\\d+?)\\]"
+      comments:
+        selector: a.torrent_name
+        attribute: href
+        filters:
+          - name: replace
+            args: ["\t", " "]
+      details:
+        selector: a.torrent_name
+        attribute: href
+        filters:
+          - name: replace
+            args: ["\t", " "]
+          - name: regexp
+            args: (.*)#torrent\d+$
+      size:
+        selector: td[class="number_column nobr"]
+      grabs:
+        selector: td[class="number_column nobr"] ~ td
+      files:
+        selector: td:nth-child(3)
+      seeders:
+        selector: td[class="number_column nobr"] ~ td ~ td
+      leechers:
+        selector: td[class="number_column nobr"] ~ td ~ td ~ td
+      date:
+        selector: td:nth-child(4)
+        filters:
+          - name: append
+            args: " ago"
diff --git a/src/Jackett/Definitions/ultimategamerclub.yml b/src/Jackett/Definitions/ultimategamerclub.yml
index b8fffe3f68be80eb88cbce09191c0c8e3fb2edc9..292652d5f6ee16f4b98ce55c4efb7d2e42c6471b 100644
--- a/src/Jackett/Definitions/ultimategamerclub.yml
+++ b/src/Jackett/Definitions/ultimategamerclub.yml
@@ -1,125 +1,125 @@
----
-  site: ultimategamerclub
-  name: Ultimate Gamer Club
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://ultimategamer.club/
-
-  caps:
-    categorymappings:
-      # Computer
-      - {id: 10, cat: PC/Games, desc: "Windows"}
-      - {id: 11, cat: PC/Mac, desc: "Macintosh"}
-      - {id: 47, cat: PC, desc: "Linux"}
-      - {id: 56, cat: PC, desc: "VR"}
-      # Microsoft
-      - {id: 14, cat: Console/Xbox, desc: "Xbox"}
-      - {id: 61, cat: Console/Xbox360, desc: "Xbox 360"}
-      - {id: 62, cat: Console/XboxOne, desc: "Xbox One"}
-      # Sony
-      - {id: 43, cat: Console/PS3, desc: "Playstation "}
-      - {id: 63, cat: Console/PS3, desc: "Playstation 2"}
-      - {id: 64, cat: Console/PS3, desc: "Playstation 3"}
-      - {id: 67, cat: Console/PS4, desc: "Playstation 4"}
-      - {id: 12, cat: Console/Other, desc: "PSN"}
-      # Nintendo
-      - {id: 57, cat: Console/Other, desc: "Gamecube"}
-      - {id: 44, cat: Console/Wii, desc: "Wii"}
-      - {id: 46, cat: Console/Wii, desc: "Wii U"}
-      # Handheld
-      - {id: 15, cat: Console/NDS, desc: "DS"}
-      - {id: 68, cat: Console/NDS, desc: "3DS"}
-      - {id: 69, cat: Console/PSP, desc: "PSP"}
-      - {id: 70, cat: Console/PSVita, desc: "PSVita"}
-      # Mobile
-      - {id: 65, cat: PC/Phone-IOS, desc: "iOS"}
-      - {id: 49, cat: PC/Phone-Android, desc: "Android"}
-      - {id: 66, cat: PC/Phone-Other, desc: "Windows Mobile"}
-      # Reading
-      - {id: 53, cat: Books, desc: "Books/Mags"}
-      - {id: 60, cat: Books, desc: "Comics"}
-      - {id: 17, cat: Books, desc: "Guides"}
-      # Media
-      - {id: 58, cat: Audio/Video, desc: "Gaming Videos"}
-      - {id: 52, cat: Audio, desc: "OST"}
-      - {id: 55, cat: Other, desc: "Time for a Break"}
-      # Various
-      - {id: 59, cat: Other, desc: "Mods"}
-      - {id: 54, cat: Other, desc: "Updates/Fixes"}
-      - {id: 71, cat: PC/0day, desc: "Applications/Tools"}
-      - {id: 48, cat: Other, desc: "Retro"}
-      - {id: 72, cat: Other, desc: "Board Games"}
-      - {id: 75, cat: Other, desc: "Paper Crafting"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: account-login.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.errFrame
-    test:
-      path: torrents-search.php
-
-  search:
-    path: torrents-search.php
-    keywordsfilters: 
-      - name: re_replace
-        args: ["[^a-zA-Z0-9]+", "+"]
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-    rows:
-      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
-      filters:
-        - name: andmatch
-    fields:
-      download:
-        selector: a[href^="download.php?id="]
-        attribute: href
-      title:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: title
-      category:
-        selector: a[href^="torrents.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      details:
-        selector: a[href^="torrents-details.php?id="]
-        attribute: href
-      date:
-        selector: td:nth-child(2) span:contains("Added:")
-        filters:
-          - name: replace
-            args: ["Added: ", ""]
-          - name: replace
-            args: [" at", ""]
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "02/01/2006 15:04:05 -07:00"
-      size:
-        selector: td:nth-child(7)
-      grabs:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(9)
-      leechers:
-        selector: td:nth-child(10)
-      downloadvolumefactor:
-        case:
-          ":root:has(globnfo:contains(\"sitewide freeleech\"))": "0"
-          img[title="freeleech"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: ultimategamerclub
+  name: Ultimate Gamer Club
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://ultimategamer.club/
+
+  caps:
+    categorymappings:
+      # Computer
+      - {id: 10, cat: PC/Games, desc: "Windows"}
+      - {id: 11, cat: PC/Mac, desc: "Macintosh"}
+      - {id: 47, cat: PC, desc: "Linux"}
+      - {id: 56, cat: PC, desc: "VR"}
+      # Microsoft
+      - {id: 14, cat: Console/Xbox, desc: "Xbox"}
+      - {id: 61, cat: Console/Xbox360, desc: "Xbox 360"}
+      - {id: 62, cat: Console/XboxOne, desc: "Xbox One"}
+      # Sony
+      - {id: 43, cat: Console/PS3, desc: "Playstation "}
+      - {id: 63, cat: Console/PS3, desc: "Playstation 2"}
+      - {id: 64, cat: Console/PS3, desc: "Playstation 3"}
+      - {id: 67, cat: Console/PS4, desc: "Playstation 4"}
+      - {id: 12, cat: Console/Other, desc: "PSN"}
+      # Nintendo
+      - {id: 57, cat: Console/Other, desc: "Gamecube"}
+      - {id: 44, cat: Console/Wii, desc: "Wii"}
+      - {id: 46, cat: Console/Wii, desc: "Wii U"}
+      # Handheld
+      - {id: 15, cat: Console/NDS, desc: "DS"}
+      - {id: 68, cat: Console/NDS, desc: "3DS"}
+      - {id: 69, cat: Console/PSP, desc: "PSP"}
+      - {id: 70, cat: Console/PSVita, desc: "PSVita"}
+      # Mobile
+      - {id: 65, cat: PC/Phone-IOS, desc: "iOS"}
+      - {id: 49, cat: PC/Phone-Android, desc: "Android"}
+      - {id: 66, cat: PC/Phone-Other, desc: "Windows Mobile"}
+      # Reading
+      - {id: 53, cat: Books, desc: "Books/Mags"}
+      - {id: 60, cat: Books, desc: "Comics"}
+      - {id: 17, cat: Books, desc: "Guides"}
+      # Media
+      - {id: 58, cat: Audio/Video, desc: "Gaming Videos"}
+      - {id: 52, cat: Audio, desc: "OST"}
+      - {id: 55, cat: Other, desc: "Time for a Break"}
+      # Various
+      - {id: 59, cat: Other, desc: "Mods"}
+      - {id: 54, cat: Other, desc: "Updates/Fixes"}
+      - {id: 71, cat: PC/0day, desc: "Applications/Tools"}
+      - {id: 48, cat: Other, desc: "Retro"}
+      - {id: 72, cat: Other, desc: "Board Games"}
+      - {id: 75, cat: Other, desc: "Paper Crafting"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: account-login.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.errFrame
+    test:
+      path: torrents-search.php
+
+  search:
+    path: torrents-search.php
+    keywordsfilters: 
+      - name: re_replace
+        args: ["[^a-zA-Z0-9]+", "+"]
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+    rows:
+      selector: table.ttable_headinner > tbody > tr[class^="t-row"]
+      filters:
+        - name: andmatch
+    fields:
+      download:
+        selector: a[href^="download.php?id="]
+        attribute: href
+      title:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: title
+      category:
+        selector: a[href^="torrents.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      details:
+        selector: a[href^="torrents-details.php?id="]
+        attribute: href
+      date:
+        selector: td:nth-child(2) span:contains("Added:")
+        filters:
+          - name: replace
+            args: ["Added: ", ""]
+          - name: replace
+            args: [" at", ""]
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "02/01/2006 15:04:05 -07:00"
+      size:
+        selector: td:nth-child(7)
+      grabs:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(9)
+      leechers:
+        selector: td:nth-child(10)
+      downloadvolumefactor:
+        case:
+          ":root:has(globnfo:contains(\"sitewide freeleech\"))": "0"
+          img[title="freeleech"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/utorrents.yml b/src/Jackett/Definitions/utorrents.yml
index 613742be6afa12bf7151c54eb44c69785e7f189b..2562e394e3747c6d9b89e6a3cde1ca23b9b274d3 100644
--- a/src/Jackett/Definitions/utorrents.yml
+++ b/src/Jackett/Definitions/utorrents.yml
@@ -1,128 +1,128 @@
----
-  site: utorrents
-  name: u-Torrent
-  language: ro-ro
-  type: private
-  encoding: windows-1252
-  links:
-    - http://www.u-torrents.ro/
-
-  caps:
-    categorymappings:
-      - {id: 48, cat: Movies/3D, desc: "3D"}
-      - {id: 1, cat: PC/0day, desc: "Appz"}
-      - {id: 3, cat: Other, desc: "Cartoons"}
-      - {id: 42, cat: TV/Documentary, desc: "Documentaries"}
-      - {id: 6, cat: Books, desc: "eBooks"}
-      - {id: 11, cat: PC/Games, desc: "Games | PC"}
-      - {id: 12, cat: Console/PS3, desc: "Games | PS2"}
-      - {id: 36, cat: Console/PS3, desc: "Games | PS3"}
-      - {id: 40, cat: Console/PSP, desc: "Games | PSP"}
-      - {id: 25, cat: Console/Wii, desc: "Games | Wii"}
-      - {id: 16, cat: Console/Xbox, desc: "Games | XBOX"}
-      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 43, cat: Movies/BluRay, desc: "Movies | Blu-Ray"}
-      - {id: 49, cat: Movies/BluRay, desc: "Movies | Blu-Ray-RO"}
-      - {id: 7, cat: Movies/DVD, desc: "Movies | DVD-R"}
-      - {id: 2, cat: Movies/DVD, desc: "Movies | DVD-RO"}
-      - {id: 17, cat: Movies/HD, desc: "Movies | HD"}
-      - {id: 45, cat: Movies/HD, desc: "Movies | HD-RO"}
-      - {id: 21, cat: Movies, desc: "Movies | Oldies"}
-      - {id: 38, cat: Movies, desc: "Movies | Packs"}
-      - {id: 8, cat: Movies/SD, desc: "Movies | x264"}
-      - {id: 4, cat: Movies/SD, desc: "Movies | x264-RO"}
-      - {id: 10, cat: Movies/SD, desc: "Movies | XviD"}
-      - {id: 44, cat: Movies/SD, desc: "Movies | XviD-RO"}
-      - {id: 5, cat: Audio/MP3, desc: "Music | Mp3"}
-      - {id: 39, cat: Audio, desc: "Music | Packs"}
-      - {id: 23, cat: Audio/Video, desc: "Music | Videos"}
-      - {id: 18, cat: Other, desc: "Pictures"}
-      - {id: 46, cat: XXX/Imageset, desc: "Pictures | xxx"}
-      - {id: 22, cat: TV/Sport, desc: "Sport"}
-      - {id: 50, cat: TV, desc: "STAR"}
-      - {id: 20, cat: TV/SD, desc: "TV | Episodes"}
-      - {id: 47, cat: TV/HD, desc: "TV | Episodes HD"}
-      - {id: 41, cat: TV, desc: "TV | Packs"}
-      - {id: 15, cat: XXX, desc: "xXx"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(h2:contains("failed"))
-    test:
-      path: /browse.php
-      
-  ratio:
-    path: /browse.php
-    selector: font:contains("Ratio:") > span
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: td.outer > table > tbody > tr:has(a[href^="details.php?id="])
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="download2.php"]
-        attribute: href
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: (\d+)
-      files:
-        selector: td:nth-child(3)
-      size:
-        selector: td:nth-child(6)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: trim
-            args: "\xF0"
-          - name: append
-            args: " +02:00"
-          - name: dateparse
-            args: "02-01-200615:04:05 -07:00"
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      banner:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=([^\s]+)
-      downloadvolumefactor:
-        case:
-          button.btnfree: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          button.btn2xup: "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
-        remove: a[href^="details.php?id="]
+---
+  site: utorrents
+  name: u-Torrent
+  language: ro-ro
+  type: private
+  encoding: windows-1252
+  links:
+    - http://www.u-torrents.ro/
+
+  caps:
+    categorymappings:
+      - {id: 48, cat: Movies/3D, desc: "3D"}
+      - {id: 1, cat: PC/0day, desc: "Appz"}
+      - {id: 3, cat: Other, desc: "Cartoons"}
+      - {id: 42, cat: TV/Documentary, desc: "Documentaries"}
+      - {id: 6, cat: Books, desc: "eBooks"}
+      - {id: 11, cat: PC/Games, desc: "Games | PC"}
+      - {id: 12, cat: Console/PS3, desc: "Games | PS2"}
+      - {id: 36, cat: Console/PS3, desc: "Games | PS3"}
+      - {id: 40, cat: Console/PSP, desc: "Games | PSP"}
+      - {id: 25, cat: Console/Wii, desc: "Games | Wii"}
+      - {id: 16, cat: Console/Xbox, desc: "Games | XBOX"}
+      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 43, cat: Movies/BluRay, desc: "Movies | Blu-Ray"}
+      - {id: 49, cat: Movies/BluRay, desc: "Movies | Blu-Ray-RO"}
+      - {id: 7, cat: Movies/DVD, desc: "Movies | DVD-R"}
+      - {id: 2, cat: Movies/DVD, desc: "Movies | DVD-RO"}
+      - {id: 17, cat: Movies/HD, desc: "Movies | HD"}
+      - {id: 45, cat: Movies/HD, desc: "Movies | HD-RO"}
+      - {id: 21, cat: Movies, desc: "Movies | Oldies"}
+      - {id: 38, cat: Movies, desc: "Movies | Packs"}
+      - {id: 8, cat: Movies/SD, desc: "Movies | x264"}
+      - {id: 4, cat: Movies/SD, desc: "Movies | x264-RO"}
+      - {id: 10, cat: Movies/SD, desc: "Movies | XviD"}
+      - {id: 44, cat: Movies/SD, desc: "Movies | XviD-RO"}
+      - {id: 5, cat: Audio/MP3, desc: "Music | Mp3"}
+      - {id: 39, cat: Audio, desc: "Music | Packs"}
+      - {id: 23, cat: Audio/Video, desc: "Music | Videos"}
+      - {id: 18, cat: Other, desc: "Pictures"}
+      - {id: 46, cat: XXX/Imageset, desc: "Pictures | xxx"}
+      - {id: 22, cat: TV/Sport, desc: "Sport"}
+      - {id: 50, cat: TV, desc: "STAR"}
+      - {id: 20, cat: TV/SD, desc: "TV | Episodes"}
+      - {id: 47, cat: TV/HD, desc: "TV | Episodes HD"}
+      - {id: 41, cat: TV, desc: "TV | Packs"}
+      - {id: 15, cat: XXX, desc: "xXx"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(h2:contains("failed"))
+    test:
+      path: /browse.php
+      
+  ratio:
+    path: /browse.php
+    selector: font:contains("Ratio:") > span
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: td.outer > table > tbody > tr:has(a[href^="details.php?id="])
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="download2.php"]
+        attribute: href
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: (\d+)
+      files:
+        selector: td:nth-child(3)
+      size:
+        selector: td:nth-child(6)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: trim
+            args: "\xF0"
+          - name: append
+            args: " +02:00"
+          - name: dateparse
+            args: "02-01-200615:04:05 -07:00"
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      banner:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=([^\s]+)
+      downloadvolumefactor:
+        case:
+          button.btnfree: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          button.btn2xup: "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
+        remove: a[href^="details.php?id="]
diff --git a/src/Jackett/Definitions/waffles.yml b/src/Jackett/Definitions/waffles.yml
index 4742da094b8eba469330631d0a3df3ec409da51f..d3f74a06b89f23689c0c338687b7fff7da5941ca 100644
--- a/src/Jackett/Definitions/waffles.yml
+++ b/src/Jackett/Definitions/waffles.yml
@@ -1,165 +1,165 @@
----
-  site: waffles
-  name: Waffles
-  description: "Music, ebook and software tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://waffles.ch/
-
-  caps:
-    categorymappings:
-      - {id: 2, cat: Audio, desc: "70s"}
-      - {id: 3, cat: Audio, desc: "80s"}
-      - {id: 4, cat: Audio, desc: "90s"}
-      - {id: 82, cat: Audio, desc: "Acoustic"}
-      - {id: 5, cat: Audio, desc: "Alternative"}
-      - {id: 6, cat: Audio, desc: "Ambient"}
-      - {id: 85, cat: PC/ISO, desc: "Apps Linux"}
-      - {id: 84, cat: PC/Mac, desc: "Apps Mac"}
-      - {id: 83, cat: PC, desc: "Apps Win"}
-      - {id: 7, cat: Audio, desc: "Asian"}
-      - {id: 89, cat: Audio/Audiobook, desc: "Audiobook Fiction"}
-      - {id: 90, cat: Audio/Audiobook, desc: "Audiobook Non Fiction"}
-      - {id: 80, cat: Audio, desc: "Avant-Garde"}
-      - {id: 8, cat: Audio, desc: "Bluegrass"}
-      - {id: 9, cat: Audio, desc: "Blues"}
-      - {id: 10, cat: Audio, desc: "Breaks"}
-      - {id: 70, cat: Audio, desc: "Classic Rock"}
-      - {id: 11, cat: Audio, desc: "Classical"}
-      - {id: 72, cat: Audio, desc: "Comedy"}
-      - {id: 88, cat: Audio, desc: "Comics"}
-      - {id: 91, cat: Audio, desc: "Components"}
-      - {id: 12, cat: Audio, desc: "Country"}
-      - {id: 13, cat: Audio, desc: "Dance"}
-      - {id: 81, cat: Audio, desc: "Disco"}
-      - {id: 67, cat: Audio, desc: "Dream Pop"}
-      - {id: 14, cat: Audio, desc: "Drum 'n' Bass"}
-      - {id: 57, cat: Audio, desc: "Dubstep"}
-      - {id: 86, cat: Books, desc: "E-Book Fiction"}
-      - {id: 87, cat: Books, desc: "E-Book Nonfiction"}
-      - {id: 93, cat: Audio, desc: "E-Learning"}
-      - {id: 15, cat: Audio, desc: "Electronic"}
-      - {id: 16, cat: Audio, desc: "Emo"}
-      - {id: 17, cat: Audio, desc: "Experimental"}
-      - {id: 18, cat: Audio, desc: "Folk"}
-      - {id: 19, cat: Audio, desc: "Funk"}
-      - {id: 20, cat: Audio, desc: "Garage"}
-      - {id: 61, cat: Audio, desc: "Goth"}
-      - {id: 66, cat: Audio, desc: "Grime"}
-      - {id: 65, cat: Audio, desc: "Grindcore"}
-      - {id: 73, cat: Audio, desc: "Grunge"}
-      - {id: 21, cat: Audio, desc: "Hardcore"}
-      - {id: 22, cat: Audio, desc: "Hip-Hop/Rap"}
-      - {id: 23, cat: Audio, desc: "House"}
-      - {id: 24, cat: Audio, desc: "IDM"}
-      - {id: 25, cat: Audio, desc: "Indie"}
-      - {id: 26, cat: Audio, desc: "Industrial"}
-      - {id: 27, cat: Audio, desc: "J-Music"}
-      - {id: 28, cat: Audio, desc: "Jazz"}
-      - {id: 29, cat: Audio, desc: "Kids"}
-      - {id: 30, cat: Audio, desc: "Latin"}
-      - {id: 75, cat: Audio, desc: "Lounge"}
-      - {id: 31, cat: Audio, desc: "Metal"}
-      - {id: 32, cat: Audio, desc: "Misc"}
-      - {id: 79, cat: Audio, desc: "Musical"}
-      - {id: 59, cat: Audio, desc: "New Wave"}
-      - {id: 60, cat: Audio, desc: "No Wave"}
-      - {id: 63, cat: Audio, desc: "Noise"}
-      - {id: 64, cat: Audio, desc: "Noiserock"}
-      - {id: 33, cat: Audio, desc: "OST"}
-      - {id: 34, cat: Audio, desc: "Pop"}
-      - {id: 77, cat: Audio, desc: "Pop-Punk"}
-      - {id: 58, cat: Audio, desc: "Post-Punk"}
-      - {id: 35, cat: Audio, desc: "Post-Rock"}
-      - {id: 36, cat: Audio, desc: "Pre-60s"}
-      - {id: 69, cat: Audio, desc: "Progressive Rock"}
-      - {id: 68, cat: Audio, desc: "Protopunk"}
-      - {id: 37, cat: Audio, desc: "Psychedelic"}
-      - {id: 78, cat: Audio, desc: "Psytrance"}
-      - {id: 38, cat: Audio, desc: "Punk"}
-      - {id: 39, cat: Audio, desc: "R 'n' B"}
-      - {id: 40, cat: Audio, desc: "Reggae"}
-      - {id: 62, cat: Audio, desc: "Remixes"}
-      - {id: 41, cat: Audio, desc: "Rock"}
-      - {id: 71, cat: Audio, desc: "Screamo"}
-      - {id: 92, cat: Audio, desc: "Sheet music"}
-      - {id: 42, cat: Audio, desc: "Ska"}
-      - {id: 43, cat: Audio, desc: "Soul"}
-      - {id: 76, cat: Audio, desc: "Synthpop"}
-      - {id: 44, cat: Audio, desc: "Techno"}
-      - {id: 45, cat: Audio, desc: "Trance"}
-      - {id: 46, cat: Audio, desc: "Trip Hop"}
-      - {id: 47, cat: Audio, desc: "UK Garage"}
-      - {id: 74, cat: Audio, desc: "Video Game Music"}
-      - {id: 48, cat: Audio, desc: "World/Ethnic"}
-      - {id: 49, cat: Audio, desc: "Xmas"}
-
-    modes:
-      search: [q]
-
-  login:
-    path: login_check
-    method: post
-    inputs:
-      _username: "{{ .Config.username }}"
-      _password: "{{ .Config.password }}"
-    # error:
-    #   - selector: title:contains("Redirecting to https://waffles.ch/login")
-    test:
-      path: index.php
-
-  download:
-    selector: a[href^="download.php?id="]
-        
-  search:
-    path: browse.php
-    inputs:
-      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
-      q: "{{ .Query.Keywords }}"
-    rows:
-      selector: table#browsetable > tbody > tr:has(a[href^="/details.php?id="])
-    fields:
-      category:
-        selector: a[href^="/browse.php?q="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: c
-      title:
-        selector: td:nth-child(2)
-      download:
-        selector: a[href^="/details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["/details.php?id=", "/download.php?id="]
-      details:
-        selector: a[href^="/details.php?id="]
-        attribute: href
-      grabs:
-        selector: td:nth-child(7)
-        filters:
-          - name: regexp
-            args: ([\d,]+)
-      files:
-        selector: td:nth-child(3)
-      size:
-        selector: td:nth-child(6)
-      seeders:
-        selector: td:nth-child(8)
-      leechers:
-        selector: td:nth-child(9)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: dateparse
-            args: "2 April 2017 +05:50"
-      downloadvolumefactor:
-        case:
-          "img[title=\"Free Torrent!\"]": "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
+---
+  site: waffles
+  name: Waffles
+  description: "Music, ebook and software tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://waffles.ch/
+
+  caps:
+    categorymappings:
+      - {id: 2, cat: Audio, desc: "70s"}
+      - {id: 3, cat: Audio, desc: "80s"}
+      - {id: 4, cat: Audio, desc: "90s"}
+      - {id: 82, cat: Audio, desc: "Acoustic"}
+      - {id: 5, cat: Audio, desc: "Alternative"}
+      - {id: 6, cat: Audio, desc: "Ambient"}
+      - {id: 85, cat: PC/ISO, desc: "Apps Linux"}
+      - {id: 84, cat: PC/Mac, desc: "Apps Mac"}
+      - {id: 83, cat: PC, desc: "Apps Win"}
+      - {id: 7, cat: Audio, desc: "Asian"}
+      - {id: 89, cat: Audio/Audiobook, desc: "Audiobook Fiction"}
+      - {id: 90, cat: Audio/Audiobook, desc: "Audiobook Non Fiction"}
+      - {id: 80, cat: Audio, desc: "Avant-Garde"}
+      - {id: 8, cat: Audio, desc: "Bluegrass"}
+      - {id: 9, cat: Audio, desc: "Blues"}
+      - {id: 10, cat: Audio, desc: "Breaks"}
+      - {id: 70, cat: Audio, desc: "Classic Rock"}
+      - {id: 11, cat: Audio, desc: "Classical"}
+      - {id: 72, cat: Audio, desc: "Comedy"}
+      - {id: 88, cat: Audio, desc: "Comics"}
+      - {id: 91, cat: Audio, desc: "Components"}
+      - {id: 12, cat: Audio, desc: "Country"}
+      - {id: 13, cat: Audio, desc: "Dance"}
+      - {id: 81, cat: Audio, desc: "Disco"}
+      - {id: 67, cat: Audio, desc: "Dream Pop"}
+      - {id: 14, cat: Audio, desc: "Drum 'n' Bass"}
+      - {id: 57, cat: Audio, desc: "Dubstep"}
+      - {id: 86, cat: Books, desc: "E-Book Fiction"}
+      - {id: 87, cat: Books, desc: "E-Book Nonfiction"}
+      - {id: 93, cat: Audio, desc: "E-Learning"}
+      - {id: 15, cat: Audio, desc: "Electronic"}
+      - {id: 16, cat: Audio, desc: "Emo"}
+      - {id: 17, cat: Audio, desc: "Experimental"}
+      - {id: 18, cat: Audio, desc: "Folk"}
+      - {id: 19, cat: Audio, desc: "Funk"}
+      - {id: 20, cat: Audio, desc: "Garage"}
+      - {id: 61, cat: Audio, desc: "Goth"}
+      - {id: 66, cat: Audio, desc: "Grime"}
+      - {id: 65, cat: Audio, desc: "Grindcore"}
+      - {id: 73, cat: Audio, desc: "Grunge"}
+      - {id: 21, cat: Audio, desc: "Hardcore"}
+      - {id: 22, cat: Audio, desc: "Hip-Hop/Rap"}
+      - {id: 23, cat: Audio, desc: "House"}
+      - {id: 24, cat: Audio, desc: "IDM"}
+      - {id: 25, cat: Audio, desc: "Indie"}
+      - {id: 26, cat: Audio, desc: "Industrial"}
+      - {id: 27, cat: Audio, desc: "J-Music"}
+      - {id: 28, cat: Audio, desc: "Jazz"}
+      - {id: 29, cat: Audio, desc: "Kids"}
+      - {id: 30, cat: Audio, desc: "Latin"}
+      - {id: 75, cat: Audio, desc: "Lounge"}
+      - {id: 31, cat: Audio, desc: "Metal"}
+      - {id: 32, cat: Audio, desc: "Misc"}
+      - {id: 79, cat: Audio, desc: "Musical"}
+      - {id: 59, cat: Audio, desc: "New Wave"}
+      - {id: 60, cat: Audio, desc: "No Wave"}
+      - {id: 63, cat: Audio, desc: "Noise"}
+      - {id: 64, cat: Audio, desc: "Noiserock"}
+      - {id: 33, cat: Audio, desc: "OST"}
+      - {id: 34, cat: Audio, desc: "Pop"}
+      - {id: 77, cat: Audio, desc: "Pop-Punk"}
+      - {id: 58, cat: Audio, desc: "Post-Punk"}
+      - {id: 35, cat: Audio, desc: "Post-Rock"}
+      - {id: 36, cat: Audio, desc: "Pre-60s"}
+      - {id: 69, cat: Audio, desc: "Progressive Rock"}
+      - {id: 68, cat: Audio, desc: "Protopunk"}
+      - {id: 37, cat: Audio, desc: "Psychedelic"}
+      - {id: 78, cat: Audio, desc: "Psytrance"}
+      - {id: 38, cat: Audio, desc: "Punk"}
+      - {id: 39, cat: Audio, desc: "R 'n' B"}
+      - {id: 40, cat: Audio, desc: "Reggae"}
+      - {id: 62, cat: Audio, desc: "Remixes"}
+      - {id: 41, cat: Audio, desc: "Rock"}
+      - {id: 71, cat: Audio, desc: "Screamo"}
+      - {id: 92, cat: Audio, desc: "Sheet music"}
+      - {id: 42, cat: Audio, desc: "Ska"}
+      - {id: 43, cat: Audio, desc: "Soul"}
+      - {id: 76, cat: Audio, desc: "Synthpop"}
+      - {id: 44, cat: Audio, desc: "Techno"}
+      - {id: 45, cat: Audio, desc: "Trance"}
+      - {id: 46, cat: Audio, desc: "Trip Hop"}
+      - {id: 47, cat: Audio, desc: "UK Garage"}
+      - {id: 74, cat: Audio, desc: "Video Game Music"}
+      - {id: 48, cat: Audio, desc: "World/Ethnic"}
+      - {id: 49, cat: Audio, desc: "Xmas"}
+
+    modes:
+      search: [q]
+
+  login:
+    path: login_check
+    method: post
+    inputs:
+      _username: "{{ .Config.username }}"
+      _password: "{{ .Config.password }}"
+    # error:
+    #   - selector: title:contains("Redirecting to https://waffles.ch/login")
+    test:
+      path: index.php
+
+  download:
+    selector: a[href^="download.php?id="]
+        
+  search:
+    path: browse.php
+    inputs:
+      $raw: "{{range .Categories}}filter_cat[{{.}}]=1&{{end}}"
+      q: "{{ .Query.Keywords }}"
+    rows:
+      selector: table#browsetable > tbody > tr:has(a[href^="/details.php?id="])
+    fields:
+      category:
+        selector: a[href^="/browse.php?q="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: c
+      title:
+        selector: td:nth-child(2)
+      download:
+        selector: a[href^="/details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["/details.php?id=", "/download.php?id="]
+      details:
+        selector: a[href^="/details.php?id="]
+        attribute: href
+      grabs:
+        selector: td:nth-child(7)
+        filters:
+          - name: regexp
+            args: ([\d,]+)
+      files:
+        selector: td:nth-child(3)
+      size:
+        selector: td:nth-child(6)
+      seeders:
+        selector: td:nth-child(8)
+      leechers:
+        selector: td:nth-child(9)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: dateparse
+            args: "2 April 2017 +05:50"
+      downloadvolumefactor:
+        case:
+          "img[title=\"Free Torrent!\"]": "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
           "*": "1"
\ No newline at end of file
diff --git a/src/Jackett/Definitions/worldofp2p.yml b/src/Jackett/Definitions/worldofp2p.yml
index 3ea615d02576d1b5653ab4c7646d9f5090c839aa..8ccbe7e521537a40d6ef0a5e3fdae7564fac1d15 100644
--- a/src/Jackett/Definitions/worldofp2p.yml
+++ b/src/Jackett/Definitions/worldofp2p.yml
@@ -1,136 +1,136 @@
----
-  site: worldofp2p
-  name: WorldOfP2P
-  description: "A general tracker"
-  language: en-us
-  type: private
-  encoding: UTF-8
-  links:
-    - https://worldofp2p.net
-
-  caps:
-    categorymappings:
-      - {id: 9, cat: TV/Anime, desc: "Anime"}
-      - {id: 15, cat: PC/0day, desc: "Apps-Linux"}
-      - {id: 16, cat: PC/Mac, desc: "Apps-Macintosh"}
-      - {id: 17, cat: PC/Phone-Other, desc: "Apps-Mobile"}
-      - {id: 1, cat:  PC/0day, desc: "Apps-Windows"}
-      - {id: 49, cat: Audio, desc: "Audio Tracks"}
-      - {id: 51, cat: Audio/Audiobook, desc: "AudioBook"}
-      - {id: 50, cat: Books, desc: "Ebooks"}
-      - {id: 23, cat: Console/Other, desc: "Games-Mixed"}
-      - {id: 32, cat: Console, desc: "Games-Packs"}
-      - {id: 2, cat: PC/Games, desc: "Games-PC"}
-      - {id: 12, cat: PC/Games, desc: "Games-PC Rips"}
-      - {id: 20, cat: Console/Other, desc: "Games-PS1"}
-      - {id: 8, cat: Console/Other, desc: "Games-PS2"}
-      - {id: 21, cat: Console/PS3, desc: "Games-PS3"}
-      - {id: 22, cat: Console/PS4, desc: "Games-PS4"}
-      - {id: 7, cat: Console/PSP, desc: "Games-PSP"}
-      - {id: 14, cat: Console/Wii, desc: "Games-Wii"}
-      - {id: 44, cat: Console/Xbox360, desc: "Games-Xbox 360"}
-      - {id: 45, cat: Console/Xbox, desc: "Games-Xbox One"}
-      - {id: 43, cat: Console/Xbox, desc: "Gamex-Xbox"}
-      - {id: 30, cat: Movies/HD, desc: "Movies-1080p"}
-      - {id: 56, cat: Movies/HD, desc: "Movies-2160p"}
-      - {id: 24, cat: Movies/3D, desc: "Movies-3D"}
-      - {id: 53, cat: Movies/SD, desc: "Movies-480p"}
-      - {id: 52, cat: Movies/SD, desc: "Movies-576p"}
-      - {id: 25, cat: Movies/HD, desc: "Movies-720p"}
-      - {id: 11, cat: Movies/BluRay, desc: "Movies-Bluray"}
-      - {id: 26, cat: Movies/HD, desc: "Movies-BRRip"}
-      - {id: 27, cat: Movies/SD, desc: "Movies-Camera"}
-      - {id: 10, cat: Movies/DVD, desc: "Movies-DVDR"}
-      - {id: 28, cat: Movies/Other, desc: "Movies-Oldies"}
-      - {id: 31, cat: Movies/Other, desc: "Movies-Packs"}
-      - {id: 57, cat: Movies/HD, desc: "Movies-Remux"}
-      - {id: 33, cat: Movies/Other, desc: "Movies-Sport"}
-      - {id: 29, cat: Movies/WEBDL, desc: "Movies-Web/DL"}
-      - {id: 3, cat: Movies/SD, desc: "Movies-XviD"}
-      - {id: 13, cat: Audio/Lossless, desc: "Music-Flac"}
-      - {id: 4, cat: Audio/MP3, desc: "Music-MP3"}
-      - {id: 18, cat: Audio, desc: "Music-Packs"}
-      - {id: 19, cat: Audio/Video, desc: "Music-Videos"}
-      - {id: 37, cat: TV/HD, desc: "TV-1080p"}
-      - {id: 54, cat: TV/HD, desc: "TV-2160p"}
-      - {id: 55, cat: TV/SD, desc: "TV-480p"}
-      - {id: 39, cat: TV/HD, desc: "TV-720p"}
-      - {id: 38, cat: TV/HD, desc: "TV-Bluray"}
-      - {id: 35, cat: TV/SD, desc: "TV-DVDR"}
-      - {id: 36, cat: TV/SD, desc: "TV-DVDRip"}
-      - {id: 41, cat: TV, desc: "TV-Packs"}
-      - {id: 42, cat: TV/WEB-DL, desc: "TV-Web/DL"}
-      - {id: 58, cat: TV/HD, desc: "TV-x264"}
-      - {id: 5, cat:  TV/SD, desc: "TV-XviD"}
-      - {id: 46, cat: XXX, desc: "xXx-HD"}
-      - {id: 47, cat: XXX/Imageset, desc: "xXx-Images"}
-      - {id: 48, cat: XXX/Packs, desc: "xXx-Packs"}
-      - {id: 6, cat: XXX/XviD, desc: "xXx-XviD"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /takelogin.php
-    method: post
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-      login: "Login"
-    error:
-      - selector: td.stdmsg2
-    test:
-      path: /usercp.php?action=default
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: "1"
-      searchin: "title"
-
-    rows:
-      selector: table.browsewidth100 > tbody > tr:has(a[href^="download.php?torrent="])
-      filters:
-        - name: andmatch
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      comments:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      download:
-        selector: a[href^="download.php?torrent="]
-        attribute: href
-      files:
-        selector: td:nth-child(5)
-      size:
-        selector: td:nth-child(8)
-      seeders:
-        selector: td:nth-child(10)
-      leechers:
-        selector: td:nth-child(11)
-      date:
-        selector: td:nth-child(7)
-      grabs:
-        selector: a[href^="snatches.php?id="]
-        filters:
-          - name: regexp
-            args: "(\\d+)"
-      downloadvolumefactor:
-        case:
-          a.info:contains("Free"): "0"
-          img[src*="/free.png"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "*": "1"
+---
+  site: worldofp2p
+  name: WorldOfP2P
+  description: "A general tracker"
+  language: en-us
+  type: private
+  encoding: UTF-8
+  links:
+    - https://worldofp2p.net
+
+  caps:
+    categorymappings:
+      - {id: 9, cat: TV/Anime, desc: "Anime"}
+      - {id: 15, cat: PC/0day, desc: "Apps-Linux"}
+      - {id: 16, cat: PC/Mac, desc: "Apps-Macintosh"}
+      - {id: 17, cat: PC/Phone-Other, desc: "Apps-Mobile"}
+      - {id: 1, cat:  PC/0day, desc: "Apps-Windows"}
+      - {id: 49, cat: Audio, desc: "Audio Tracks"}
+      - {id: 51, cat: Audio/Audiobook, desc: "AudioBook"}
+      - {id: 50, cat: Books, desc: "Ebooks"}
+      - {id: 23, cat: Console/Other, desc: "Games-Mixed"}
+      - {id: 32, cat: Console, desc: "Games-Packs"}
+      - {id: 2, cat: PC/Games, desc: "Games-PC"}
+      - {id: 12, cat: PC/Games, desc: "Games-PC Rips"}
+      - {id: 20, cat: Console/Other, desc: "Games-PS1"}
+      - {id: 8, cat: Console/Other, desc: "Games-PS2"}
+      - {id: 21, cat: Console/PS3, desc: "Games-PS3"}
+      - {id: 22, cat: Console/PS4, desc: "Games-PS4"}
+      - {id: 7, cat: Console/PSP, desc: "Games-PSP"}
+      - {id: 14, cat: Console/Wii, desc: "Games-Wii"}
+      - {id: 44, cat: Console/Xbox360, desc: "Games-Xbox 360"}
+      - {id: 45, cat: Console/Xbox, desc: "Games-Xbox One"}
+      - {id: 43, cat: Console/Xbox, desc: "Gamex-Xbox"}
+      - {id: 30, cat: Movies/HD, desc: "Movies-1080p"}
+      - {id: 56, cat: Movies/HD, desc: "Movies-2160p"}
+      - {id: 24, cat: Movies/3D, desc: "Movies-3D"}
+      - {id: 53, cat: Movies/SD, desc: "Movies-480p"}
+      - {id: 52, cat: Movies/SD, desc: "Movies-576p"}
+      - {id: 25, cat: Movies/HD, desc: "Movies-720p"}
+      - {id: 11, cat: Movies/BluRay, desc: "Movies-Bluray"}
+      - {id: 26, cat: Movies/HD, desc: "Movies-BRRip"}
+      - {id: 27, cat: Movies/SD, desc: "Movies-Camera"}
+      - {id: 10, cat: Movies/DVD, desc: "Movies-DVDR"}
+      - {id: 28, cat: Movies/Other, desc: "Movies-Oldies"}
+      - {id: 31, cat: Movies/Other, desc: "Movies-Packs"}
+      - {id: 57, cat: Movies/HD, desc: "Movies-Remux"}
+      - {id: 33, cat: Movies/Other, desc: "Movies-Sport"}
+      - {id: 29, cat: Movies/WEBDL, desc: "Movies-Web/DL"}
+      - {id: 3, cat: Movies/SD, desc: "Movies-XviD"}
+      - {id: 13, cat: Audio/Lossless, desc: "Music-Flac"}
+      - {id: 4, cat: Audio/MP3, desc: "Music-MP3"}
+      - {id: 18, cat: Audio, desc: "Music-Packs"}
+      - {id: 19, cat: Audio/Video, desc: "Music-Videos"}
+      - {id: 37, cat: TV/HD, desc: "TV-1080p"}
+      - {id: 54, cat: TV/HD, desc: "TV-2160p"}
+      - {id: 55, cat: TV/SD, desc: "TV-480p"}
+      - {id: 39, cat: TV/HD, desc: "TV-720p"}
+      - {id: 38, cat: TV/HD, desc: "TV-Bluray"}
+      - {id: 35, cat: TV/SD, desc: "TV-DVDR"}
+      - {id: 36, cat: TV/SD, desc: "TV-DVDRip"}
+      - {id: 41, cat: TV, desc: "TV-Packs"}
+      - {id: 42, cat: TV/WEB-DL, desc: "TV-Web/DL"}
+      - {id: 58, cat: TV/HD, desc: "TV-x264"}
+      - {id: 5, cat:  TV/SD, desc: "TV-XviD"}
+      - {id: 46, cat: XXX, desc: "xXx-HD"}
+      - {id: 47, cat: XXX/Imageset, desc: "xXx-Images"}
+      - {id: 48, cat: XXX/Packs, desc: "xXx-Packs"}
+      - {id: 6, cat: XXX/XviD, desc: "xXx-XviD"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /takelogin.php
+    method: post
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+      login: "Login"
+    error:
+      - selector: td.stdmsg2
+    test:
+      path: /usercp.php?action=default
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: "1"
+      searchin: "title"
+
+    rows:
+      selector: table.browsewidth100 > tbody > tr:has(a[href^="download.php?torrent="])
+      filters:
+        - name: andmatch
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      comments:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      download:
+        selector: a[href^="download.php?torrent="]
+        attribute: href
+      files:
+        selector: td:nth-child(5)
+      size:
+        selector: td:nth-child(8)
+      seeders:
+        selector: td:nth-child(10)
+      leechers:
+        selector: td:nth-child(11)
+      date:
+        selector: td:nth-child(7)
+      grabs:
+        selector: a[href^="snatches.php?id="]
+        filters:
+          - name: regexp
+            args: "(\\d+)"
+      downloadvolumefactor:
+        case:
+          a.info:contains("Free"): "0"
+          img[src*="/free.png"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "*": "1"
diff --git a/src/Jackett/Definitions/xtremezone.yml b/src/Jackett/Definitions/xtremezone.yml
index 110e5bb662b3f3ac2430a844b82d12737f995a48..3c7bdaaf53a2853e22306b837949e8f080104eb3 100644
--- a/src/Jackett/Definitions/xtremezone.yml
+++ b/src/Jackett/Definitions/xtremezone.yml
@@ -1,118 +1,118 @@
----
-  site: xtremezone
-  name: Xtreme Zone
-  language: ro-ro
-  type: semi-private
-  encoding: UTF-8
-  links:
-    - https://www.myxz.org/
-
-  caps:
-    categorymappings:
-      - {id: 3, cat: TV/Anime, desc: "Anime/Hentai"}
-      - {id: 1, cat: PC/0day, desc: "Appz"}
-      - {id: 9, cat: TV/Documentary, desc: "Documentary"}
-      - {id: 6, cat: Books, desc: "eBooks"}
-      - {id: 52, cat: Console, desc: "Games-Console"}
-      - {id: 11, cat: PC/Games, desc: "Games-PC"}
-      - {id: 18, cat: Other, desc: "Images"}
-      - {id: 14, cat: PC, desc: "Linux"}
-      - {id: 37, cat: PC/Mac, desc: "Mac"}
-      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
-      - {id: 17, cat: Movies/BluRay, desc: "Movies-BluRay"}
-      - {id: 24, cat: Movies/BluRay, desc: "Movies-BluRayRO"}
-      - {id: 7, cat: Movies/DVD, desc: "Movies-DVD"}
-      - {id: 2, cat: Movies/DVD, desc: "Movies-DVD-RO"}
-      - {id: 8, cat: Movies/HD, desc: "Movies-HD"}
-      - {id: 29, cat: Movies/HD, desc: "Movies-HD-RO"}
-      - {id: 38, cat: Movies, desc: "Movies-Packs"}
-      - {id: 10, cat: Movies/SD, desc: "Movies-SD"}
-      - {id: 35, cat: Movies/SD, desc: "Movies-SD-RO"}
-      - {id: 5, cat: Audio, desc: "Music"}
-      - {id: 22, cat: TV/Sport, desc: "Sport"}
-      - {id: 43, cat: TV/HD, desc: "TV-HD"}
-      - {id: 44, cat: TV/HD, desc: "TV-HD-RO"}
-      - {id: 41, cat: TV, desc: "TV-Packs"}
-      - {id: 45, cat: TV/SD, desc: "TV-SD"}
-      - {id: 46, cat: TV/SD, desc: "TV-SD-RO"}
-      - {id: 15, cat: XXX, desc: "XXX"}
-      - {id: 47, cat: XXX, desc: "XXX-DVD"}
-      - {id: 48, cat: XXX, desc: "XXX-HD"}
-      - {id: 49, cat: XXX/Imageset, desc: "XXX-IMGSet"}
-      - {id: 50, cat: XXX, desc: "XXX-Packs"}
-      - {id: 51, cat: XXX, desc: "XXX-SD"}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-
-  login:
-    path: /login.php
-    method: form
-    form: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: td.embedded:has(center > h2:contains(failed))
-    test:
-      path: /browse.php
-      
-  ratio:
-    path: /browse.php
-    selector: font:contains("Ratio:")+font
-
-  search:
-    path: /browse.php
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      search: "{{ .Query.Keywords }}"
-      incldead: 1
-    rows:
-      selector: table.browser > tbody > tr.browse[style]
-    fields:
-      title:
-        selector: a[href^="details.php?id="]
-      details:
-        selector: a[href^="details.php?id="]
-        attribute: href
-      category:
-        selector: a[href^="browse.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href^="dwn.php"]
-        attribute: href
-      size:
-        selector: td:nth-child(6)
-      date:
-        selector: td:nth-child(5)
-        filters:
-          - name: append
-            args: " +00:00"
-          - name: dateparse
-            args: "02-01-200615:04:05 -07:00"
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      banner:
-        selector: a[onmouseover][href^="details.php?id="]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: src=([^\s]+)
-      downloadvolumefactor:
-        case:
-          "img[title^=\"FreeLech: \"]": "0"
-          "img[title^=\"HALF: \"]": "0.5"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          "img[title^=\"2xUP: \"]": "2"
-          "*": "1"
-      description:
-        selector: td:nth-child(2)
+---
+  site: xtremezone
+  name: Xtreme Zone
+  language: ro-ro
+  type: semi-private
+  encoding: UTF-8
+  links:
+    - https://www.myxz.org/
+
+  caps:
+    categorymappings:
+      - {id: 3, cat: TV/Anime, desc: "Anime/Hentai"}
+      - {id: 1, cat: PC/0day, desc: "Appz"}
+      - {id: 9, cat: TV/Documentary, desc: "Documentary"}
+      - {id: 6, cat: Books, desc: "eBooks"}
+      - {id: 52, cat: Console, desc: "Games-Console"}
+      - {id: 11, cat: PC/Games, desc: "Games-PC"}
+      - {id: 18, cat: Other, desc: "Images"}
+      - {id: 14, cat: PC, desc: "Linux"}
+      - {id: 37, cat: PC/Mac, desc: "Mac"}
+      - {id: 19, cat: PC/Phone-Other, desc: "Mobile"}
+      - {id: 17, cat: Movies/BluRay, desc: "Movies-BluRay"}
+      - {id: 24, cat: Movies/BluRay, desc: "Movies-BluRayRO"}
+      - {id: 7, cat: Movies/DVD, desc: "Movies-DVD"}
+      - {id: 2, cat: Movies/DVD, desc: "Movies-DVD-RO"}
+      - {id: 8, cat: Movies/HD, desc: "Movies-HD"}
+      - {id: 29, cat: Movies/HD, desc: "Movies-HD-RO"}
+      - {id: 38, cat: Movies, desc: "Movies-Packs"}
+      - {id: 10, cat: Movies/SD, desc: "Movies-SD"}
+      - {id: 35, cat: Movies/SD, desc: "Movies-SD-RO"}
+      - {id: 5, cat: Audio, desc: "Music"}
+      - {id: 22, cat: TV/Sport, desc: "Sport"}
+      - {id: 43, cat: TV/HD, desc: "TV-HD"}
+      - {id: 44, cat: TV/HD, desc: "TV-HD-RO"}
+      - {id: 41, cat: TV, desc: "TV-Packs"}
+      - {id: 45, cat: TV/SD, desc: "TV-SD"}
+      - {id: 46, cat: TV/SD, desc: "TV-SD-RO"}
+      - {id: 15, cat: XXX, desc: "XXX"}
+      - {id: 47, cat: XXX, desc: "XXX-DVD"}
+      - {id: 48, cat: XXX, desc: "XXX-HD"}
+      - {id: 49, cat: XXX/Imageset, desc: "XXX-IMGSet"}
+      - {id: 50, cat: XXX, desc: "XXX-Packs"}
+      - {id: 51, cat: XXX, desc: "XXX-SD"}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+
+  login:
+    path: /login.php
+    method: form
+    form: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: td.embedded:has(center > h2:contains(failed))
+    test:
+      path: /browse.php
+      
+  ratio:
+    path: /browse.php
+    selector: font:contains("Ratio:")+font
+
+  search:
+    path: /browse.php
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      search: "{{ .Query.Keywords }}"
+      incldead: 1
+    rows:
+      selector: table.browser > tbody > tr.browse[style]
+    fields:
+      title:
+        selector: a[href^="details.php?id="]
+      details:
+        selector: a[href^="details.php?id="]
+        attribute: href
+      category:
+        selector: a[href^="browse.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href^="dwn.php"]
+        attribute: href
+      size:
+        selector: td:nth-child(6)
+      date:
+        selector: td:nth-child(5)
+        filters:
+          - name: append
+            args: " +00:00"
+          - name: dateparse
+            args: "02-01-200615:04:05 -07:00"
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      banner:
+        selector: a[onmouseover][href^="details.php?id="]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: src=([^\s]+)
+      downloadvolumefactor:
+        case:
+          "img[title^=\"FreeLech: \"]": "0"
+          "img[title^=\"HALF: \"]": "0.5"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          "img[title^=\"2xUP: \"]": "2"
+          "*": "1"
+      description:
+        selector: td:nth-child(2)
         remove: a, img
\ No newline at end of file
diff --git a/src/Jackett/Definitions/ztracker.yml b/src/Jackett/Definitions/ztracker.yml
index 8a7f7fbced374d4aa37503d6b4a12d561817b07e..34abc5e00e89cabce95ad71273398c222c8bd5b0 100644
--- a/src/Jackett/Definitions/ztracker.yml
+++ b/src/Jackett/Definitions/ztracker.yml
@@ -1,128 +1,128 @@
----
-  site: ztracker
-  name: Ztracker
-  language: hu-hu
-  type: semi-private
-  encoding: ISO-8859-2
-  links:
-    - http://ztracker.org
-
-  caps:
-    categorymappings:
-      - {id: 30, cat: Movies/SD, desc: "CAM/HUN"}
-      - {id: 29, cat: Movies/SD, desc: "CAM/Külf."}
-      - {id: 3, cat: Books, desc: "Ebook"}
-      - {id: 9, cat: Movies/HD, desc: "Film/HD-DVD/Hun"}
-      - {id: 10, cat: Movies/HD, desc: "Film/HD-DVD/Külf"}
-      - {id: 7, cat: Movies/SD, desc: "Film/Xvid/Hun"}
-      - {id: 8, cat: Movies/SD, desc: "Film/Xvid/Külf."}
-      - {id: 15, cat: XXX, desc: "Film/Xvid/XXX"}
-      - {id: 16, cat: XXX, desc: "Filmek/HD-DVD/XXX"}
-      - {id: 4, cat: PC/Games, desc: "Játék"}
-      - {id: 18, cat: Other, desc: "Képek"}
-      - {id: 17, cat: XXX, desc: "Képek/XXX"}
-      - {id: 27, cat: Books, desc: "Mese/Hun"}
-      - {id: 28, cat: Books, desc: "Mese/Külf."}
-      - {id: 24, cat: PC/Phone-Other, desc: "Program/Mobil"}
-      - {id: 1, cat: PC/0day, desc: "Program/Win"}
-      - {id: 25, cat: TV, desc: "Sorozat/Hun"}
-      - {id: 26, cat: TV, desc: "Sorozat/Külf."}
-      - {id: 11, cat: Audio, desc: "Zene/Hun"}
-      - {id: 12, cat: Audio, desc: "Zene/Külf."}
-
-    modes:
-      search: [q]
-      tv-search: [q, season, ep]
-      movie-search: [q]
-
-  login:
-    path: belepes.php
-    method: form
-    inputs:
-      username: "{{ .Config.username }}"
-      password: "{{ .Config.password }}"
-    error:
-      - selector: div.error
-      - selector: table:has(img[src="/pic/ts_error/error.jpg"])
-        message:
-          selector: table:has(img[src="/pic/ts_error/error.jpg"])
-          remove: style
-    test:
-      path: browse_old.php
-
-  search:
-    path: browse_old.php
-    keywordsfilters:
-      - name: re_replace
-        args: ["[^a-zA-Z0-9]+", "%"]
-    inputs:
-      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
-      keywords: "{{ .Keywords }}"
-      search_type: "t_name"
-    rows:
-      selector: table[border="1"] > tbody > tr:has(a[href*="details.php?id="])
-    fields:
-      title:
-        selector: a[href*="details.php?id="][onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: <font class=\\'smalltext\\'>(.*?)</font>
-      banner:
-        selector: a[href*="details.php?id="][onmouseover]
-        attribute: onmouseover
-        filters:
-          - name: regexp
-            args: img src=\\'(.*?)\\'
-      details:
-        selector: a[href*="details.php?id="][onmouseover]
-        attribute: href
-      category:
-        selector: a[href^="/browse_old.php?cat="]
-        attribute: href
-        filters:
-          - name: querystring
-            args: cat
-      download:
-        selector: a[href*="details.php?id="]
-        attribute: href
-        filters:
-          - name: replace
-            args: ["details.php", "download.php"]
-      seeders:
-        selector: td:nth-child(7)
-      leechers:
-        selector: td:nth-child(8)
-      files:
-        selector: td:nth-child(5)
-      grabs:
-        selector: td:nth-child(11) > b
-        filters:
-          - name: trim
-            args: "x"
-      size:
-        selector: td:nth-child(11)
-        remove: b
-        filters:
-          - name: replace
-            args: ["time", ""]
-      downloadvolumefactor:
-        case:
-          img[src="./pic/freedownload.gif"]: "0"
-          "*": "1"
-      uploadvolumefactor:
-        case:
-          img[src="./pic/x2.gif"]: "2"
-          "*": "1"
-      date:
-        selector: td:nth-child(2)
-        remove: a, img
-        filters:
-          - name: replace
-            args: ["\xA0", " "]
-          - name: replace
-            args: ["Ma", "Today"]
-          - name: replace
-            args: ["Tegnap", "Yesterday"]
-          - name: re_replace
-            args: ["12:(\\d\\d) PM", "00:$1 PM"]
+---
+  site: ztracker
+  name: Ztracker
+  language: hu-hu
+  type: semi-private
+  encoding: ISO-8859-2
+  links:
+    - http://ztracker.org
+
+  caps:
+    categorymappings:
+      - {id: 30, cat: Movies/SD, desc: "CAM/HUN"}
+      - {id: 29, cat: Movies/SD, desc: "CAM/Külf."}
+      - {id: 3, cat: Books, desc: "Ebook"}
+      - {id: 9, cat: Movies/HD, desc: "Film/HD-DVD/Hun"}
+      - {id: 10, cat: Movies/HD, desc: "Film/HD-DVD/Külf"}
+      - {id: 7, cat: Movies/SD, desc: "Film/Xvid/Hun"}
+      - {id: 8, cat: Movies/SD, desc: "Film/Xvid/Külf."}
+      - {id: 15, cat: XXX, desc: "Film/Xvid/XXX"}
+      - {id: 16, cat: XXX, desc: "Filmek/HD-DVD/XXX"}
+      - {id: 4, cat: PC/Games, desc: "Játék"}
+      - {id: 18, cat: Other, desc: "Képek"}
+      - {id: 17, cat: XXX, desc: "Képek/XXX"}
+      - {id: 27, cat: Books, desc: "Mese/Hun"}
+      - {id: 28, cat: Books, desc: "Mese/Külf."}
+      - {id: 24, cat: PC/Phone-Other, desc: "Program/Mobil"}
+      - {id: 1, cat: PC/0day, desc: "Program/Win"}
+      - {id: 25, cat: TV, desc: "Sorozat/Hun"}
+      - {id: 26, cat: TV, desc: "Sorozat/Külf."}
+      - {id: 11, cat: Audio, desc: "Zene/Hun"}
+      - {id: 12, cat: Audio, desc: "Zene/Külf."}
+
+    modes:
+      search: [q]
+      tv-search: [q, season, ep]
+      movie-search: [q]
+
+  login:
+    path: belepes.php
+    method: form
+    inputs:
+      username: "{{ .Config.username }}"
+      password: "{{ .Config.password }}"
+    error:
+      - selector: div.error
+      - selector: table:has(img[src="/pic/ts_error/error.jpg"])
+        message:
+          selector: table:has(img[src="/pic/ts_error/error.jpg"])
+          remove: style
+    test:
+      path: browse_old.php
+
+  search:
+    path: browse_old.php
+    keywordsfilters:
+      - name: re_replace
+        args: ["[^a-zA-Z0-9]+", "%"]
+    inputs:
+      $raw: "{{range .Categories}}c{{.}}=1&{{end}}"
+      keywords: "{{ .Keywords }}"
+      search_type: "t_name"
+    rows:
+      selector: table[border="1"] > tbody > tr:has(a[href*="details.php?id="])
+    fields:
+      title:
+        selector: a[href*="details.php?id="][onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: <font class=\\'smalltext\\'>(.*?)</font>
+      banner:
+        selector: a[href*="details.php?id="][onmouseover]
+        attribute: onmouseover
+        filters:
+          - name: regexp
+            args: img src=\\'(.*?)\\'
+      details:
+        selector: a[href*="details.php?id="][onmouseover]
+        attribute: href
+      category:
+        selector: a[href^="/browse_old.php?cat="]
+        attribute: href
+        filters:
+          - name: querystring
+            args: cat
+      download:
+        selector: a[href*="details.php?id="]
+        attribute: href
+        filters:
+          - name: replace
+            args: ["details.php", "download.php"]
+      seeders:
+        selector: td:nth-child(7)
+      leechers:
+        selector: td:nth-child(8)
+      files:
+        selector: td:nth-child(5)
+      grabs:
+        selector: td:nth-child(11) > b
+        filters:
+          - name: trim
+            args: "x"
+      size:
+        selector: td:nth-child(11)
+        remove: b
+        filters:
+          - name: replace
+            args: ["time", ""]
+      downloadvolumefactor:
+        case:
+          img[src="./pic/freedownload.gif"]: "0"
+          "*": "1"
+      uploadvolumefactor:
+        case:
+          img[src="./pic/x2.gif"]: "2"
+          "*": "1"
+      date:
+        selector: td:nth-child(2)
+        remove: a, img
+        filters:
+          - name: replace
+            args: ["\xA0", " "]
+          - name: replace
+            args: ["Ma", "Today"]
+          - name: replace
+            args: ["Tegnap", "Yesterday"]
+          - name: re_replace
+            args: ["12:(\\d\\d) PM", "00:$1 PM"]
diff --git a/src/Jackett/Engine.cs b/src/Jackett/Engine.cs
index 87e38fe10c240094abc41bee7b9cdeb3c6fb94f0..2809aeda74a0151fb46a3ee2f14fce8a75db43ea 100644
--- a/src/Jackett/Engine.cs
+++ b/src/Jackett/Engine.cs
@@ -1,191 +1,191 @@
-using Autofac;
-using Jackett.Services;
-using NLog;
-using NLog.Config;
-using NLog.LayoutRenderers;
-using NLog.Targets;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett
-{
-    public class Engine
-    {
-        private static IContainer container = null;
-
-        static Engine()
-        {
-            BuildContainer();
-
-        }
-
-        public static void BuildContainer()
-        {
-            var builder = new ContainerBuilder();
-            builder.RegisterModule<JackettModule>();
-            container = builder.Build();
-
-            // Register the container in itself to allow for late resolves
-            var secondaryBuilder = new ContainerBuilder();
-            secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
-            SetupLogging(secondaryBuilder);
-            secondaryBuilder.Update(container);
-
-        }
-
-        public static IContainer GetContainer()
-        {
-            return container;
-        }
-
-        public static bool IsWindows
-        {
-            get
-            {
-                return Environment.OSVersion.Platform == PlatformID.Win32NT;
-            }
-        }
-
-        public static IConfigurationService ConfigService
-        {
-            get
-            {
-                return container.Resolve<IConfigurationService>();
-            }
-        }
-
-        public static IProcessService ProcessService
-        {
-            get
-            {
-                return container.Resolve<IProcessService>();
-            }
-        }
-
-        public static IServiceConfigService ServiceConfig
-        {
-            get
-            {
-                return container.Resolve<IServiceConfigService>();
-            }
-        }
-
-        public static ITrayLockService LockService
-        {
-            get
-            {
-                return container.Resolve<ITrayLockService>();
-            }
-        }
-
-        public static IServerService Server
-        {
-            get
-            {
-                return container.Resolve<IServerService>();
-            }
-        }
-
-        public static IRunTimeService RunTime
-        {
-            get
-            {
-                return container.Resolve<IRunTimeService>();
-            }
-        }
-
-        public static Logger Logger
-        {
-            get
-            {
-                return container.Resolve<Logger>();
-            }
-        }
-
-        public static ISecuityService SecurityService
-        {
-            get
-            {
-                return container.Resolve<ISecuityService>();
-            }
-        }
-
-
-        public static void SetupLogging(ContainerBuilder builder = null, string logfile = "log.txt")
-        {
-            var logLevel = Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info;
-            // Add custom date time format renderer as the default is too long
-            ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("simpledatetime", typeof(SimpleDateTimeRenderer));
-
-            var logConfig = new LoggingConfiguration();
-            var logFile = new FileTarget();
-            logConfig.AddTarget("file", logFile);
-            logFile.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
-            logFile.FileName = Path.Combine(ConfigurationService.GetAppDataFolderStatic(), logfile);
-            logFile.ArchiveFileName = "log.{#####}.txt";
-            logFile.ArchiveAboveSize = 500000;
-            logFile.MaxArchiveFiles = 5;
-            logFile.KeepFileOpen = false;
-            logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
-            var logFileRule = new LoggingRule("*", logLevel, logFile);
-            logConfig.LoggingRules.Add(logFileRule);
-
-            var logConsole = new ColoredConsoleTarget();
-            logConfig.AddTarget("console", logConsole);
-
-            logConsole.Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}";
-            var logConsoleRule = new LoggingRule("*", logLevel, logConsole);
-            logConfig.LoggingRules.Add(logConsoleRule);
-
-            var logService = new LogCacheService();
-            logConfig.AddTarget("service", logService);
-            var serviceRule = new LoggingRule("*", logLevel, logService);
-            logConfig.LoggingRules.Add(serviceRule);
-
-            LogManager.Configuration = logConfig;
-            if (builder != null)
-            {
-                builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
-            }
-        }
-
-        public static void SetLogLevel(LogLevel level)
-        {
-
-            foreach (var rule in LogManager.Configuration.LoggingRules)
-            {
-                if (level == LogLevel.Debug)
-                {
-                    if (!rule.Levels.Contains(LogLevel.Debug))
-                    {
-                        rule.EnableLoggingForLevel(LogLevel.Debug);
-                    }
-                }
-                else
-                {
-                    if (rule.Levels.Contains(LogLevel.Debug))
-                    {
-                        rule.DisableLoggingForLevel(LogLevel.Debug);
-                    }
-                }
-
-            }
-
-            LogManager.ReconfigExistingLoggers();
-        }
-    }
-
-
-    [LayoutRenderer("simpledatetime")]
-    public class SimpleDateTimeRenderer : LayoutRenderer
-    {
-        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
-        {
-            builder.Append(DateTime.Now.ToString("MM-dd HH:mm:ss"));
-        }
-    }
-}
+using Autofac;
+using Jackett.Services;
+using NLog;
+using NLog.Config;
+using NLog.LayoutRenderers;
+using NLog.Targets;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett
+{
+    public class Engine
+    {
+        private static IContainer container = null;
+
+        static Engine()
+        {
+            BuildContainer();
+
+        }
+
+        public static void BuildContainer()
+        {
+            var builder = new ContainerBuilder();
+            builder.RegisterModule<JackettModule>();
+            container = builder.Build();
+
+            // Register the container in itself to allow for late resolves
+            var secondaryBuilder = new ContainerBuilder();
+            secondaryBuilder.RegisterInstance<IContainer>(container).SingleInstance();
+            SetupLogging(secondaryBuilder);
+            secondaryBuilder.Update(container);
+
+        }
+
+        public static IContainer GetContainer()
+        {
+            return container;
+        }
+
+        public static bool IsWindows
+        {
+            get
+            {
+                return Environment.OSVersion.Platform == PlatformID.Win32NT;
+            }
+        }
+
+        public static IConfigurationService ConfigService
+        {
+            get
+            {
+                return container.Resolve<IConfigurationService>();
+            }
+        }
+
+        public static IProcessService ProcessService
+        {
+            get
+            {
+                return container.Resolve<IProcessService>();
+            }
+        }
+
+        public static IServiceConfigService ServiceConfig
+        {
+            get
+            {
+                return container.Resolve<IServiceConfigService>();
+            }
+        }
+
+        public static ITrayLockService LockService
+        {
+            get
+            {
+                return container.Resolve<ITrayLockService>();
+            }
+        }
+
+        public static IServerService Server
+        {
+            get
+            {
+                return container.Resolve<IServerService>();
+            }
+        }
+
+        public static IRunTimeService RunTime
+        {
+            get
+            {
+                return container.Resolve<IRunTimeService>();
+            }
+        }
+
+        public static Logger Logger
+        {
+            get
+            {
+                return container.Resolve<Logger>();
+            }
+        }
+
+        public static ISecuityService SecurityService
+        {
+            get
+            {
+                return container.Resolve<ISecuityService>();
+            }
+        }
+
+
+        public static void SetupLogging(ContainerBuilder builder = null, string logfile = "log.txt")
+        {
+            var logLevel = Startup.TracingEnabled ? LogLevel.Debug : LogLevel.Info;
+            // Add custom date time format renderer as the default is too long
+            ConfigurationItemFactory.Default.LayoutRenderers.RegisterDefinition("simpledatetime", typeof(SimpleDateTimeRenderer));
+
+            var logConfig = new LoggingConfiguration();
+            var logFile = new FileTarget();
+            logConfig.AddTarget("file", logFile);
+            logFile.Layout = "${longdate} ${level} ${message} ${exception:format=ToString}";
+            logFile.FileName = Path.Combine(ConfigurationService.GetAppDataFolderStatic(), logfile);
+            logFile.ArchiveFileName = "log.{#####}.txt";
+            logFile.ArchiveAboveSize = 500000;
+            logFile.MaxArchiveFiles = 5;
+            logFile.KeepFileOpen = false;
+            logFile.ArchiveNumbering = ArchiveNumberingMode.DateAndSequence;
+            var logFileRule = new LoggingRule("*", logLevel, logFile);
+            logConfig.LoggingRules.Add(logFileRule);
+
+            var logConsole = new ColoredConsoleTarget();
+            logConfig.AddTarget("console", logConsole);
+
+            logConsole.Layout = "${simpledatetime} ${level} ${message} ${exception:format=ToString}";
+            var logConsoleRule = new LoggingRule("*", logLevel, logConsole);
+            logConfig.LoggingRules.Add(logConsoleRule);
+
+            var logService = new LogCacheService();
+            logConfig.AddTarget("service", logService);
+            var serviceRule = new LoggingRule("*", logLevel, logService);
+            logConfig.LoggingRules.Add(serviceRule);
+
+            LogManager.Configuration = logConfig;
+            if (builder != null)
+            {
+                builder.RegisterInstance<Logger>(LogManager.GetCurrentClassLogger()).SingleInstance();
+            }
+        }
+
+        public static void SetLogLevel(LogLevel level)
+        {
+
+            foreach (var rule in LogManager.Configuration.LoggingRules)
+            {
+                if (level == LogLevel.Debug)
+                {
+                    if (!rule.Levels.Contains(LogLevel.Debug))
+                    {
+                        rule.EnableLoggingForLevel(LogLevel.Debug);
+                    }
+                }
+                else
+                {
+                    if (rule.Levels.Contains(LogLevel.Debug))
+                    {
+                        rule.DisableLoggingForLevel(LogLevel.Debug);
+                    }
+                }
+
+            }
+
+            LogManager.ReconfigExistingLoggers();
+        }
+    }
+
+
+    [LayoutRenderer("simpledatetime")]
+    public class SimpleDateTimeRenderer : LayoutRenderer
+    {
+        protected override void Append(StringBuilder builder, LogEventInfo logEvent)
+        {
+            builder.Append(DateTime.Now.ToString("MM-dd HH:mm:ss"));
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/7tor.cs b/src/Jackett/Indexers/7tor.cs
index fc5bae7b1e1dfe6fd076a3f1fa9e7265057e9031..a2c534686d0156944092d9162dd37e2b29b45c39 100644
--- a/src/Jackett/Indexers/7tor.cs
+++ b/src/Jackett/Indexers/7tor.cs
@@ -10,12 +10,12 @@ using System;
 using System.Text;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using AngleSharp.Parser.Html;
-using AngleSharp.Dom;
-using System.Text.RegularExpressions;
-using System.Web;
-
+using System.Collections.Specialized;
+using AngleSharp.Parser.Html;
+using AngleSharp.Dom;
+using System.Text.RegularExpressions;
+using System.Web;
+
 namespace Jackett.Indexers
 {
     public class SevenTor : BaseIndexer, IIndexer
@@ -39,1548 +39,1548 @@ namespace Jackett.Indexers
                    logger: l,
                    p: ps,
                    configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
+        {
             Encoding = Encoding.UTF8;
             Language = "ru-ru";
             Type = "semi-private";
 
-            AddCategoryMapping(30, TorznabCatType.Movies, "Video content");
-            AddCategoryMapping(31, TorznabCatType.TVDocumentary, "   Documentary films, TV and other video");
-            AddCategoryMapping(127, TorznabCatType.TVDocumentary, "      Documentary movies and TV shows");
-            AddCategoryMapping(1071, TorznabCatType.TVDocumentary, "         Documentary (DVD)");
-            AddCategoryMapping(1069, TorznabCatType.TVDocumentary, "         Documentary (HD Video)");
-            AddCategoryMapping(1070, TorznabCatType.TVDocumentary, "            TV shows (HD Video), non-documentary");
-            AddCategoryMapping(1843, TorznabCatType.TVDocumentary, "            Biographies. Personality and idols (HD Video)");
-            AddCategoryMapping(1844, TorznabCatType.TVDocumentary, "            Military Science (HD Video)");
-            AddCategoryMapping(1845, TorznabCatType.TVDocumentary, "            Natural science, science and technology (HD Video)");
-            AddCategoryMapping(1846, TorznabCatType.TVDocumentary, "            Travel and Tourism (HD Video)");
-            AddCategoryMapping(1847, TorznabCatType.TVDocumentary, "            Flora and fauna (HD Video)");
-            AddCategoryMapping(1848, TorznabCatType.TVDocumentary, "            History (HD Video)");
-            AddCategoryMapping(1849, TorznabCatType.TVDocumentary, "            BBC, Discovery, National Geographic (HD Video)");
-            AddCategoryMapping(1850, TorznabCatType.TVDocumentary, "            Crime Documentary (HD Video)");
-            AddCategoryMapping(1072, TorznabCatType.TVDocumentary, "         Biographies. Personality and idols");
-            AddCategoryMapping(1073, TorznabCatType.TVDocumentary, "         Documentary movies and TV shows on film and animation (including biographies)");
-            AddCategoryMapping(1074, TorznabCatType.TVDocumentary, "         Art, Art History");
-            AddCategoryMapping(1075, TorznabCatType.TVDocumentary, "         Documentaries and television music (including biographies)");
-            AddCategoryMapping(1076, TorznabCatType.TVDocumentary, "         criminal documentary");
-            AddCategoryMapping(1077, TorznabCatType.TVDocumentary, "         Secrets of the Ages / Special Services / Conspiracy Theory");
-            AddCategoryMapping(1078, TorznabCatType.TVDocumentary, "         Movies and TV shows on military issues");
-            AddCategoryMapping(1079, TorznabCatType.TVDocumentary, "            The Second World War");
-            AddCategoryMapping(1675, TorznabCatType.TVDocumentary, "            Fleet");
-            AddCategoryMapping(1080, TorznabCatType.TVDocumentary, "         Accidents / Accidents / Disasters");
-            AddCategoryMapping(1081, TorznabCatType.TVDocumentary, "         Aviation (video)");
-            AddCategoryMapping(1674, TorznabCatType.TVDocumentary, "            Wings of Russia");
-            AddCategoryMapping(1082, TorznabCatType.TVDocumentary, "         Space (Video)");
-            AddCategoryMapping(576, TorznabCatType.TVDocumentary, "         Popular-science film");
-            AddCategoryMapping(1083, TorznabCatType.TVDocumentary, "         The flora and fauna of the (video)");
-            AddCategoryMapping(1084, TorznabCatType.TVDocumentary, "         Travel and Tourism (video)");
-            AddCategoryMapping(1085, TorznabCatType.TVDocumentary, "         Social talk show");
-            AddCategoryMapping(1086, TorznabCatType.TVDocumentary, "         Information-analytical and socio-political programs");
-            AddCategoryMapping(1087, TorznabCatType.TVDocumentary, "         Architecture and Construction (video)");
-            AddCategoryMapping(1088, TorznabCatType.TVDocumentary, "         All about home, life and design");
-            AddCategoryMapping(1094, TorznabCatType.TVDocumentary, "         The era of the Soviet Union (video)");
-            AddCategoryMapping(1095, TorznabCatType.TVDocumentary, "         Battle of psychics / Theory improbability / Seekers / Galileo");
-            AddCategoryMapping(1096, TorznabCatType.TVDocumentary, "         Russian sensation / Program Maximum / Profession Reporter / Ukrainian sensation");
-            AddCategoryMapping(1097, TorznabCatType.TVDocumentary, "         Paranormal activity");
-            AddCategoryMapping(1098, TorznabCatType.TVDocumentary, "         Alternative history, Science (video)");
-            AddCategoryMapping(1099, TorznabCatType.TVDocumentary, "         Vnezhanrovaya documentary");
-            AddCategoryMapping(1660, TorznabCatType.TVDocumentary, "         Foreign TV-brands");
-            AddCategoryMapping(1089, TorznabCatType.TVDocumentary, "            BBC");
-            AddCategoryMapping(1090, TorznabCatType.TVDocumentary, "            Discovery");
-            AddCategoryMapping(1091, TorznabCatType.TVDocumentary, "            National Geographic");
-            AddCategoryMapping(1661, TorznabCatType.TVDocumentary, "            Animal Planet");
-            AddCategoryMapping(1662, TorznabCatType.TVDocumentary, "            Da Vinci Learning");
-            AddCategoryMapping(1663, TorznabCatType.TVDocumentary, "            History Channel");
-            AddCategoryMapping(1664, TorznabCatType.TVDocumentary, "            PBS");
-            AddCategoryMapping(1665, TorznabCatType.TVDocumentary, "            Readers Digest");
-            AddCategoryMapping(1666, TorznabCatType.TVDocumentary, "            I wonder about everything");
-            AddCategoryMapping(1667, TorznabCatType.TVDocumentary, "            Mega-Projects");
-            AddCategoryMapping(1668, TorznabCatType.TVDocumentary, "            Prehistoric world");
-            AddCategoryMapping(1669, TorznabCatType.TVDocumentary, "            World of Tomorrow");
-            AddCategoryMapping(1670, TorznabCatType.TVDocumentary, "            Jacques Cousteau Odyssey");
-            AddCategoryMapping(1671, TorznabCatType.TVDocumentary, "            Secrets and Mysteries");
-            AddCategoryMapping(1672, TorznabCatType.TVDocumentary, "         History");
-            AddCategoryMapping(1092, TorznabCatType.TVDocumentary, "            History: Ancient World / Antiquity / Middle Ages (video)");
-            AddCategoryMapping(1093, TorznabCatType.TVDocumentary, "            History: modern and contemporary times");
-            AddCategoryMapping(1673, TorznabCatType.TVDocumentary, "         Relax, landscape film");
-            AddCategoryMapping(1100, TorznabCatType.TVDocumentary, "         Miscellaneous / nekonditsiya (documentary and transfer)");
-            AddCategoryMapping(569, TorznabCatType.TV, "      Entertaining TV programs and shows, fun and humor");
-            AddCategoryMapping(1101, TorznabCatType.TV, "         Mind games and quizzes");
-            AddCategoryMapping(1102, TorznabCatType.TV, "         Reality and talk show host / category / impressions");
-            AddCategoryMapping(1103, TorznabCatType.TV, "         children's TV Shows");
-            AddCategoryMapping(1104, TorznabCatType.TV, "         KVN");
-            AddCategoryMapping(1105, TorznabCatType.TV, "         Drink Post");
-            AddCategoryMapping(1106, TorznabCatType.TV, "         Distorting Mirror / town / in the town");
-            AddCategoryMapping(1107, TorznabCatType.TV, "         ice show");
-            AddCategoryMapping(1108, TorznabCatType.TV, "         Thank God you came!");
-            AddCategoryMapping(1109, TorznabCatType.TV, "         dinner Party");
-            AddCategoryMapping(1110, TorznabCatType.TV, "         Good jokes");
-            AddCategoryMapping(1111, TorznabCatType.TV, "         Evening Quarter");
-            AddCategoryMapping(1112, TorznabCatType.TV, "         Films with a funny transfer (parody)");
-            AddCategoryMapping(1113, TorznabCatType.TV, "         Stand-up comedy");
-            AddCategoryMapping(1114, TorznabCatType.TV, "         Moment of glory");
-            AddCategoryMapping(1115, TorznabCatType.TV, "         Ukrainian Show");
-            AddCategoryMapping(1116, TorznabCatType.TV, "         Star Factory");
-            AddCategoryMapping(1117, TorznabCatType.TV, "         Dance shows, concerts, performances");
-            AddCategoryMapping(1118, TorznabCatType.TV, "         Circus");
-            AddCategoryMapping(1119, TorznabCatType.TV, "         School for Scandal");
-            AddCategoryMapping(1120, TorznabCatType.TV, "         Satirists and humorists");
-            AddCategoryMapping(1873, TorznabCatType.TV, "         Musical show");
-            AddCategoryMapping(1121, TorznabCatType.TV, "         Humorous audio transmission");
-            AddCategoryMapping(1122, TorznabCatType.TV, "         Audio and video clips (Jokes and humor)");
-            AddCategoryMapping(32, TorznabCatType.Movies, "   Foreign movies");
-            AddCategoryMapping(567, TorznabCatType.Movies, "      Foreign films 2016");
-            AddCategoryMapping(37, TorznabCatType.Movies, "      Foreign films 2011 - 2015 the year");
-            AddCategoryMapping(38, TorznabCatType.Movies, "      Foreign films of the year 2006-2010");
-            AddCategoryMapping(39, TorznabCatType.Movies, "      Foreign films of the year 2001-2005");
-            AddCategoryMapping(40, TorznabCatType.Movies, "      Foreign films 1991-2000");
-            AddCategoryMapping(1031, TorznabCatType.Movies, "      Foreign films until 1990");
-            AddCategoryMapping(41, TorznabCatType.Movies, "      Classic foreign film");
-            AddCategoryMapping(1044, TorznabCatType.Movies, "         Classic foreign film (DVD Video)");
-            AddCategoryMapping(1042, TorznabCatType.Movies, "         Classic foreign film (HD Video)");
-            AddCategoryMapping(1051, TorznabCatType.Movies, "      Foreign films (DVD)");
-            AddCategoryMapping(43, TorznabCatType.Movies, "      Foreign films (HD Video)");
-            AddCategoryMapping(773, TorznabCatType.Movies, "      Grindhouse");
-            AddCategoryMapping(1040, TorznabCatType.Movies, "         Grindhouse DVD and HD Video");
-            AddCategoryMapping(913, TorznabCatType.Movies, "      Asian movies");
-            AddCategoryMapping(1010, TorznabCatType.MoviesSD, "         Asian movies (DVD Video)");
-            AddCategoryMapping(1052, TorznabCatType.MoviesHD, "         Asian films (HD Video)");
-            AddCategoryMapping(1032, TorznabCatType.Movies, "      Indian film");
-            AddCategoryMapping(1043, TorznabCatType.Movies, "         Indian Cinema DVD and HD Video");
-            AddCategoryMapping(1039, TorznabCatType.Movies, "      Shorts");
-            AddCategoryMapping(1041, TorznabCatType.Movies, "      Sound track and Translations");
-            AddCategoryMapping(1804, TorznabCatType.Movies, "      Foreign films without translation");
-            AddCategoryMapping(1805, TorznabCatType.Movies, "         Foreign films in the original");
-            AddCategoryMapping(1806, TorznabCatType.Movies, "            Foreign films in the original (HD)");
-            AddCategoryMapping(1807, TorznabCatType.Movies, "         Foreign films with translation into other languages");
-            AddCategoryMapping(33, TorznabCatType.Movies, "   national cinema");
-            AddCategoryMapping(568, TorznabCatType.Movies, "      Domestic films 2016");
-            AddCategoryMapping(44, TorznabCatType.Movies, "      Domestic films of 2011 - 2015 the year");
-            AddCategoryMapping(45, TorznabCatType.Movies, "      Domestic films of the year 2006-2010");
-            AddCategoryMapping(46, TorznabCatType.Movies, "      Domestic films of the year 2001-2005");
-            AddCategoryMapping(47, TorznabCatType.Movies, "      Domestic films of the year 1992-2000");
-            AddCategoryMapping(48, TorznabCatType.Movies, "      Cinema of the USSR, Soviet Russia, the Russian republic (1917-1991)");
-            AddCategoryMapping(1609, TorznabCatType.Movies, "      Films of the Russian Empire (until 1917)");
-            AddCategoryMapping(1048, TorznabCatType.Movies, "      National cinema (DVD)");
-            AddCategoryMapping(49, TorznabCatType.Movies, "      National cinema (HD Video)");
-            AddCategoryMapping(1046, TorznabCatType.Movies, "      Author debuts");
-            AddCategoryMapping(1047, TorznabCatType.Movies, "      Child domestic films");
-            AddCategoryMapping(1011, TorznabCatType.Movies, "   Art-house cinema and author");
-            AddCategoryMapping(1012, TorznabCatType.Movies, "      Art-house and auteur cinema (DVD)");
-            AddCategoryMapping(1038, TorznabCatType.Movies, "      Art-house and auteur cinema (HD Video)");
-            AddCategoryMapping(1033, TorznabCatType.Movies, "      Author cinema");
-            AddCategoryMapping(1035, TorznabCatType.Movies, "      Shorts (Art-house cinema and author)");
-            AddCategoryMapping(1036, TorznabCatType.Movies, "      Documentaries (Art-house cinema and author)");
-            AddCategoryMapping(1037, TorznabCatType.Movies, "      Animation (Art-house cinema and author)");
-            AddCategoryMapping(1617, TorznabCatType.Movies, "      Intelligent movie");
-            AddCategoryMapping(34, TorznabCatType.TV, "   TV series");
-            AddCategoryMapping(51, TorznabCatType.TV, "      Domestic series");
-            AddCategoryMapping(1860, TorznabCatType.TV, "         Domestic series 2016");
-            AddCategoryMapping(1810, TorznabCatType.TV, "         Domestic series 2015");
-            AddCategoryMapping(574, TorznabCatType.TV, "         Domestic series 2014");
-            AddCategoryMapping(50, TorznabCatType.TV, "      Foreign TV series");
-            AddCategoryMapping(1861, TorznabCatType.TV, "         Foreign series 2016");
-            AddCategoryMapping(1809, TorznabCatType.TV, "         Foreign series 2015");
-            AddCategoryMapping(575, TorznabCatType.TV, "         Foreign series 2014");
-            AddCategoryMapping(1181, TorznabCatType.TV, "         Foreign TV shows (HD Video)");
-            AddCategoryMapping(1184, TorznabCatType.TV, "         Soaps Spain, Italy, Latin America, Turkey and India");
-            AddCategoryMapping(1185, TorznabCatType.TV, "            Indian series");
-            AddCategoryMapping(1186, TorznabCatType.TV, "            spanish series");
-            AddCategoryMapping(1187, TorznabCatType.TV, "            Italian TV series");
-            AddCategoryMapping(1615, TorznabCatType.TV, "            Latin American soap operas");
-            AddCategoryMapping(1189, TorznabCatType.TV, "               Official short version Latin American serials");
-            AddCategoryMapping(1190, TorznabCatType.TV, "               Latin American soap operas with the voice acting (folders distribution)");
-            AddCategoryMapping(1191, TorznabCatType.TV, "               Latin American serials with subtitles");
-            AddCategoryMapping(1188, TorznabCatType.TV, "            turkish TV series");
-            AddCategoryMapping(1192, TorznabCatType.TV, "            Serials OST Spain, Italy, Latin America, Turkey and India");
-            AddCategoryMapping(1193, TorznabCatType.TV, "            For sub-standard hands");
-            AddCategoryMapping(1194, TorznabCatType.TV, "         Asian series");
-            AddCategoryMapping(1195, TorznabCatType.TV, "            Chinese serials with subtitles");
-            AddCategoryMapping(1196, TorznabCatType.TV, "            Korean soap operas with the voice acting");
-            AddCategoryMapping(1197, TorznabCatType.TV, "            Korean serials with subtitles");
-            AddCategoryMapping(1198, TorznabCatType.TV, "            Other Asian series with the voice acting");
-            AddCategoryMapping(1199, TorznabCatType.TV, "            Taiwanese serials with subtitles");
-            AddCategoryMapping(1200, TorznabCatType.TV, "            Japanese serials with subtitles");
-            AddCategoryMapping(1201, TorznabCatType.TV, "            Japanese TV series with the voice acting");
-            AddCategoryMapping(1202, TorznabCatType.TV, "            VMV and others. Videos");
-            AddCategoryMapping(1203, TorznabCatType.TV, "            OST Asian series");
-            AddCategoryMapping(1616, TorznabCatType.TV, "         Soaps with Ukrainian sound track");
-            AddCategoryMapping(1049, TorznabCatType.TV, "   Theater");
-            AddCategoryMapping(1050, TorznabCatType.TV, "      Benefit. Master of Arts of Russian theater and cinema.");
-            AddCategoryMapping(1053, TorznabCatType.Movies3D, "   3D / Stereo (Cinema, Animation, Video, TV &amp; Sports)");
-            AddCategoryMapping(1054, TorznabCatType.Movies3D, "      3D Movies");
-            AddCategoryMapping(581, TorznabCatType.Movies3D, "         Foreign Movies 3D");
-            AddCategoryMapping(1614, TorznabCatType.Movies3D, "            Asian Movies 3D");
-            AddCategoryMapping(1613, TorznabCatType.Movies3D, "         Domestic 3D Movies");
-            AddCategoryMapping(586, TorznabCatType.Movies3D, "      3D Animation");
-            AddCategoryMapping(1055, TorznabCatType.Movies3D, "      3D Documentaries");
-            AddCategoryMapping(1056, TorznabCatType.Movies3D, "      3D Sports");
-            AddCategoryMapping(1057, TorznabCatType.Movies3D, "      3D Clips, Music Videos, Movie Trailers");
-            AddCategoryMapping(53, TorznabCatType.TVAnime, "   Animation and cartoons");
-            AddCategoryMapping(341, TorznabCatType.TVAnime, "      Foreign cartoons");
-            AddCategoryMapping(344, TorznabCatType.TVAnime, "         Foreign cartoons (DVD)");
-            AddCategoryMapping(342, TorznabCatType.TVAnime, "      Domestic cartoons");
-            AddCategoryMapping(1062, TorznabCatType.TVAnime, "         Domestic full-length cartoons");
-            AddCategoryMapping(1061, TorznabCatType.TVAnime, "         Domestic cartoons (DVD)");
-            AddCategoryMapping(346, TorznabCatType.TVAnime, "      short cartoons");
-            AddCategoryMapping(1058, TorznabCatType.TVAnime, "         Short Film (HD Video)");
-            AddCategoryMapping(1060, TorznabCatType.TVAnime, "         Foreign short cartoons");
-            AddCategoryMapping(1059, TorznabCatType.TVAnime, "         Foreign Short Film (DVD)");
-            AddCategoryMapping(345, TorznabCatType.TVAnime, "      Cartoons HD-Video");
-            AddCategoryMapping(1063, TorznabCatType.TVAnime, "      cartoon Puzzle");
-            AddCategoryMapping(343, TorznabCatType.TVAnime, "      Serial cartoons");
-            AddCategoryMapping(1813, TorznabCatType.TVAnime, "      Cartoons and cartoons without translation");
-            AddCategoryMapping(1814, TorznabCatType.TVAnime, "         Cartoons and cartoons with the Ukrainian sound track");
-            AddCategoryMapping(1064, TorznabCatType.TVAnime, "      Archive and nekonditsiya cartoons and animated series");
-            AddCategoryMapping(54, TorznabCatType.TVAnime, "   Anime and everything associated with him");
-            AddCategoryMapping(55, TorznabCatType.TVAnime, "      Anime (Main)");
-            AddCategoryMapping(976, TorznabCatType.TVAnime, "      Anime (pleerny subsection)");
-            AddCategoryMapping(977, TorznabCatType.TVAnime, "      Anime (QC subsection)");
-            AddCategoryMapping(333, TorznabCatType.TVAnime, "      Anime DVD-Video");
-            AddCategoryMapping(334, TorznabCatType.TVAnime, "      Anime (HD and Blu-ray)");
-            AddCategoryMapping(1815, TorznabCatType.TVAnime, "      OST to Anime");
-            AddCategoryMapping(979, TorznabCatType.TVAnime, "         Anime OST to (lossless)");
-            AddCategoryMapping(335, TorznabCatType.TVAnime, "         OST to Anime (mp3 and others lossy-format)");
-            AddCategoryMapping(336, TorznabCatType.TVAnime, "      Manga and other art");
-            AddCategoryMapping(474, TorznabCatType.TVAnime, "         Manga");
-            AddCategoryMapping(680, TorznabCatType.TVAnime, "         Wallpapers, artbook, and others.");
-            AddCategoryMapping(60, TorznabCatType.TVAnime, "      Anime (Hentai)");
-            AddCategoryMapping(978, TorznabCatType.TVAnime, "      AMV etc. Videos");
-            AddCategoryMapping(980, TorznabCatType.TVAnime, "      Japanese cartoons");
-            AddCategoryMapping(1065, TorznabCatType.TVAnime, "      Archive and nekonditsiya Anime");
-            AddCategoryMapping(922, TorznabCatType.Movies, "   Faith and Religion (Video)");
-            AddCategoryMapping(1068, TorznabCatType.Movies, "      Islam (video)");
-            AddCategoryMapping(1067, TorznabCatType.Movies, "      Cults and new religious movements (video)");
-            AddCategoryMapping(1066, TorznabCatType.Movies, "      Religions of India, Tibet and East Asia (video)");
-            AddCategoryMapping(923, TorznabCatType.Movies, "      Christianity (video)");
-            AddCategoryMapping(577, TorznabCatType.TVSport, "   Health &amp; Sports (sports tournaments, films and programs etc)");
-            AddCategoryMapping(583, TorznabCatType.TVSport, "      wrestling");
-            AddCategoryMapping(740, TorznabCatType.TVSport, "         Professional Wrestling");
-            AddCategoryMapping(1176, TorznabCatType.TVSport, "         Independent Wrestling");
-            AddCategoryMapping(1177, TorznabCatType.TVSport, "         International Wrestling");
-            AddCategoryMapping(1178, TorznabCatType.TVSport, "         Oldschool Wrestling");
-            AddCategoryMapping(1179, TorznabCatType.TVSport, "         Documentary Wrestling");
-            AddCategoryMapping(677, TorznabCatType.TVSport, "      cycle racing");
-            AddCategoryMapping(724, TorznabCatType.TVSport, "      Tennis");
-            AddCategoryMapping(925, TorznabCatType.TVSport, "      Athletics / Water Sports");
-            AddCategoryMapping(926, TorznabCatType.TVSport, "      motorcycling");
-            AddCategoryMapping(930, TorznabCatType.TVSport, "      Hockey");
-            AddCategoryMapping(1171, TorznabCatType.TVSport, "         Hockey / Bandy");
-            AddCategoryMapping(1172, TorznabCatType.TVSport, "         International hockey tournaments");
-            AddCategoryMapping(1173, TorznabCatType.TVSport, "         KXL");
-            AddCategoryMapping(932, TorznabCatType.TVSport, "         NHL (until 2011/12)");
-            AddCategoryMapping(931, TorznabCatType.TVSport, "         NHL (2013)");
-            AddCategoryMapping(1174, TorznabCatType.TVSport, "         USSR - Canada");
-            AddCategoryMapping(1175, TorznabCatType.TVSport, "         Documentaries and Analysis (hockey)");
-            AddCategoryMapping(1123, TorznabCatType.TVSport, "      Motorsports");
-            AddCategoryMapping(1125, TorznabCatType.TVSport, "      Formula 1");
-            AddCategoryMapping(1126, TorznabCatType.TVSport, "         Formula 1 2012-2015");
-            AddCategoryMapping(1127, TorznabCatType.TVSport, "         Formula January 2016");
-            AddCategoryMapping(1128, TorznabCatType.TVSport, "      Volleyball / Handball");
-            AddCategoryMapping(1129, TorznabCatType.TVSport, "      Billiards");
-            AddCategoryMapping(1130, TorznabCatType.TVSport, "      Poker");
-            AddCategoryMapping(1131, TorznabCatType.TVSport, "      Bodybuilding / Power Sports");
-            AddCategoryMapping(1132, TorznabCatType.TVSport, "      Boxing");
-            AddCategoryMapping(1133, TorznabCatType.TVSport, "      Classic arts");
-            AddCategoryMapping(1134, TorznabCatType.TVSport, "      MMA and K-1");
-            AddCategoryMapping(1135, TorznabCatType.TVSport, "      American football");
-            AddCategoryMapping(1136, TorznabCatType.TVSport, "      Rugby");
-            AddCategoryMapping(1137, TorznabCatType.TVSport, "      Baseball");
-            AddCategoryMapping(1138, TorznabCatType.TVSport, "      Badminton / Table Tennis");
-            AddCategoryMapping(1139, TorznabCatType.TVSport, "      Gymnastics / Dance Competitions");
-            AddCategoryMapping(1140, TorznabCatType.TVSport, "      Winter sports");
-            AddCategoryMapping(1141, TorznabCatType.TVSport, "      Figure skating");
-            AddCategoryMapping(1142, TorznabCatType.TVSport, "      Biathlon");
-            AddCategoryMapping(1143, TorznabCatType.TVSport, "      Extreme sports");
-            AddCategoryMapping(1144, TorznabCatType.TVSport, "      Football");
-            AddCategoryMapping(1146, TorznabCatType.TVSport, "         Russia 2015-2016");
-            AddCategoryMapping(1145, TorznabCatType.TVSport, "         Russia 2014-2015");
-            AddCategoryMapping(1147, TorznabCatType.TVSport, "         Russia / USSR");
-            AddCategoryMapping(1148, TorznabCatType.TVSport, "         England");
-            AddCategoryMapping(1149, TorznabCatType.TVSport, "         Spain");
-            AddCategoryMapping(1150, TorznabCatType.TVSport, "         Italy");
-            AddCategoryMapping(1151, TorznabCatType.TVSport, "         Germany");
-            AddCategoryMapping(1851, TorznabCatType.TVSport, "         France");
-            AddCategoryMapping(1152, TorznabCatType.TVSport, "         Ukraine");
-            AddCategoryMapping(1153, TorznabCatType.TVSport, "         Other national championships and cups");
-            AddCategoryMapping(1154, TorznabCatType.TVSport, "         International football tournaments");
-            AddCategoryMapping(1157, TorznabCatType.TVSport, "         European Cups");
-            AddCategoryMapping(1156, TorznabCatType.TVSport, "            Eurocup 2011-2014");
-            AddCategoryMapping(1155, TorznabCatType.TVSport, "            Eurocup 2014-2015");
-            AddCategoryMapping(1161, TorznabCatType.TVSport, "            Eurocup 2015-2016");
-            AddCategoryMapping(1158, TorznabCatType.TVSport, "         European Championships");
-            AddCategoryMapping(1159, TorznabCatType.TVSport, "            European Championship 2016");
-            AddCategoryMapping(1863, TorznabCatType.TVSport, "               European Championships 2016 (Selection section)");
-            AddCategoryMapping(1864, TorznabCatType.TVSport, "               European Championship 2016 (the final part)");
-            AddCategoryMapping(1160, TorznabCatType.TVSport, "         World Championships");
-            AddCategoryMapping(1852, TorznabCatType.TVSport, "            World Championship 2018");
-            AddCategoryMapping(1162, TorznabCatType.TVSport, "         Friendly tournaments and matches");
-            AddCategoryMapping(1163, TorznabCatType.TVSport, "         The survey and analysis of transmission");
-            AddCategoryMapping(1853, TorznabCatType.TVSport, "            The survey and analytical programs 2014-2016");
-            AddCategoryMapping(1164, TorznabCatType.TVSport, "         Mini Soccer / Football");
-            AddCategoryMapping(1165, TorznabCatType.TVSport, "      Basketball");
-            AddCategoryMapping(1166, TorznabCatType.TVSport, "         International competitions");
-            AddCategoryMapping(1167, TorznabCatType.TVSport, "         NBA / NCAA (until 2000)");
-            AddCategoryMapping(1168, TorznabCatType.TVSport, "         NBA / NCAA (2000-2010 biennium).");
-            AddCategoryMapping(1169, TorznabCatType.TVSport, "         NBA / NCAA (2010-2016 biennium).");
-            AddCategoryMapping(1170, TorznabCatType.TVSport, "         European club basketball");
-            AddCategoryMapping(1885, TorznabCatType.TVSport, "      XXXI Summer Olympic Games. Rio de Janeiro 2016");
-            AddCategoryMapping(1886, TorznabCatType.TVSport, "         Football");
-            AddCategoryMapping(1887, TorznabCatType.TVSport, "         Basketball");
-            AddCategoryMapping(1888, TorznabCatType.TVSport, "         Volleyball / Beach Volleyball / Handball / Water Polo");
-            AddCategoryMapping(1889, TorznabCatType.TVSport, "         Athletics");
-            AddCategoryMapping(1890, TorznabCatType.TVSport, "         Tennis / Table Tennis / Badminton");
-            AddCategoryMapping(1891, TorznabCatType.TVSport, "         Boxing / Martial Arts and Martial Arts / Weightlifting");
-            AddCategoryMapping(1892, TorznabCatType.TVSport, "         Water Sports / Boating");
-            AddCategoryMapping(1893, TorznabCatType.TVSport, "         cycle racing");
-            AddCategoryMapping(1894, TorznabCatType.TVSport, "         Gymnastics");
-            AddCategoryMapping(1895, TorznabCatType.TVSport, "         Other Sports");
-            AddCategoryMapping(1896, TorznabCatType.TVSport, "         The survey and analysis of transmission");
-            AddCategoryMapping(1897, TorznabCatType.Books, "         Books, manuals, periodicals on the Olympic theme");
-            AddCategoryMapping(1575, TorznabCatType.Movies, "   Video for mobile devices");
-            AddCategoryMapping(1576, TorznabCatType.Movies, "      Video for Smartphones and PDAs");
-            AddCategoryMapping(1577, TorznabCatType.Movies, "      Mobile Video (3GP)");
-            AddCategoryMapping(1589, TorznabCatType.Movies, "   Video for Apple devices");
-            AddCategoryMapping(1590, TorznabCatType.Movies, "      Video (Apple)");
-            AddCategoryMapping(1592, TorznabCatType.MoviesSD, "         Movies for iPod, iPhone, iPad");
-            AddCategoryMapping(1593, TorznabCatType.MoviesSD, "         Soaps for iPod, iPhone, iPad");
-            AddCategoryMapping(1594, TorznabCatType.MoviesSD, "         Cartoons to iPod, iPhone, iPad");
-            AddCategoryMapping(1595, TorznabCatType.MoviesSD, "         Anime for iPod, iPhone, iPad");
-            AddCategoryMapping(1596, TorznabCatType.MoviesSD, "         The music video for iPod, iPhone, iPad");
-            AddCategoryMapping(1591, TorznabCatType.MoviesHD, "      Videos HD (Apple)");
-            AddCategoryMapping(1597, TorznabCatType.MoviesHD, "         HD Movies to Apple TV");
-            AddCategoryMapping(1598, TorznabCatType.MoviesHD, "         HD TV Shows on Apple TV");
-            AddCategoryMapping(1599, TorznabCatType.MoviesHD, "         Cartoon HD for Apple TV");
-            AddCategoryMapping(1600, TorznabCatType.MoviesHD, "         Documentary HD video for Apple TV");
-            AddCategoryMapping(1601, TorznabCatType.MoviesHD, "         Music HD video for Apple TV");
-            AddCategoryMapping(1568, TorznabCatType.Movies, "   Trailers and additional materials for films");
-            AddCategoryMapping(1549, TorznabCatType.Movies, "   Video consoles");
-            AddCategoryMapping(1550, TorznabCatType.Movies, "      Video for PSVita");
-            AddCategoryMapping(1551, TorznabCatType.Movies, "      Movies for PSP");
-            AddCategoryMapping(1552, TorznabCatType.Movies, "      for PSP TV Shows");
-            AddCategoryMapping(1553, TorznabCatType.Movies, "      Cartoons for PSP");
-            AddCategoryMapping(1554, TorznabCatType.Movies, "      Drama for PSP");
-            AddCategoryMapping(1555, TorznabCatType.Movies, "      Anime for PSP");
-            AddCategoryMapping(1556, TorznabCatType.Movies, "      Video to PSP");
-            AddCategoryMapping(1557, TorznabCatType.Movies, "      Videos for the PS3 and other consoles");
-            AddCategoryMapping(165, TorznabCatType.Movies, "   video Game");
-            AddCategoryMapping(1544, TorznabCatType.Movies, "      Walkthroughs");
-            AddCategoryMapping(1545, TorznabCatType.Movies, "      Lineage II Movies");
-            AddCategoryMapping(1546, TorznabCatType.Movies, "      World of Warcraft Movies");
-            AddCategoryMapping(1547, TorznabCatType.Movies, "      Counter Strike Movies");
-            AddCategoryMapping(1045, TorznabCatType.Movies, "   Video on moderation");
-            AddCategoryMapping(1607, TorznabCatType.MoviesSD, "      DVD Video on moderation");
-            AddCategoryMapping(1608, TorznabCatType.MoviesHD, "      HD Video on moderation");
-            AddCategoryMapping(1837, TorznabCatType.PCGames, "Releases SE7ENKILLS");
-            AddCategoryMapping(1839, TorznabCatType.PCGames, "   Games");
-            AddCategoryMapping(1840, TorznabCatType.PCGames, "      Patches");
-            AddCategoryMapping(1841, TorznabCatType.PCGames, "   Frequently asked questions about cs: go");
-            AddCategoryMapping(1182, TorznabCatType.PCGames, "Games");
-            AddCategoryMapping(158, TorznabCatType.PCGames, "   Games General Section");
-            AddCategoryMapping(68, TorznabCatType.PCGames, "   Games for PC");
-            AddCategoryMapping(69, TorznabCatType.PCGames, "      Hot New Releases Games");
-            AddCategoryMapping(1030, TorznabCatType.PCGames, "         Games without pills");
-            AddCategoryMapping(70, TorznabCatType.PCGames, "      Action");
-            AddCategoryMapping(148, TorznabCatType.PCGames, "         FPS (1st Person)");
-            AddCategoryMapping(149, TorznabCatType.PCGames, "         TPS (3rd Person)");
-            AddCategoryMapping(150, TorznabCatType.PCGames, "         Stealth Action");
-            AddCategoryMapping(151, TorznabCatType.PCGames, "         Tactical shooter");
-            AddCategoryMapping(71, TorznabCatType.PCGames, "      RPG");
-            AddCategoryMapping(72, TorznabCatType.PCGames, "      Strategy");
-            AddCategoryMapping(152, TorznabCatType.PCGames, "         RTS (real time strategy)");
-            AddCategoryMapping(153, TorznabCatType.PCGames, "         TBS (turn-based strategy)");
-            AddCategoryMapping(154, TorznabCatType.PCGames, "         Wargame");
-            AddCategoryMapping(155, TorznabCatType.PCGames, "         Economic strategies");
-            AddCategoryMapping(73, TorznabCatType.PCGames, "      Simulations");
-            AddCategoryMapping(74, TorznabCatType.PCGames, "         Autos and Racing");
-            AddCategoryMapping(75, TorznabCatType.PCGames, "         Sports simulators");
-            AddCategoryMapping(464, TorznabCatType.PCGames, "         Other simulators");
-            AddCategoryMapping(1531, TorznabCatType.PCGames, "         Space and flight simulators");
-            AddCategoryMapping(76, TorznabCatType.PCGames, "            Aviasimulators");
-            AddCategoryMapping(463, TorznabCatType.PCGames, "            space Simulation");
-            AddCategoryMapping(1540, TorznabCatType.PCGames, "            Microsoft Flight Simulator add-ons, and for him");
-            AddCategoryMapping(1541, TorznabCatType.PCGames, "               Scripts, meshes and airports");
-            AddCategoryMapping(1542, TorznabCatType.PCGames, "               Airplanes and helicopters");
-            AddCategoryMapping(1543, TorznabCatType.PCGames, "               Mission, traffic sounds, packs and tools");
-            AddCategoryMapping(1899, TorznabCatType.PCGames, "               Scenarios (FSX-P3D)");
-            AddCategoryMapping(77, TorznabCatType.PCGames, "      Arcade");
-            AddCategoryMapping(459, TorznabCatType.PCGames, "         Arcade (various)");
-            AddCategoryMapping(461, TorznabCatType.PCGames, "         Board &amp; Card Arcade");
-            AddCategoryMapping(78, TorznabCatType.PCGames, "      Adventure Quests");
-            AddCategoryMapping(746, TorznabCatType.PCGames, "         Quest-style \"search objects\"");
-            AddCategoryMapping(79, TorznabCatType.PCGames, "      Online Games");
-            AddCategoryMapping(743, TorznabCatType.PCGames, "         Free");
-            AddCategoryMapping(744, TorznabCatType.PCGames, "         paid");
-            AddCategoryMapping(742, TorznabCatType.PCGames, "         Other online gaming");
-            AddCategoryMapping(157, TorznabCatType.PCGames, "      For the little ones");
-            AddCategoryMapping(465, TorznabCatType.PCGames, "      Old games for PC");
-            AddCategoryMapping(466, TorznabCatType.PCGames, "         Arcade and Puzzle Games (old games)");
-            AddCategoryMapping(1871, TorznabCatType.PCGames, "            Arcade (Old Games)");
-            AddCategoryMapping(1872, TorznabCatType.PCGames, "            Puzzle games (old games)");
-            AddCategoryMapping(467, TorznabCatType.PCGames, "         Adventure quests (old games)");
-            AddCategoryMapping(468, TorznabCatType.PCGames, "         Action (old games)");
-            AddCategoryMapping(469, TorznabCatType.PCGames, "         Strategy (old games)");
-            AddCategoryMapping(470, TorznabCatType.PCGames, "         RPG (old games)");
-            AddCategoryMapping(471, TorznabCatType.PCGames, "         Simulations (old games)");
-            AddCategoryMapping(1532, TorznabCatType.PCGames, "            Autos and Racing (old games)");
-            AddCategoryMapping(1533, TorznabCatType.PCGames, "            Space simulators, flight simulators and aviaigry (old games)");
-            AddCategoryMapping(1534, TorznabCatType.PCGames, "            Sports simulators (old games)");
-            AddCategoryMapping(1535, TorznabCatType.PCGames, "            Other simulators (Old Games)");
-            AddCategoryMapping(472, TorznabCatType.PCGames, "         Multi-genre compilations (old games)");
-            AddCategoryMapping(1536, TorznabCatType.PCGames, "         Erotic games (old games)");
-            AddCategoryMapping(1537, TorznabCatType.PCGames, "         For the little ones (Old Games)");
-            AddCategoryMapping(1538, TorznabCatType.PCGames, "         Puzzle Games (Old Games)");
-            AddCategoryMapping(1539, TorznabCatType.PCGames, "         IBM PC are not compatible (old games)");
-            AddCategoryMapping(473, TorznabCatType.PCGames, "      Erotic games");
-            AddCategoryMapping(745, TorznabCatType.PCGames, "      Chess");
-            AddCategoryMapping(924, TorznabCatType.PCGames, "      game Collections");
-            AddCategoryMapping(970, TorznabCatType.PCGames, "      Other for PC-games");
-            AddCategoryMapping(1803, TorznabCatType.PCGames, "         Patches");
-            AddCategoryMapping(80, TorznabCatType.PCGames, "            Official patches");
-            AddCategoryMapping(1790, TorznabCatType.PCGames, "         Fashion, plug-ins, add-ons");
-            AddCategoryMapping(972, TorznabCatType.PCGames, "            Official mode, plug-ins, add-ons");
-            AddCategoryMapping(162, TorznabCatType.PCGames, "            Informal fashion, plugins, add-ons");
-            AddCategoryMapping(161, TorznabCatType.PCGames, "         Fun");
-            AddCategoryMapping(973, TorznabCatType.PCGames, "         Editors, emulators and other gaming utility");
-            AddCategoryMapping(160, TorznabCatType.PCGames, "         NoCD / NoDVD");
-            AddCategoryMapping(974, TorznabCatType.PCGames, "         Conservation games");
-            AddCategoryMapping(971, TorznabCatType.PCGames, "         Cheat program and trainers");
-            AddCategoryMapping(164, TorznabCatType.PCGames, "         Guidelines and passing");
-            AddCategoryMapping(163, TorznabCatType.PCGames, "         The bonus disc for the games");
-            AddCategoryMapping(159, TorznabCatType.PCGames, "      The demo version of the game and with early access");
-            AddCategoryMapping(975, TorznabCatType.PCGames, "      Anime Games");
-            AddCategoryMapping(1025, TorznabCatType.PCGames, "      Fighting");
-            AddCategoryMapping(460, TorznabCatType.PCGames, "      Logic games");
-            AddCategoryMapping(462, TorznabCatType.PCGames, "      Mini / Flash games");
-            AddCategoryMapping(1029, TorznabCatType.PCGames, "      Indie Game");
-            AddCategoryMapping(111, TorznabCatType.Console, "   Games for consoles");
-            AddCategoryMapping(458, TorznabCatType.Console, "      Portable and Console Games (general section of games for different platforms)");
-            AddCategoryMapping(129, TorznabCatType.ConsoleXbox, "      Xbox");
-            AddCategoryMapping(131, TorznabCatType.ConsoleXbox360, "         XBox360 | Games");
-            AddCategoryMapping(132, TorznabCatType.ConsoleXbox360, "         XBox360 | GOD Games");
-            AddCategoryMapping(133, TorznabCatType.ConsoleXbox360, "         XBox360 | JTAG");
-            AddCategoryMapping(134, TorznabCatType.ConsoleXbox360, "         XBox360 | 360E");
-            AddCategoryMapping(135, TorznabCatType.ConsoleXbox360, "         XBox360 | Demo");
-            AddCategoryMapping(136, TorznabCatType.ConsoleXbox360, "         XBox360 | Soft");
-            AddCategoryMapping(137, TorznabCatType.ConsoleXbox, "         Original XBox | Games");
-            AddCategoryMapping(138, TorznabCatType.ConsolePS4, "      PlayStation");
-            AddCategoryMapping(621, TorznabCatType.ConsolePS3, "         PS");
-            AddCategoryMapping(141, TorznabCatType.ConsolePS3, "         PS2 | Games");
-            AddCategoryMapping(112, TorznabCatType.ConsolePS3, "         PS3 | Games");
-            AddCategoryMapping(142, TorznabCatType.ConsolePS3, "         PS3 | Other");
-            AddCategoryMapping(139, TorznabCatType.ConsolePS4, "         PSN | Games");
-            AddCategoryMapping(140, TorznabCatType.ConsolePSP, "         PSP | Games");
-            AddCategoryMapping(622, TorznabCatType.ConsolePSP, "         PS1 games for PSP");
-            AddCategoryMapping(143, TorznabCatType.ConsolePSP, "         PSP | Programs | Other");
-            AddCategoryMapping(1548, TorznabCatType.ConsolePSP, "            Software for PSP (Homebrew)");
-            AddCategoryMapping(455, TorznabCatType.ConsolePSVita, "         PS Vita | Games");
-            AddCategoryMapping(130, TorznabCatType.ConsoleOther, "      Nintendo");
-            AddCategoryMapping(144, TorznabCatType.ConsoleNDS, "         NDS | Games");
-            AddCategoryMapping(145, TorznabCatType.ConsoleWii, "         Wii | Games");
-            AddCategoryMapping(146, TorznabCatType.ConsoleWiiwareVC, "         WiiWare | Games");
-            AddCategoryMapping(147, TorznabCatType.ConsoleOther, "         GameCube | Games");
-            AddCategoryMapping(456, TorznabCatType.ConsoleOther, "      Sega");
-            AddCategoryMapping(588, TorznabCatType.ConsoleOther, "         Dreamcast");
-            AddCategoryMapping(457, TorznabCatType.ConsoleOther, "      Games for older consoles");
-            AddCategoryMapping(589, TorznabCatType.ConsoleOther, "      Games for the DVD player");
-            AddCategoryMapping(928, TorznabCatType.PCGames, "   Games for Linux");
-            AddCategoryMapping(1868, TorznabCatType.PCGames, "      Native games for Linux");
-            AddCategoryMapping(1869, TorznabCatType.PCGames, "      Ported games for Linux");
-            AddCategoryMapping(1870, TorznabCatType.PCGames, "      Archive for Linux games");
-            AddCategoryMapping(81, TorznabCatType.PC0day, "Software");
-            AddCategoryMapping(570, TorznabCatType.PC0day, "   General Section for software");
-            AddCategoryMapping(109, TorznabCatType.PCPhoneOther, "   Software for smart phones, mobile phones and PDAs");
-            AddCategoryMapping(899, TorznabCatType.PCPhoneOther, "      Java");
-            AddCategoryMapping(900, TorznabCatType.PCPhoneOther, "         Games for Java");
-            AddCategoryMapping(901, TorznabCatType.PCPhoneOther, "         Applications for Java");
-            AddCategoryMapping(590, TorznabCatType.PCPhoneAndroid, "      Android");
-            AddCategoryMapping(592, TorznabCatType.PCPhoneAndroid, "         Games for Android");
-            AddCategoryMapping(1017, TorznabCatType.PCPhoneAndroid, "            Games for Android [Eng]");
-            AddCategoryMapping(895, TorznabCatType.PCPhoneAndroid, "         Apps for Android OS");
-            AddCategoryMapping(1018, TorznabCatType.PCPhoneAndroid, "            Applications for Android [Eng]");
-            AddCategoryMapping(480, TorznabCatType.PCPhoneIOS, "      Apple Mobile Device Software");
-            AddCategoryMapping(481, TorznabCatType.PCPhoneIOS, "         Firmware (iPhone / iPod Touch / iPad / Apple TV)");
-            AddCategoryMapping(482, TorznabCatType.PCPhoneIOS, "         Programs for iOS (iPhone / iPod Touch / iPad)");
-            AddCategoryMapping(483, TorznabCatType.PCPhoneIOS, "         Games for iOS (iPhone / iPod Touch / iPad)");
-            AddCategoryMapping(485, TorznabCatType.PCPhoneIOS, "         Miscellaneous iOS (iPhone / iPod Touch / iPad)");
-            AddCategoryMapping(896, TorznabCatType.PCPhoneOther, "      Symbian");
-            AddCategoryMapping(897, TorznabCatType.PCPhoneOther, "         Games for Symbian");
-            AddCategoryMapping(898, TorznabCatType.PCPhoneOther, "         Applications for Symbian");
-            AddCategoryMapping(902, TorznabCatType.PCPhoneOther, "      Windows Mobile, Palm OS, BlackBerry etc");
-            AddCategoryMapping(903, TorznabCatType.PCPhoneOther, "         Games for Windows Mobile, Palm OS, BlackBerry etc");
-            AddCategoryMapping(904, TorznabCatType.PCPhoneOther, "         Applications for Windows Mobile, Palm OS, BlackBerry etc");
-            AddCategoryMapping(1579, TorznabCatType.PCPhoneOther, "      Windows Phone 7,8");
-            AddCategoryMapping(1580, TorznabCatType.PCPhoneOther, "         Games for Windows Phone 7,8");
-            AddCategoryMapping(1581, TorznabCatType.PCPhoneOther, "         Applications for Windows Phone 7,8");
-            AddCategoryMapping(1582, TorznabCatType.PCPhoneOther, "      Software for your phone");
-            AddCategoryMapping(1583, TorznabCatType.PCPhoneOther, "      Firmware for phones");
-            AddCategoryMapping(106, TorznabCatType.PC0day, "   On Linux, Unix etc");
-            AddCategoryMapping(282, TorznabCatType.PC0day, "      Operating Systems (Linux, Unix)");
-            AddCategoryMapping(1574, TorznabCatType.PC0day, "      Program (Linux, Unix)");
-            AddCategoryMapping(284, TorznabCatType.PC0day, "      Other operating systems and software for them");
-            AddCategoryMapping(287, TorznabCatType.PC0day, "      Archive (Linux OS, Unix etc)");
-            AddCategoryMapping(276, TorznabCatType.PCMac, "   Apple OS");
-            AddCategoryMapping(277, TorznabCatType.PCMac, "      Mac OS [for Macintosh]");
-            AddCategoryMapping(278, TorznabCatType.PCMac, "      Mac OS [PC-Hackintosh]");
-            AddCategoryMapping(591, TorznabCatType.PCMac, "      Games Mac OS");
-            AddCategoryMapping(1019, TorznabCatType.PCMac, "         Mac Games [ENG]");
-            AddCategoryMapping(1021, TorznabCatType.PCMac, "      Program for viewing and video processing (Mac OS)");
-            AddCategoryMapping(1022, TorznabCatType.PCMac, "      Programs for creating and processing graphs (Mac OS)");
-            AddCategoryMapping(1023, TorznabCatType.PCMac, "      Plug-ins for Adobe's software (Mac OS)");
-            AddCategoryMapping(1584, TorznabCatType.PCMac, "      Audio editor and converter (Mac OS)");
-            AddCategoryMapping(1585, TorznabCatType.PCMac, "      System software (Mac OS)");
-            AddCategoryMapping(1586, TorznabCatType.PCMac, "      Office software (Mac OS)");
-            AddCategoryMapping(1587, TorznabCatType.PCMac, "      Programs for the Internet and network (Mac OS)");
-            AddCategoryMapping(1588, TorznabCatType.PCMac, "      Other software (Mac OS)");
-            AddCategoryMapping(103, TorznabCatType.PC0day, "   Microsoft OS");
-            AddCategoryMapping(104, TorznabCatType.PC0day, "      Desktop operating system from Microsoft (released prior to Windows XP)");
-            AddCategoryMapping(105, TorznabCatType.PC0day, "      Desktop operating system from Microsoft (since Windows XP)");
-            AddCategoryMapping(1629, TorznabCatType.PC0day, "         Windows XP");
-            AddCategoryMapping(1628, TorznabCatType.PC0day, "         Windows Vista");
-            AddCategoryMapping(981, TorznabCatType.PC0day, "         Windows 7");
-            AddCategoryMapping(1610, TorznabCatType.PC0day, "         Windows 8");
-            AddCategoryMapping(1811, TorznabCatType.PC0day, "         Windows 10");
-            AddCategoryMapping(274, TorznabCatType.PC0day, "      Windows Server");
-            AddCategoryMapping(927, TorznabCatType.PC0day, "      Other (Operating Systems from Microsoft)");
-            AddCategoryMapping(275, TorznabCatType.PC0day, "      Archive (OS from Microsoft)");
-            AddCategoryMapping(84, TorznabCatType.PC0day, "   System programs");
-            AddCategoryMapping(86, TorznabCatType.PC0day, "      Programs for configuring and optimizing OS");
-            AddCategoryMapping(87, TorznabCatType.PC0day, "      Archivers and File Managers");
-            AddCategoryMapping(1630, TorznabCatType.PC0day, "      Safety protection system and PC");
-            AddCategoryMapping(93, TorznabCatType.PC0day, "         Software to protect your computer (antivirus software, firewalls)");
-            AddCategoryMapping(580, TorznabCatType.PC0day, "            Keys and Activation");
-            AddCategoryMapping(94, TorznabCatType.PC0day, "         Anti-spyware and anti-trojan");
-            AddCategoryMapping(95, TorznabCatType.PC0day, "         Programs for the protection of information");
-            AddCategoryMapping(88, TorznabCatType.PC0day, "      Backup");
-            AddCategoryMapping(89, TorznabCatType.PC0day, "      Service computer service");
-            AddCategoryMapping(1631, TorznabCatType.PC0day, "         LiveCD / DVD / Flash etc");
-            AddCategoryMapping(90, TorznabCatType.PC0day, "      Work with data carriers");
-            AddCategoryMapping(91, TorznabCatType.PC0day, "      Information and Diagnostics");
-            AddCategoryMapping(92, TorznabCatType.PC0day, "      Programs for Internet and networks");
-            AddCategoryMapping(96, TorznabCatType.PC0day, "      Drivers and Firmware");
-            AddCategoryMapping(97, TorznabCatType.PC0day, "      Original disks to computers and accessories");
-            AddCategoryMapping(98, TorznabCatType.PC0day, "      Server Software for Windows");
-            AddCategoryMapping(99, TorznabCatType.PC0day, "      Change the Windows interface");
-            AddCategoryMapping(101, TorznabCatType.PC0day, "      Screensavers");
-            AddCategoryMapping(85, TorznabCatType.PC0day, "      Work with hard drive");
-            AddCategoryMapping(102, TorznabCatType.PC0day, "      Miscellaneous (System programs on Windows)");
-            AddCategoryMapping(82, TorznabCatType.PC0day, "   Systems for business, office, research and project work");
-            AddCategoryMapping(83, TorznabCatType.PC0day, "      Business Systems");
-            AddCategoryMapping(585, TorznabCatType.PC0day, "         The company's products 1C");
-            AddCategoryMapping(1829, TorznabCatType.PC0day, "            typical configuration");
-            AddCategoryMapping(1830, TorznabCatType.PC0day, "            industry configuration");
-            AddCategoryMapping(1831, TorznabCatType.PC0day, "            ITS 2015");
-            AddCategoryMapping(1832, TorznabCatType.PC0day, "            ITS 2014");
-            AddCategoryMapping(1833, TorznabCatType.PC0day, "            ITS 2013");
-            AddCategoryMapping(1834, TorznabCatType.PC0day, "            ITS 2012");
-            AddCategoryMapping(1835, TorznabCatType.PC0day, "            ITS 2011");
-            AddCategoryMapping(1836, TorznabCatType.PC0day, "            Archive (Products 1C)");
-            AddCategoryMapping(270, TorznabCatType.PC0day, "      Office systems");
-            AddCategoryMapping(266, TorznabCatType.PC0day, "      Dictionaries, translators");
-            AddCategoryMapping(272, TorznabCatType.PC0day, "      Recognition of text, sound and speech synthesis");
-            AddCategoryMapping(269, TorznabCatType.PC0day, "      Miscellaneous (business systems, office, research and project work)");
-            AddCategoryMapping(302, TorznabCatType.PC0day, "      CAD software for architects");
-            AddCategoryMapping(593, TorznabCatType.PC0day, "         CAD (general and engineering)");
-            AddCategoryMapping(594, TorznabCatType.PC0day, "         CAD (electronics, automation, GAP)");
-            AddCategoryMapping(940, TorznabCatType.PC0day, "         Programs for architects and builders");
-            AddCategoryMapping(937, TorznabCatType.PC0day, "      All for house: dressmaking, sewing, cooking");
-            AddCategoryMapping(938, TorznabCatType.PC0day, "      Work with PDF and DjVu");
-            AddCategoryMapping(939, TorznabCatType.PC0day, "      Systems for scientific work");
-            AddCategoryMapping(941, TorznabCatType.PC0day, "      Libraries and projects for architects and interior designers");
-            AddCategoryMapping(942, TorznabCatType.PC0day, "      Other reference systems");
-            AddCategoryMapping(107, TorznabCatType.PC0day, "   Web Development and Programming");
-            AddCategoryMapping(293, TorznabCatType.PC0day, "      Search / Offer");
-            AddCategoryMapping(943, TorznabCatType.PC0day, "      WYSIWYG editors for web design");
-            AddCategoryMapping(496, TorznabCatType.PC0day, "      Database Management Systems (DBMS)");
-            AddCategoryMapping(494, TorznabCatType.PC0day, "      programming environments, compilers and software tools");
-            AddCategoryMapping(290, TorznabCatType.PC0day, "      The components for the development of media");
-            AddCategoryMapping(495, TorznabCatType.PC0day, "      Text editors Illuminated");
-            AddCategoryMapping(291, TorznabCatType.PC0day, "      Scripting engines and websites, CMS and extensions to it");
-            AddCategoryMapping(944, TorznabCatType.PC0day, "      Templates for websites and CMS");
-            AddCategoryMapping(292, TorznabCatType.PC0day, "      Miscellaneous (Web Development and Programming)");
-            AddCategoryMapping(294, TorznabCatType.PC0day, "      Archive (Web Development and Programming)");
-            AddCategoryMapping(108, TorznabCatType.PC0day, "   Programs to work with multimedia and 3D");
-            AddCategoryMapping(487, TorznabCatType.PC0day, "      Software kits");
-            AddCategoryMapping(488, TorznabCatType.PC0day, "      Plug-ins for Adobe's programs");
-            AddCategoryMapping(491, TorznabCatType.PC0day, "      3D modeling, rendering and plugins for them");
-            AddCategoryMapping(489, TorznabCatType.PC0day, "      Graphic editor");
-            AddCategoryMapping(303, TorznabCatType.PC0day, "      Editors video");
-            AddCategoryMapping(305, TorznabCatType.PC0day, "      Virtual Studios, sequencers and audio editor");
-            AddCategoryMapping(492, TorznabCatType.PC0day, "      Animation");
-            AddCategoryMapping(490, TorznabCatType.PC0day, "      Programs for typesetting, printing, and working with fonts");
-            AddCategoryMapping(304, TorznabCatType.PC0day, "      Video, Audio Conversion");
-            AddCategoryMapping(493, TorznabCatType.PC0day, "      Creating a BD / HD / DVD-Video");
-            AddCategoryMapping(306, TorznabCatType.PC0day, "      Plug-ins for sound processing");
-            AddCategoryMapping(308, TorznabCatType.PC0day, "      Archive (Programme for multimedia and 3D)");
-            AddCategoryMapping(595, TorznabCatType.PC0day, "      Miscellaneous (Programme for multimedia and 3D)");
-            AddCategoryMapping(596, TorznabCatType.PC0day, "      Miscellaneous (Programs for working with audio)");
-            AddCategoryMapping(597, TorznabCatType.PC0day, "      Virtual instruments and synthesizers");
-            AddCategoryMapping(264, TorznabCatType.PC0day, "      Audio and video, players and catalogers");
-            AddCategoryMapping(263, TorznabCatType.PC0day, "      Cataloging and graphics viewers");
-            AddCategoryMapping(348, TorznabCatType.PC0day, "   Materials for Multimedia and Design");
-            AddCategoryMapping(945, TorznabCatType.PC0day, "      Author's works");
-            AddCategoryMapping(946, TorznabCatType.PC0day, "      Official collection vector clipart");
-            AddCategoryMapping(948, TorznabCatType.PC0day, "      Other vector cliparts");
-            AddCategoryMapping(949, TorznabCatType.PC0day, "      Photostosks");
-            AddCategoryMapping(950, TorznabCatType.PC0day, "      The costumes for the photomontage");
-            AddCategoryMapping(350, TorznabCatType.PC0day, "      Frames and Vignettes for processing photos");
-            AddCategoryMapping(352, TorznabCatType.PC0day, "      Other raster clipart");
-            AddCategoryMapping(1634, TorznabCatType.PC0day, "         backgrounds");
-            AddCategoryMapping(1635, TorznabCatType.PC0day, "         Templates");
-            AddCategoryMapping(1637, TorznabCatType.PC0day, "         Raster Graphics (photos)");
-            AddCategoryMapping(1638, TorznabCatType.PC0day, "         Raster Graphics (elements)");
-            AddCategoryMapping(1639, TorznabCatType.PC0day, "         Raster Graphics (illustrations)");
-            AddCategoryMapping(353, TorznabCatType.PC0day, "      3D models, scenes and materials");
-            AddCategoryMapping(1633, TorznabCatType.PC0day, "         Textures");
-            AddCategoryMapping(354, TorznabCatType.PC0day, "      Footage");
-            AddCategoryMapping(951, TorznabCatType.PC0day, "      Other collections footage");
-            AddCategoryMapping(952, TorznabCatType.PC0day, "      music library");
-            AddCategoryMapping(355, TorznabCatType.PC0day, "      Sound effects");
-            AddCategoryMapping(953, TorznabCatType.PC0day, "      sample Libraries");
-            AddCategoryMapping(954, TorznabCatType.PC0day, "      Libraries and saundbanki for samplers, synth presets");
-            AddCategoryMapping(955, TorznabCatType.PC0day, "      Multitracks");
-            AddCategoryMapping(956, TorznabCatType.PC0day, "      Materials for creating menus and DVD covers");
-            AddCategoryMapping(351, TorznabCatType.PC0day, "      Styles, brushes, shapes and patterns for Adobe Photoshop");
-            AddCategoryMapping(356, TorznabCatType.PC0day, "      Fonts");
-            AddCategoryMapping(358, TorznabCatType.PC0day, "      Miscellaneous (Materials for Multimedia and Design)");
-            AddCategoryMapping(1632, TorznabCatType.PC0day, "      Digital Juice");
-            AddCategoryMapping(1874, TorznabCatType.PC0day, "      Projects");
-            AddCategoryMapping(1875, TorznabCatType.PC0day, "         Children (projects)");
-            AddCategoryMapping(1876, TorznabCatType.PC0day, "         Wedding and romantic (projects)");
-            AddCategoryMapping(1877, TorznabCatType.PC0day, "         Holiday (projects)");
-            AddCategoryMapping(1878, TorznabCatType.PC0day, "         Presentations (projects)");
-            AddCategoryMapping(1879, TorznabCatType.PC0day, "         Sport (projects)");
-            AddCategoryMapping(1880, TorznabCatType.PC0day, "         Logos (projects)");
-            AddCategoryMapping(1881, TorznabCatType.PC0day, "         Slideshow (projects)");
-            AddCategoryMapping(1882, TorznabCatType.PC0day, "         Titles (projects)");
-            AddCategoryMapping(1883, TorznabCatType.PC0day, "         Items (Projects)");
-            AddCategoryMapping(1884, TorznabCatType.PC0day, "         Miscellaneous (projects)");
-            AddCategoryMapping(1898, TorznabCatType.PC0day, "         Trailers (projects)");
-            AddCategoryMapping(295, TorznabCatType.PC0day, "   Reference and legal system");
-            AddCategoryMapping(296, TorznabCatType.PC0day, "      Consultant Plus");
-            AddCategoryMapping(584, TorznabCatType.PC0day, "         Consultant Accountant");
-            AddCategoryMapping(755, TorznabCatType.PC0day, "         Archive irrelevant hands");
-            AddCategoryMapping(297, TorznabCatType.PC0day, "      code");
-            AddCategoryMapping(298, TorznabCatType.PC0day, "      Guarantee");
-            AddCategoryMapping(299, TorznabCatType.PC0day, "      other");
-            AddCategoryMapping(300, TorznabCatType.PC0day, "      Archive (Reference and legal system)");
-            AddCategoryMapping(301, TorznabCatType.PC0day, "      RG PCA - a hidden forum");
-            AddCategoryMapping(587, TorznabCatType.PC0day, "   Collections of programs and WPI");
-            AddCategoryMapping(929, TorznabCatType.PC0day, "   Test drives to adjust the audio / video equipment");
-            AddCategoryMapping(957, TorznabCatType.PC0day, "   GIS, navigation systems and maps");
-            AddCategoryMapping(958, TorznabCatType.PC0day, "      GIS (Geographic Information Systems)");
-            AddCategoryMapping(959, TorznabCatType.PC0day, "      Maps provided with the program shell");
-            AddCategoryMapping(960, TorznabCatType.PC0day, "      Atlases and maps modern (after 1950)");
-            AddCategoryMapping(961, TorznabCatType.PC0day, "      Atlases and maps of old (pre-1950)");
-            AddCategoryMapping(962, TorznabCatType.PC0day, "      Cards Other (astronomical, historical, thematic)");
-            AddCategoryMapping(963, TorznabCatType.PC0day, "      Built-in car navigation");
-            AddCategoryMapping(964, TorznabCatType.PC0day, "      Garmin");
-            AddCategoryMapping(965, TorznabCatType.PC0day, "      Ozi");
-            AddCategoryMapping(966, TorznabCatType.PC0day, "      TomTom");
-            AddCategoryMapping(967, TorznabCatType.PC0day, "      Navigon / Navitel");
-            AddCategoryMapping(968, TorznabCatType.PC0day, "      Igo");
-            AddCategoryMapping(969, TorznabCatType.PC0day, "      Miscellaneous - navigation and maps");
-            AddCategoryMapping(61, TorznabCatType.Audio, "Music and music videos");
-            AddCategoryMapping(579, TorznabCatType.Audio, "   Total music section");
-            AddCategoryMapping(537, TorznabCatType.AudioVideo, "      General Discussion unsorted music video");
-            AddCategoryMapping(538, TorznabCatType.AudioVideo, "         Music video (HD / DVD)");
-            AddCategoryMapping(544, TorznabCatType.AudioVideo, "         Concert recording");
-            AddCategoryMapping(1781, TorznabCatType.AudioVideo, "            Concerts (DVD)");
-            AddCategoryMapping(1782, TorznabCatType.AudioVideo, "            Concerts (HD)");
-            AddCategoryMapping(1784, TorznabCatType.AudioVideo, "         Opera, Ballet, Musicals");
-            AddCategoryMapping(1785, TorznabCatType.AudioVideo, "         Music videos (transit)");
-            AddCategoryMapping(501, TorznabCatType.AudioLossless, "      unsorted Lossless");
-            AddCategoryMapping(532, TorznabCatType.Audio, "      Multi-channel HD Audio and Music");
-            AddCategoryMapping(533, TorznabCatType.Audio, "         DVD-Audio, SACD, Audio-DVD");
-            AddCategoryMapping(1687, TorznabCatType.Audio, "            DVD-Audio");
-            AddCategoryMapping(1688, TorznabCatType.Audio, "            SACD-R");
-            AddCategoryMapping(534, TorznabCatType.Audio, "         DTS");
-            AddCategoryMapping(535, TorznabCatType.Audio, "         Vinyl-Rip and Hand-Made");
-            AddCategoryMapping(536, TorznabCatType.Audio, "         Hi-Res stereo");
-            AddCategoryMapping(529, TorznabCatType.Audio, "      discography");
-            AddCategoryMapping(530, TorznabCatType.Audio, "         Domestic");
-            AddCategoryMapping(531, TorznabCatType.Audio, "         foreign");
-            AddCategoryMapping(1679, TorznabCatType.Audio, "      Jazz, Blues, Soul (transit)");
-            AddCategoryMapping(1680, TorznabCatType.Audio, "         Jazz (transit lossless)");
-            AddCategoryMapping(1681, TorznabCatType.Audio, "         Jazz (transit lossy)");
-            AddCategoryMapping(1682, TorznabCatType.Audio, "         Blues, Soul (transit lossless)");
-            AddCategoryMapping(1683, TorznabCatType.Audio, "         Blues, Soul (transit lossy)");
-            AddCategoryMapping(525, TorznabCatType.Audio, "         Jazz, Blues, Soul (transit lossless)");
-            AddCategoryMapping(1689, TorznabCatType.Audio, "      Rock, Alternative, Punk, Metal (transit)");
-            AddCategoryMapping(521, TorznabCatType.Audio, "         Rock (transit Lossless)");
-            AddCategoryMapping(1691, TorznabCatType.Audio, "         Rock (transit Lossy)");
-            AddCategoryMapping(1692, TorznabCatType.Audio, "         Alternative, Punk (transit Lossless)");
-            AddCategoryMapping(1693, TorznabCatType.Audio, "         Alternative, Punk (transit Lossy)");
-            AddCategoryMapping(1694, TorznabCatType.Audio, "         Hard Rock (transit Lossless)");
-            AddCategoryMapping(1695, TorznabCatType.Audio, "         Hard Rock (transit Lossy)");
-            AddCategoryMapping(506, TorznabCatType.Audio, "         Metal (transit Lossless)");
-            AddCategoryMapping(1697, TorznabCatType.Audio, "         Metal (transit Lossy)");
-            AddCategoryMapping(1698, TorznabCatType.Audio, "         Russian Rock (transit Lossless)");
-            AddCategoryMapping(1699, TorznabCatType.Audio, "         Russian Rock (transit Lossy)");
-            AddCategoryMapping(1817, TorznabCatType.Audio, "         Rock, Alternative, Punk, Metal (transit Lossless)");
-            AddCategoryMapping(1700, TorznabCatType.Audio, "      Popular music (transit)");
-            AddCategoryMapping(1701, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (transit Lossless)");
-            AddCategoryMapping(1702, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (transit Lossy)");
-            AddCategoryMapping(1703, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (transit Lossless)");
-            AddCategoryMapping(1704, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (transit Lossy)");
-            AddCategoryMapping(1705, TorznabCatType.Audio, "         Patriotic Pop (transit lossless)");
-            AddCategoryMapping(1706, TorznabCatType.Audio, "         Patriotic Pop (transit Lossy)");
-            AddCategoryMapping(1707, TorznabCatType.Audio, "         Soviet stage, Retro (transit Lossless)");
-            AddCategoryMapping(1708, TorznabCatType.Audio, "         Soviet stage, Retro (transit Lossy)");
-            AddCategoryMapping(1709, TorznabCatType.Audio, "         Foreign pop music (transit Lossless)");
-            AddCategoryMapping(1710, TorznabCatType.Audio, "         Foreign pop music (transit Lossy)");
-            AddCategoryMapping(1818, TorznabCatType.Audio, "         Popular music (transit Lossless)");
-            AddCategoryMapping(1711, TorznabCatType.Audio, "      Electronic music (transit)");
-            AddCategoryMapping(1712, TorznabCatType.Audio, "         Trance (transit Lossless)");
-            AddCategoryMapping(1713, TorznabCatType.Audio, "         Trance (transit Lossy)");
-            AddCategoryMapping(1714, TorznabCatType.Audio, "         House, Techno, Electro, Minimal (transit Lossless)");
-            AddCategoryMapping(1715, TorznabCatType.Audio, "         House (transit Lossy)");
-            AddCategoryMapping(1716, TorznabCatType.Audio, "         Techno, Electro, Minimal (transit Lossy)");
-            AddCategoryMapping(1717, TorznabCatType.Audio, "         Easy listening (transit Lossless)");
-            AddCategoryMapping(1718, TorznabCatType.Audio, "         Easy listening (transit Lossy)");
-            AddCategoryMapping(1719, TorznabCatType.Audio, "         Experimental, Industrial, EBM, Dark Electro (Lossless)");
-            AddCategoryMapping(1720, TorznabCatType.Audio, "         Experimental Electronic (transit Lossy)");
-            AddCategoryMapping(1721, TorznabCatType.Audio, "         Industrial, EBM, Dark Electro (transit Lossy)");
-            AddCategoryMapping(1722, TorznabCatType.Audio, "         Synthpop, New Wave (Lossless transit)");
-            AddCategoryMapping(1723, TorznabCatType.Audio, "         Synthpop, New Wave (transit Lossy)");
-            AddCategoryMapping(1724, TorznabCatType.Audio, "         Drum'n'Bass, Jungle, Breaks, Breakbeat, Dubstep (transit Lossless)");
-            AddCategoryMapping(1725, TorznabCatType.Audio, "         Drum'n'Bass, Jungle, Breaks, Breakbeat, Dubstep (transit Lossy)");
-            AddCategoryMapping(1726, TorznabCatType.Audio, "         Hardstyle, Jumpstyle, Hardcore (transit Lossless)");
-            AddCategoryMapping(1727, TorznabCatType.Audio, "         Hardstyle, Jumpstyle, Hardcore (transit Lossy)");
-            AddCategoryMapping(1728, TorznabCatType.Audio, "         Psychedelic, psytrance, fullon (transit Lossless)");
-            AddCategoryMapping(1729, TorznabCatType.Audio, "         Psychedelic, psytrance, fullon (transit Lossy)");
-            AddCategoryMapping(1730, TorznabCatType.Audio, "         Radioshow, Live Mixes (transit Lossy)");
-            AddCategoryMapping(1820, TorznabCatType.Audio, "         Electronic music (transit Lossless)");
-            AddCategoryMapping(1731, TorznabCatType.Audio, "      Rap, Hip-hop, RnB, Reggae (transit)");
-            AddCategoryMapping(1732, TorznabCatType.Audio, "         Rap, Hip-hop overseas (transit Lossless)");
-            AddCategoryMapping(1733, TorznabCatType.Audio, "         Rap, Hip-hop overseas (transit Lossy)");
-            AddCategoryMapping(1734, TorznabCatType.Audio, "         Rap, Hip-hop domestic (Lossless)");
-            AddCategoryMapping(1735, TorznabCatType.Audio, "         Rap, Hip-hop domestic (transit Lossy)");
-            AddCategoryMapping(1736, TorznabCatType.Audio, "         RnB, Reggae (transit Lossless)");
-            AddCategoryMapping(1737, TorznabCatType.Audio, "         RnB, Reggae (transit Lossy)");
-            AddCategoryMapping(1819, TorznabCatType.Audio, "         Rap, Hip-hop, RnB (transit Lossless)");
-            AddCategoryMapping(1738, TorznabCatType.Audio, "      East Asian Music (transit)");
-            AddCategoryMapping(1739, TorznabCatType.Audio, "         Asian Traditional, Ethnic (transit Lossless)");
-            AddCategoryMapping(1740, TorznabCatType.Audio, "         Asian Traditional, Ethnic (transit Lossy)");
-            AddCategoryMapping(1741, TorznabCatType.Audio, "         Asian Pop (transit Lossless)");
-            AddCategoryMapping(1742, TorznabCatType.Audio, "         Asian Pop (transit Lossy)");
-            AddCategoryMapping(1743, TorznabCatType.Audio, "         Asian Rock, Metal (transit Lossless)");
-            AddCategoryMapping(1744, TorznabCatType.Audio, "         Asian Rock, Metal (transit Lossy)");
-            AddCategoryMapping(1745, TorznabCatType.Audio, "         Doujin Music (transit Lossless)");
-            AddCategoryMapping(1746, TorznabCatType.Audio, "         Doujin Music (transit Lossy)");
-            AddCategoryMapping(1747, TorznabCatType.Audio, "         Other Asian (transit Lossless)");
-            AddCategoryMapping(1748, TorznabCatType.Audio, "         Other Asian (transit Lossy)");
-            AddCategoryMapping(1749, TorznabCatType.Audio, "      Other Styles (transit)");
-            AddCategoryMapping(1750, TorznabCatType.Audio, "         Instrumental (transit Lossless)");
-            AddCategoryMapping(1751, TorznabCatType.Audio, "         Instrumental (transit Lossy)");
-            AddCategoryMapping(1752, TorznabCatType.Audio, "         New Age / Meditative / Relax (transit Lossless)");
-            AddCategoryMapping(1753, TorznabCatType.Audio, "         New Age / Meditative / Relax (transit Lossy)");
-            AddCategoryMapping(1754, TorznabCatType.Audio, "         Classical Crossover / Neoclassical (transit Lossless)");
-            AddCategoryMapping(1755, TorznabCatType.Audio, "         Classical Crossover / Neoclassical (transit Lossy)");
-            AddCategoryMapping(1756, TorznabCatType.Audio, "         Folk (transit Lossless)");
-            AddCategoryMapping(1757, TorznabCatType.Audio, "         Folk (transit Lossy)");
-            AddCategoryMapping(1758, TorznabCatType.Audio, "         Other (transit Lossless)");
-            AddCategoryMapping(1759, TorznabCatType.Audio, "         Other (transit Lossy)");
-            AddCategoryMapping(1821, TorznabCatType.Audio, "            Folklore / Folk / Folk / World Music (transit Lossy)");
-            AddCategoryMapping(1822, TorznabCatType.Audio, "            Compilations Folklore / Folk / Folk / World Music (transit Lossy)");
-            AddCategoryMapping(1823, TorznabCatType.Audio, "            Country &amp; Folk (transit Lossy)");
-            AddCategoryMapping(1760, TorznabCatType.Audio, "         OST (transit Lossless)");
-            AddCategoryMapping(1761, TorznabCatType.Audio, "         OST (transit Lossy)");
-            AddCategoryMapping(1762, TorznabCatType.Audio, "      Classic (transit)");
-            AddCategoryMapping(1763, TorznabCatType.Audio, "         Notes (transit)");
-            AddCategoryMapping(1764, TorznabCatType.Audio, "         Complete Works (transit)");
-            AddCategoryMapping(1765, TorznabCatType.Audio, "         Vocals (transit)");
-            AddCategoryMapping(1766, TorznabCatType.Audio, "         Concerts (transit)");
-            AddCategoryMapping(1767, TorznabCatType.Audio, "         Orchestral (transit)");
-            AddCategoryMapping(1768, TorznabCatType.Audio, "         Chamber (transit)");
-            AddCategoryMapping(1769, TorznabCatType.Audio, "         Piano (transit)");
-            AddCategoryMapping(1770, TorznabCatType.Audio, "         Compilations (transit)");
-            AddCategoryMapping(1771, TorznabCatType.Audio, "         In processing (transit)");
-            AddCategoryMapping(1783, TorznabCatType.Audio, "         Classic (transit Lossless)");
-            AddCategoryMapping(1800, TorznabCatType.Audio, "      Author and military songs");
-            AddCategoryMapping(1798, TorznabCatType.Audio, "         Author and war songs (transit Lossless)");
-            AddCategoryMapping(1799, TorznabCatType.Audio, "         Author and war songs (transit Lossy)");
-            AddCategoryMapping(1772, TorznabCatType.Audio, "      Unofficial collections (transit)");
-            AddCategoryMapping(1773, TorznabCatType.Audio, "         Jazz, Blues, Soul (transit collections)");
-            AddCategoryMapping(1774, TorznabCatType.Audio, "         Chanson, Author and war songs (collections transit)");
-            AddCategoryMapping(1775, TorznabCatType.Audio, "         Rock, Alternative, Punk, Metal (collections of transit)");
-            AddCategoryMapping(1776, TorznabCatType.Audio, "         Pop (transit collections)");
-            AddCategoryMapping(1777, TorznabCatType.Audio, "         Electronic (transit collections)");
-            AddCategoryMapping(1778, TorznabCatType.Audio, "         Rap, Hip-hop, RnB, Reggae (transit collections)");
-            AddCategoryMapping(1779, TorznabCatType.Audio, "         Instrumental / New Age / Meditative / Relax (transit collections)");
-            AddCategoryMapping(1780, TorznabCatType.Audio, "         Other (transit collections)");
-            AddCategoryMapping(1816, TorznabCatType.Audio, "      Chanson, Author and war songs (transit)");
-            AddCategoryMapping(1677, TorznabCatType.Audio, "         Chanson, Author and war songs (transit lossless)");
-            AddCategoryMapping(1678, TorznabCatType.Audio, "         Chanson, Author and war songs (transit lossy)");
-            AddCategoryMapping(63, TorznabCatType.Audio, "   Electonic music");
-            AddCategoryMapping(784, TorznabCatType.Audio, "      Chillout, Lounge, Downtempo, Trip-Hop");
-            AddCategoryMapping(785, TorznabCatType.Audio, "         Chillout, Lounge, Downtempo (lossless)");
-            AddCategoryMapping(225, TorznabCatType.Audio, "         Chillout, Lounge, Downtempo (lossy)");
-            AddCategoryMapping(786, TorznabCatType.Audio, "         Nu Jazz, Acid Jazz, Future Jazz (lossless)");
-            AddCategoryMapping(787, TorznabCatType.Audio, "         Nu Jazz, Acid Jazz, Future Jazz (lossy)");
-            AddCategoryMapping(788, TorznabCatType.Audio, "         Trip Hop, Abstract Hip-Hop (lossless)");
-            AddCategoryMapping(789, TorznabCatType.Audio, "         Trip Hop, Abstract Hip-Hop (lossy)");
-            AddCategoryMapping(800, TorznabCatType.Audio, "      Drum &amp; Bass, Jungle, Breakbeat, Dubstep, IDM, Electro");
-            AddCategoryMapping(801, TorznabCatType.Audio, "         Dubstep (lossy)");
-            AddCategoryMapping(224, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (lossy)");
-            AddCategoryMapping(803, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (lossless)");
-            AddCategoryMapping(804, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (Radioshows, Podcasts, Livesets, Mixes)");
-            AddCategoryMapping(805, TorznabCatType.Audio, "         Breakbeat (lossless)");
-            AddCategoryMapping(806, TorznabCatType.Audio, "         Breakbeat (lossy)");
-            AddCategoryMapping(1517, TorznabCatType.Audio, "         Electro, Electro-Freestyle, Nu Electro (lossless)");
-            AddCategoryMapping(1518, TorznabCatType.Audio, "         Electro, Electro-Freestyle, Nu Electro (lossy)");
-            AddCategoryMapping(1519, TorznabCatType.Audio, "         Dubstep (lossless)");
-            AddCategoryMapping(1520, TorznabCatType.Audio, "         Breakbeat, Dubstep (Radioshows, Podcasts, Livesets, Mixes)");
-            AddCategoryMapping(1521, TorznabCatType.Audio, "         IDM (lossless)");
-            AddCategoryMapping(1522, TorznabCatType.Audio, "         IDM (lossy)");
-            AddCategoryMapping(1523, TorznabCatType.Audio, "         IDM Discography &amp; Collections (lossy)");
-            AddCategoryMapping(227, TorznabCatType.Audio, "      Industrial, Noise, EBM, Dark Electro, Aggrotech, Synthpop, New Wave");
-            AddCategoryMapping(774, TorznabCatType.Audio, "         EBM, Dark Electro, Aggrotech (lossless)");
-            AddCategoryMapping(775, TorznabCatType.Audio, "         EBM, Dark Electro, Aggrotech (lossy)");
-            AddCategoryMapping(776, TorznabCatType.Audio, "         Industrial, Noise (lossless)");
-            AddCategoryMapping(777, TorznabCatType.Audio, "         Industrial, Noise (lossy)");
-            AddCategoryMapping(778, TorznabCatType.Audio, "         Synthpop, New Wave (lossless)");
-            AddCategoryMapping(779, TorznabCatType.Audio, "         Synthpop, New Wave (lossy)");
-            AddCategoryMapping(780, TorznabCatType.Audio, "         Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossless)");
-            AddCategoryMapping(781, TorznabCatType.Audio, "         Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossy)");
-            AddCategoryMapping(752, TorznabCatType.Audio, "      House, Techno, Hardcore, Hardstyle, Jumpstyle");
-            AddCategoryMapping(760, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (lossy)");
-            AddCategoryMapping(759, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (lossless)");
-            AddCategoryMapping(753, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (vinyl, web)");
-            AddCategoryMapping(223, TorznabCatType.Audio, "         House (lossy)");
-            AddCategoryMapping(756, TorznabCatType.Audio, "         House (lossless)");
-            AddCategoryMapping(770, TorznabCatType.Audio, "         House (Radioshow, Podcast, Liveset, Mixes)");
-            AddCategoryMapping(754, TorznabCatType.Audio, "         House (Singles, EPs) (lossy)");
-            AddCategoryMapping(771, TorznabCatType.Audio, "         House (Promorelizy, collections)");
-            AddCategoryMapping(757, TorznabCatType.Audio, "         Techno (lossy)");
-            AddCategoryMapping(758, TorznabCatType.Audio, "         Techno (lossless)");
-            AddCategoryMapping(769, TorznabCatType.Audio, "         Techno (Radioshows, Podcasts, Livesets, Mixes)");
-            AddCategoryMapping(761, TorznabCatType.Audio, "         Techno (Singles, EPs) (lossy)");
-            AddCategoryMapping(790, TorznabCatType.Audio, "      Trance, Goa Trance, Psy-Trance, PsyChill, Ambient Dub");
-            AddCategoryMapping(792, TorznabCatType.Audio, "         Goa Trance, Psy-Trance (lossless)");
-            AddCategoryMapping(793, TorznabCatType.Audio, "         Goa Trance, Psy-Trance (lossy)");
-            AddCategoryMapping(798, TorznabCatType.Audio, "         Goa / Psy-Trance, PsyChill and Ambient Dub (Radioshows, Livesets, Mixes) (lossy)");
-            AddCategoryMapping(791, TorznabCatType.Audio, "         Trance (lossless)");
-            AddCategoryMapping(222, TorznabCatType.Audio, "         Trance (lossy)");
-            AddCategoryMapping(795, TorznabCatType.Audio, "         Trance (Radioshows, Podcasts, Live Sets, Mixes) (lossy)");
-            AddCategoryMapping(794, TorznabCatType.Audio, "         Trance (Singles, EPs) (lossy)");
-            AddCategoryMapping(796, TorznabCatType.Audio, "         PsyChill, Ambient Dub (lossless)");
-            AddCategoryMapping(797, TorznabCatType.Audio, "         PsyChill, Ambient Dub (lossy)");
-            AddCategoryMapping(762, TorznabCatType.Audio, "      Traditional Electronic, Ambient, Modern Classical, Electroacoustic, Experimental");
-            AddCategoryMapping(768, TorznabCatType.Audio, "         8-bit, Chiptune (lossy &amp; lossless)");
-            AddCategoryMapping(679, TorznabCatType.Audio, "         Experimental (lossy)");
-            AddCategoryMapping(764, TorznabCatType.Audio, "         Experimental (lossless)");
-            AddCategoryMapping(767, TorznabCatType.Audio, "         Modern Classical, Electroacoustic (lossy)");
-            AddCategoryMapping(766, TorznabCatType.Audio, "         Modern Classical, Electroacoustic (lossless)");
-            AddCategoryMapping(226, TorznabCatType.Audio, "         Traditional Electronic, Ambient (lossy)");
-            AddCategoryMapping(763, TorznabCatType.Audio, "         Traditional Electronic, Ambient (lossless)");
-            AddCategoryMapping(799, TorznabCatType.Audio, "      Label Packs (lossless)");
-            AddCategoryMapping(802, TorznabCatType.Audio, "      Label packs, Scene packs (lossy)");
-            AddCategoryMapping(782, TorznabCatType.Audio, "      Electronic music (Video, DVD Video / Audio, HD Video, DTS, SACD)");
-            AddCategoryMapping(783, TorznabCatType.Audio, "         Electronic music (own digitization)");
-            AddCategoryMapping(914, TorznabCatType.Audio, "         Electronic music (Video)");
-            AddCategoryMapping(1524, TorznabCatType.Audio, "         Electronic music (Official DVD Video)");
-            AddCategoryMapping(1525, TorznabCatType.Audio, "         Electronic music (Informal amateur DVD Video)");
-            AddCategoryMapping(1526, TorznabCatType.Audio, "         Electronic Music (Hi-Res stereo)");
-            AddCategoryMapping(1527, TorznabCatType.Audio, "         Multichannel music (Electronics)");
-            AddCategoryMapping(1528, TorznabCatType.Audio, "         Electronic music (HD Video)");
-            AddCategoryMapping(64, TorznabCatType.Audio, "   Rap, Hip-Hop, R'n'B");
-            AddCategoryMapping(213, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (lossy)");
-            AddCategoryMapping(214, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop (lossy)");
-            AddCategoryMapping(692, TorznabCatType.Audio, "      Foreign R'n'B (lossy)");
-            AddCategoryMapping(894, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (lossless)");
-            AddCategoryMapping(1387, TorznabCatType.Audio, "      Minus (Instrumentals)");
-            AddCategoryMapping(1388, TorznabCatType.Audio, "      Domestic R'n'B (lossy)");
-            AddCategoryMapping(1389, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop, R'n'B (lossless)");
-            AddCategoryMapping(1390, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop (Video)");
-            AddCategoryMapping(1391, TorznabCatType.Audio, "      Domestic R'n'B (Video)");
-            AddCategoryMapping(1392, TorznabCatType.Audio, "      Foreign R'n'B (lossless)");
-            AddCategoryMapping(1393, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (own digitization)");
-            AddCategoryMapping(1394, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (Video)");
-            AddCategoryMapping(1395, TorznabCatType.Audio, "      Foreign R'n'B (Video)");
-            AddCategoryMapping(1396, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (DVD Video)");
-            AddCategoryMapping(1397, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (HD Video)");
-            AddCategoryMapping(65, TorznabCatType.Audio, "   Pop music");
-            AddCategoryMapping(196, TorznabCatType.Audio, "      International Pop Music");
-            AddCategoryMapping(689, TorznabCatType.Audio, "         Foreign pop music (lossy)");
-            AddCategoryMapping(712, TorznabCatType.Audio, "         Foreign pop music (lossless)");
-            AddCategoryMapping(1429, TorznabCatType.Audio, "         Foreign pop music (collections) (lossy)");
-            AddCategoryMapping(711, TorznabCatType.Audio, "         East Asian pop music (lossy)");
-            AddCategoryMapping(1432, TorznabCatType.Audio, "         East Asian pop music (lossless)");
-            AddCategoryMapping(879, TorznabCatType.Audio, "      Domestic Pop");
-            AddCategoryMapping(197, TorznabCatType.Audio, "         Patriotic Pop (lossy)");
-            AddCategoryMapping(1425, TorznabCatType.Audio, "         Patriotic Pop (lossless)");
-            AddCategoryMapping(1426, TorznabCatType.Audio, "         Patriotic Pop music (collections) (lossy)");
-            AddCategoryMapping(1427, TorznabCatType.Audio, "         Soviet stage, Retro (lossy)");
-            AddCategoryMapping(1428, TorznabCatType.Audio, "         Soviet stage, Retro (lossless)");
-            AddCategoryMapping(198, TorznabCatType.Audio, "      Eurodance, Disco, Hi-NRG");
-            AddCategoryMapping(703, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (lossy)");
-            AddCategoryMapping(877, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (lossless)");
-            AddCategoryMapping(199, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (collections) (lossy)");
-            AddCategoryMapping(704, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossy)");
-            AddCategoryMapping(878, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossless)");
-            AddCategoryMapping(1433, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (collections) (lossy)");
-            AddCategoryMapping(1434, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Pop)");
-            AddCategoryMapping(1435, TorznabCatType.Audio, "         Patriotic Pop (Video)");
-            AddCategoryMapping(1436, TorznabCatType.Audio, "         Patriotic Pop (DVD Video)");
-            AddCategoryMapping(1437, TorznabCatType.Audio, "         Soviet stage, Retro (video)");
-            AddCategoryMapping(1438, TorznabCatType.Audio, "         Soviet stage, Retro (DVD Video)");
-            AddCategoryMapping(1439, TorznabCatType.Audio, "         Foreign pop music (Video)");
-            AddCategoryMapping(1440, TorznabCatType.Audio, "         Foreign pop music (DVD Video)");
-            AddCategoryMapping(1441, TorznabCatType.Audio, "         Eurodance, Disco (video)");
-            AddCategoryMapping(1442, TorznabCatType.Audio, "         Eurodance, Disco (DVD Video)");
-            AddCategoryMapping(1443, TorznabCatType.Audio, "         East Asian pop music (Video)");
-            AddCategoryMapping(1444, TorznabCatType.Audio, "         East Asian pop music (DVD Video)");
-            AddCategoryMapping(1447, TorznabCatType.Audio, "         Patriotic Pop (National concerts, Doc. Video) (Video and DVD)");
-            AddCategoryMapping(1448, TorznabCatType.Audio, "         Foreign pop music (National concerts, Doc. Video) (Video and DVD)");
-            AddCategoryMapping(1449, TorznabCatType.Audio, "         International Pop Music, Chanson, Eurodance, Disco (HD Video)");
-            AddCategoryMapping(1450, TorznabCatType.Audio, "         Patriotic Pop Music, Chanson, Eurodance, Disco (HD Video)");
-            AddCategoryMapping(1451, TorznabCatType.Audio, "      The multi-channel music and own digitization (pop music)");
-            AddCategoryMapping(1452, TorznabCatType.Audio, "         Foreign pop music (own digitization)");
-            AddCategoryMapping(1453, TorznabCatType.Audio, "         Eastern pop music (own digitization)");
-            AddCategoryMapping(1454, TorznabCatType.Audio, "         Patriotic Pop (own digitization)");
-            AddCategoryMapping(1455, TorznabCatType.Audio, "         Instrumental Pop (own digitization)");
-            AddCategoryMapping(1456, TorznabCatType.Audio, "         Multichannel music (pop music)");
-            AddCategoryMapping(1457, TorznabCatType.Audio, "         Foreign pop music (Hi-Res stereo)");
-            AddCategoryMapping(66, TorznabCatType.Audio, "   Soundtracks, Karaoke and Minus");
-            AddCategoryMapping(917, TorznabCatType.Audio, "      The arrangements of music from the game (lossy and lossless)");
-            AddCategoryMapping(1400, TorznabCatType.Audio, "      Minus (lossy and lossless)");
-            AddCategoryMapping(1824, TorznabCatType.Audio, "      Soundtracks");
-            AddCategoryMapping(232, TorznabCatType.Audio, "         Soundtracks to movies and cartoons (mp3)");
-            AddCategoryMapping(234, TorznabCatType.Audio, "         Soundtracks for games (lossy)");
-            AddCategoryMapping(693, TorznabCatType.Audio, "         Soundtracks to foreign films (lossy)");
-            AddCategoryMapping(880, TorznabCatType.Audio, "         Soundtracks to foreign films (lossless)");
-            AddCategoryMapping(915, TorznabCatType.Audio, "         Soundtracks for games (lossless)");
-            AddCategoryMapping(916, TorznabCatType.Audio, "         Informal soundtracks for games (lossy)");
-            AddCategoryMapping(918, TorznabCatType.Audio, "         Informal soundtracks for films and TV series (lossy)");
-            AddCategoryMapping(919, TorznabCatType.Audio, "         Soundtracks for domestic films (lossy)");
-            AddCategoryMapping(920, TorznabCatType.Audio, "         Soundtracks for domestic films (lossless)");
-            AddCategoryMapping(921, TorznabCatType.Audio, "         Soundtracks (own digitization)");
-            AddCategoryMapping(1825, TorznabCatType.Audio, "      Karaoke");
-            AddCategoryMapping(1398, TorznabCatType.Audio, "         Karaoke (Audio)");
-            AddCategoryMapping(1399, TorznabCatType.Audio, "         Karaoke (Video)");
-            AddCategoryMapping(67, TorznabCatType.Audio, "   Music of other genres");
-            AddCategoryMapping(694, TorznabCatType.Audio, "      Proper sampling (music of other genres)");
-            AddCategoryMapping(695, TorznabCatType.Audio, "      Patriotic music of other genres (lossy)");
-            AddCategoryMapping(696, TorznabCatType.Audio, "      Patriotic music of other genres (lossless)");
-            AddCategoryMapping(697, TorznabCatType.Audio, "      Foreign music of other genres (lossy)");
-            AddCategoryMapping(1408, TorznabCatType.Audio, "      Foreign music of other genres (lossless)");
-            AddCategoryMapping(1409, TorznabCatType.Audio, "      Music for ballroom dancing (lossy and lossless)");
-            AddCategoryMapping(1410, TorznabCatType.Audio, "      Orthodox chants (lossy)");
-            AddCategoryMapping(1411, TorznabCatType.Audio, "      Orthodox chants (lossless)");
-            AddCategoryMapping(1412, TorznabCatType.Audio, "      A collection of songs for children (lossy and lossless)");
-            AddCategoryMapping(1686, TorznabCatType.Audio, "         Classics for mothers and babies");
-            AddCategoryMapping(1413, TorznabCatType.Audio, "      Video (Music from other genres)");
-            AddCategoryMapping(1414, TorznabCatType.Audio, "      DVD Video (Music from other genres)");
-            AddCategoryMapping(1415, TorznabCatType.Audio, "      Musical (lossy and lossless)");
-            AddCategoryMapping(1416, TorznabCatType.Audio, "      Musical (Video and DVD Video)");
-            AddCategoryMapping(1417, TorznabCatType.Audio, "      Informal and vnezhanrovye collections (lossy)");
-            AddCategoryMapping(172, TorznabCatType.Audio, "   Classical and contemporary academic music");
-            AddCategoryMapping(705, TorznabCatType.Audio, "      Vocal music (lossless)");
-            AddCategoryMapping(706, TorznabCatType.Audio, "      Orchestral music (lossless)");
-            AddCategoryMapping(707, TorznabCatType.Audio, "      Concerto for instrument and orchestra (lossless)");
-            AddCategoryMapping(708, TorznabCatType.Audio, "      Chamber instrumental music (lossless)");
-            AddCategoryMapping(709, TorznabCatType.Audio, "      Solo instrumental music (lossless)");
-            AddCategoryMapping(710, TorznabCatType.Audio, "      Vocal and choral music (lossy)");
-            AddCategoryMapping(1001, TorznabCatType.Audio, "      Proper digitization (Classical Music)");
-            AddCategoryMapping(1002, TorznabCatType.Audio, "      Multichannel music (Classic and classic with a modern twist)");
-            AddCategoryMapping(1003, TorznabCatType.Audio, "      Classic and classic in modern processing (Hi-Res stereo)");
-            AddCategoryMapping(1008, TorznabCatType.Audio, "      Classical Music (Video)");
-            AddCategoryMapping(1009, TorznabCatType.Audio, "      Classical Music (DVD and HD Video)");
-            AddCategoryMapping(1362, TorznabCatType.Audio, "      Opera (Video)");
-            AddCategoryMapping(1363, TorznabCatType.Audio, "      Opera (DVD and HD Video)");
-            AddCategoryMapping(1364, TorznabCatType.Audio, "      Ballet and modern choreography (Video, DVD and HD Video)");
-            AddCategoryMapping(1365, TorznabCatType.Audio, "      The complete collection of works and multi-disc edition (lossless)");
-            AddCategoryMapping(1366, TorznabCatType.Audio, "      Opera (lossless)");
-            AddCategoryMapping(1367, TorznabCatType.Audio, "      Choral music (lossless)");
-            AddCategoryMapping(1368, TorznabCatType.Audio, "      The complete collection of works and multi-disc edition (lossy)");
-            AddCategoryMapping(1369, TorznabCatType.Audio, "      Orchestral music (lossy)");
-            AddCategoryMapping(1370, TorznabCatType.Audio, "      Chamber and solo instrumental music (lossy)");
-            AddCategoryMapping(1371, TorznabCatType.Audio, "      Classics in modern processing, Classical Crossover (lossy and lossless)");
-            AddCategoryMapping(175, TorznabCatType.Audio, "   Jazz, Blues");
-            AddCategoryMapping(178, TorznabCatType.Audio, "      foreign Jazz");
-            AddCategoryMapping(747, TorznabCatType.Audio, "         Avant-Garde Jazz, Free Improvisation (lossless)");
-            AddCategoryMapping(741, TorznabCatType.Audio, "         Bop (lossless)");
-            AddCategoryMapping(842, TorznabCatType.Audio, "         Early Jazz, Swing, Gypsy (lossless)");
-            AddCategoryMapping(847, TorznabCatType.Audio, "         Funk, Soul, R &amp; B (lossless)");
-            AddCategoryMapping(843, TorznabCatType.Audio, "         Jazz Fusion (lossless)");
-            AddCategoryMapping(599, TorznabCatType.Audio, "         Mainstream Jazz, Cool (lossless)");
-            AddCategoryMapping(845, TorznabCatType.Audio, "         Modern Creative, Third Stream (lossless)");
-            AddCategoryMapping(846, TorznabCatType.Audio, "         Smooth, Jazz-Pop (lossless)");
-            AddCategoryMapping(620, TorznabCatType.Audio, "         Vocal Jazz (lossless)");
-            AddCategoryMapping(844, TorznabCatType.Audio, "         World Fusion, Ethnic Jazz (lossless)");
-            AddCategoryMapping(673, TorznabCatType.Audio, "         Foreign jazz (lossy)");
-            AddCategoryMapping(848, TorznabCatType.Audio, "         Collections of foreign jazz (lossless)");
-            AddCategoryMapping(690, TorznabCatType.Audio, "      foreign blues");
-            AddCategoryMapping(839, TorznabCatType.Audio, "         Blues-rock (lossless)");
-            AddCategoryMapping(713, TorznabCatType.Audio, "         Blues (Texas, Chicago, Modern and Others) (lossless)");
-            AddCategoryMapping(840, TorznabCatType.Audio, "         Roots, Pre-War Blues, Early R &amp; B, Gospel (lossless)");
-            AddCategoryMapping(691, TorznabCatType.Audio, "         Foreign blues (lossy)");
-            AddCategoryMapping(841, TorznabCatType.Audio, "         Foreign blues (collections; Tribute VA) (lossless)");
-            AddCategoryMapping(849, TorznabCatType.Audio, "      Domestic jazz and blues");
-            AddCategoryMapping(850, TorznabCatType.Audio, "         Domestic Jazz (lossless)");
-            AddCategoryMapping(851, TorznabCatType.Audio, "         Domestic jazz (lossy)");
-            AddCategoryMapping(853, TorznabCatType.Audio, "         Domestic Blues (lossless)");
-            AddCategoryMapping(854, TorznabCatType.Audio, "         Domestic Blues (lossy)");
-            AddCategoryMapping(1013, TorznabCatType.Audio, "      The multi-channel music and own digitization (Jazz and Blues)");
-            AddCategoryMapping(1014, TorznabCatType.Audio, "         Multichannel music (Jazz and Blues)");
-            AddCategoryMapping(1015, TorznabCatType.Audio, "         Foreign Jazz and Blues (Hi-Res stereo)");
-            AddCategoryMapping(1016, TorznabCatType.Audio, "         Proper digitization (Jazz and Blues)");
-            AddCategoryMapping(1458, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Jazz and Blues)");
-            AddCategoryMapping(1459, TorznabCatType.Audio, "         Jazz and Blues (Video)");
-            AddCategoryMapping(1460, TorznabCatType.Audio, "         Jazz and Blues (DVD Video)");
-            AddCategoryMapping(1461, TorznabCatType.Audio, "         Jazz and Blues (HD Video)");
-            AddCategoryMapping(204, TorznabCatType.Audio, "   New Age, Relax, Meditative &amp; Flamenco");
-            AddCategoryMapping(207, TorznabCatType.Audio, "      NewAge &amp; Meditative (lossy)");
-            AddCategoryMapping(1004, TorznabCatType.Audio, "      NewAge &amp; Meditative (lossless)");
-            AddCategoryMapping(1005, TorznabCatType.Audio, "      Flamenco and acoustic guitar (lossy)");
-            AddCategoryMapping(1006, TorznabCatType.Audio, "      Flamenco and acoustic guitar (lossless)");
-            AddCategoryMapping(1385, TorznabCatType.Audio, "      New Age, Relax, Meditative &amp; Flamenco (Video)");
-            AddCategoryMapping(1386, TorznabCatType.Audio, "      New Age, Relax, Meditative &amp; Flamenco (DVD and HD Video)");
-            AddCategoryMapping(1007, TorznabCatType.Audio, "      Sounds of nature");
-            AddCategoryMapping(701, TorznabCatType.Audio, "   Chanson, Author and military songs");
-            AddCategoryMapping(702, TorznabCatType.Audio, "      Domestic chanson (lossy)");
-            AddCategoryMapping(891, TorznabCatType.Audio, "      Domestic chanson (lossless)");
-            AddCategoryMapping(892, TorznabCatType.Audio, "      Military song (lossy)");
-            AddCategoryMapping(893, TorznabCatType.Audio, "      Chanson (lossy)");
-            AddCategoryMapping(1401, TorznabCatType.Audio, "      Collections domestic chanson (lossy)");
-            AddCategoryMapping(1402, TorznabCatType.Audio, "      Military song (lossless)");
-            AddCategoryMapping(1403, TorznabCatType.Audio, "      Chanson (lossless)");
-            AddCategoryMapping(1404, TorznabCatType.Audio, "      Minstrels and roleviki (lossy and lossless)");
-            AddCategoryMapping(1405, TorznabCatType.Audio, "      Proper digitization (Chanson, and Bards) lossless");
-            AddCategoryMapping(1406, TorznabCatType.Audio, "      Videos (Chanson, and Bards)");
-            AddCategoryMapping(1407, TorznabCatType.Audio, "      DVD Video (Chanson, and Bards)");
-            AddCategoryMapping(1430, TorznabCatType.Audio, "      Foreign chanson (lossy)");
-            AddCategoryMapping(1431, TorznabCatType.Audio, "      Foreign chanson (lossless)");
-            AddCategoryMapping(1445, TorznabCatType.Audio, "      Foreign chanson (Video)");
-            AddCategoryMapping(1446, TorznabCatType.Audio, "      Foreign chanson (DVD Video)");
-            AddCategoryMapping(865, TorznabCatType.Audio, "   Rock music");
-            AddCategoryMapping(62, TorznabCatType.Audio, "      foreign Rock");
-            AddCategoryMapping(859, TorznabCatType.Audio, "         AOR (Melodic Hard Rock, Arena rock) (lossless)");
-            AddCategoryMapping(860, TorznabCatType.Audio, "         AOR (Melodic Hard Rock, Arena rock) (lossy)");
-            AddCategoryMapping(855, TorznabCatType.Audio, "         Classic Rock &amp; Hard Rock (lossless)");
-            AddCategoryMapping(856, TorznabCatType.Audio, "         Classic Rock &amp; Hard Rock (lossy)");
-            AddCategoryMapping(864, TorznabCatType.Audio, "         Instrumental Guitar Rock (lossy)");
-            AddCategoryMapping(1027, TorznabCatType.Audio, "         Instrumental Guitar Rock (lossless)");
-            AddCategoryMapping(858, TorznabCatType.Audio, "         Folk-Rock (lossless)");
-            AddCategoryMapping(675, TorznabCatType.Audio, "         Folk-Rock (lossy)");
-            AddCategoryMapping(861, TorznabCatType.Audio, "         Pop-Rock &amp; Soft Rock (lossless)");
-            AddCategoryMapping(676, TorznabCatType.Audio, "         Pop-Rock &amp; Soft Rock (lossy)");
-            AddCategoryMapping(857, TorznabCatType.Audio, "         Progressive &amp; Art-Rock (lossless)");
-            AddCategoryMapping(674, TorznabCatType.Audio, "         Progressive &amp; Art-Rock (lossy)");
-            AddCategoryMapping(863, TorznabCatType.Audio, "         Rockabilly, Psychobilly, Rock'n'Roll (lossless)");
-            AddCategoryMapping(730, TorznabCatType.Audio, "         Rockabilly, Psychobilly, Rock'n'Roll (lossy)");
-            AddCategoryMapping(1028, TorznabCatType.Audio, "         East Asian Rock (lossless)");
-            AddCategoryMapping(862, TorznabCatType.Audio, "         East Asian rock (lossy)");
-            AddCategoryMapping(1858, TorznabCatType.Audio, "         Collections of foreign rock (lossless)");
-            AddCategoryMapping(1859, TorznabCatType.Audio, "         Collections of foreign rock (lossy)");
-            AddCategoryMapping(187, TorznabCatType.Audio, "      Domestic Rock");
-            AddCategoryMapping(872, TorznabCatType.Audio, "         Rock, Punk, Alternative (lossless)");
-            AddCategoryMapping(190, TorznabCatType.Audio, "         Rock, Punk, Alternative (lossy)");
-            AddCategoryMapping(1489, TorznabCatType.Audio, "         Metal (lossless)");
-            AddCategoryMapping(191, TorznabCatType.Audio, "         Metal (lossy)");
-            AddCategoryMapping(1490, TorznabCatType.Audio, "         Rock on the languages ??of the peoples xUSSR (lossless)");
-            AddCategoryMapping(1491, TorznabCatType.Audio, "         Rock on the languages ??of the peoples xUSSR (lossy)");
-            AddCategoryMapping(866, TorznabCatType.Audio, "      foreign Metal");
-            AddCategoryMapping(727, TorznabCatType.Audio, "         Black (lossy)");
-            AddCategoryMapping(728, TorznabCatType.Audio, "         Death, Doom (lossy)");
-            AddCategoryMapping(729, TorznabCatType.Audio, "         Heavy, Power, Progressive (lossy)");
-            AddCategoryMapping(871, TorznabCatType.Audio, "         Heavy, Power, Progressive (lossless)");
-            AddCategoryMapping(1462, TorznabCatType.Audio, "         Avant-garde, Experimental Metal (lossless)");
-            AddCategoryMapping(1463, TorznabCatType.Audio, "         Avant-garde, Experimental Metal (lossy)");
-            AddCategoryMapping(1464, TorznabCatType.Audio, "         Black (lossless)");
-            AddCategoryMapping(1466, TorznabCatType.Audio, "         Death, Doom (lossless)");
-            AddCategoryMapping(1468, TorznabCatType.Audio, "         Folk, Pagan, Viking (lossless)");
-            AddCategoryMapping(1469, TorznabCatType.Audio, "         Folk, Pagan, Viking (lossy)");
-            AddCategoryMapping(1470, TorznabCatType.Audio, "         Gothic Metal (lossless)");
-            AddCategoryMapping(1471, TorznabCatType.Audio, "         Gothic Metal (lossy)");
-            AddCategoryMapping(1472, TorznabCatType.Audio, "         Grind, Brutal Death (lossless)");
-            AddCategoryMapping(1473, TorznabCatType.Audio, "         Grind, Brutal Death (lossy)");
-            AddCategoryMapping(1474, TorznabCatType.Audio, "         Sludge, Stoner, Post-Metal (lossless)");
-            AddCategoryMapping(1475, TorznabCatType.Audio, "         Sludge, Stoner, Post-Metal (lossy)");
-            AddCategoryMapping(1476, TorznabCatType.Audio, "         Thrash, Speed ??(lossless)");
-            AddCategoryMapping(1477, TorznabCatType.Audio, "         Thrash, Speed ??(lossy)");
-            AddCategoryMapping(1478, TorznabCatType.Audio, "         Collections \"Foreign Metal\" (lossless)");
-            AddCategoryMapping(1479, TorznabCatType.Audio, "         Collections \"Foreign Metal\" (lossy)");
-            AddCategoryMapping(867, TorznabCatType.Audio, "      Foreign Alternative, Punk, Independent");
-            AddCategoryMapping(185, TorznabCatType.Audio, "         Alternative &amp; Nu-metal (lossless)");
-            AddCategoryMapping(868, TorznabCatType.Audio, "         Alternative &amp; Nu-metal (lossy)");
-            AddCategoryMapping(869, TorznabCatType.Audio, "         Indie, Post-Rock &amp; Post-Punk (lossless)");
-            AddCategoryMapping(870, TorznabCatType.Audio, "         Indie, Post-Rock &amp; Post-Punk (lossy)");
-            AddCategoryMapping(873, TorznabCatType.Audio, "         Avant-garde, Experimental Rock (lossy)");
-            AddCategoryMapping(874, TorznabCatType.Audio, "         Punk (lossy)");
-            AddCategoryMapping(875, TorznabCatType.Audio, "         Punk (lossless)");
-            AddCategoryMapping(876, TorznabCatType.Audio, "         Avant-garde, Experimental Rock (lossless)");
-            AddCategoryMapping(1480, TorznabCatType.Audio, "         Hardcore (lossless)");
-            AddCategoryMapping(1481, TorznabCatType.Audio, "         Hardcore (lossy)");
-            AddCategoryMapping(1482, TorznabCatType.Audio, "         Industrial &amp; Post-industrial (lossless)");
-            AddCategoryMapping(1483, TorznabCatType.Audio, "         Industrial &amp; Post-industrial (lossy)");
-            AddCategoryMapping(1484, TorznabCatType.Audio, "         Emocore, Post-hardcore, Metalcore (lossless)");
-            AddCategoryMapping(1485, TorznabCatType.Audio, "         Emocore, Post-hardcore, Metalcore (lossy)");
-            AddCategoryMapping(1486, TorznabCatType.Audio, "         Gothic Rock &amp; Dark Folk (lossless)");
-            AddCategoryMapping(1487, TorznabCatType.Audio, "         Gothic Rock &amp; Dark Folk (lossy)");
-            AddCategoryMapping(1492, TorznabCatType.Audio, "      The multi-channel music and own digitization (Rock)");
-            AddCategoryMapping(1493, TorznabCatType.Audio, "         Foreign rock (own digitization)");
-            AddCategoryMapping(1494, TorznabCatType.Audio, "         Domestic Rock (own digitization)");
-            AddCategoryMapping(1495, TorznabCatType.Audio, "         Foreign and domestic rock (multichannel music)");
-            AddCategoryMapping(1496, TorznabCatType.Audio, "         Foreign rock (Hi-Res stereo)");
-            AddCategoryMapping(1497, TorznabCatType.Audio, "         Conversion Quadraphonic (multichannel music)");
-            AddCategoryMapping(1498, TorznabCatType.Audio, "         Conversion SACD (multi-channel music)");
-            AddCategoryMapping(1499, TorznabCatType.Audio, "         Conversions in Blu-Ray (multichannel music)");
-            AddCategoryMapping(1500, TorznabCatType.Audio, "         Apmiksy-Upmixes / downmix-Downmix (multi-channel and Hi-Res stereo music)");
-            AddCategoryMapping(1501, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Rock)");
-            AddCategoryMapping(1502, TorznabCatType.Audio, "         Rock (Video)");
-            AddCategoryMapping(1503, TorznabCatType.Audio, "         Rock (DVD Video)");
-            AddCategoryMapping(1504, TorznabCatType.Audio, "         Rock (Unofficial DVD Video)");
-            AddCategoryMapping(1505, TorznabCatType.Audio, "         Metal (Video)");
-            AddCategoryMapping(1506, TorznabCatType.Audio, "         Metal (DVD Video)");
-            AddCategoryMapping(1507, TorznabCatType.Audio, "         Metal (Unofficial DVD Video)");
-            AddCategoryMapping(1508, TorznabCatType.Audio, "         Alternative, Punk, Independent (Video)");
-            AddCategoryMapping(1509, TorznabCatType.Audio, "         Alternative, Punk, Independent (DVD Video)");
-            AddCategoryMapping(1510, TorznabCatType.Audio, "         Alternative, Punk, Independent (Unofficial DVD Video)");
-            AddCategoryMapping(1511, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative (Video)");
-            AddCategoryMapping(1512, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative (DVD Video)");
-            AddCategoryMapping(1513, TorznabCatType.Audio, "         Domestic Metal (Video)");
-            AddCategoryMapping(1514, TorznabCatType.Audio, "         Domestic Metal (DVD Video)");
-            AddCategoryMapping(1515, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative, Metal (Unofficial DVD Video)");
-            AddCategoryMapping(1516, TorznabCatType.Audio, "         Rock (HD Video)");
-            AddCategoryMapping(905, TorznabCatType.Audio, "   Folklore, Folk and World Music");
-            AddCategoryMapping(906, TorznabCatType.Audio, "      Eastern European Folk (lossy)");
-            AddCategoryMapping(907, TorznabCatType.Audio, "      Eastern European Folk (lossless)");
-            AddCategoryMapping(908, TorznabCatType.Audio, "      Western European folk (lossy)");
-            AddCategoryMapping(909, TorznabCatType.Audio, "      Western European folk (lossless)");
-            AddCategoryMapping(910, TorznabCatType.Audio, "      Klezmer and Jewish folklore (lossy and lossless)");
-            AddCategoryMapping(911, TorznabCatType.Audio, "      Country, Bluegrass (lossy)");
-            AddCategoryMapping(912, TorznabCatType.Audio, "      Country, Bluegrass (lossless)");
-            AddCategoryMapping(1372, TorznabCatType.Audio, "      World Music Siberia, Central Asia and East Asia (lossy)");
-            AddCategoryMapping(1373, TorznabCatType.Audio, "      World Music Siberia, Central Asia and East Asia (lossless)");
-            AddCategoryMapping(1374, TorznabCatType.Audio, "      World Music India (lossy)");
-            AddCategoryMapping(1375, TorznabCatType.Audio, "      World Music India (lossless)");
-            AddCategoryMapping(1376, TorznabCatType.Audio, "      World Music Africa and the Middle East (lossy)");
-            AddCategoryMapping(1377, TorznabCatType.Audio, "      World Music Africa and the Middle East (lossless)");
-            AddCategoryMapping(1378, TorznabCatType.Audio, "      Ethnic Caucasus and Transcaucasia music (lossy and lossless)");
-            AddCategoryMapping(1379, TorznabCatType.Audio, "      World Music Americas (lossy)");
-            AddCategoryMapping(1380, TorznabCatType.Audio, "      World Music Americas (lossless)");
-            AddCategoryMapping(1381, TorznabCatType.Audio, "      World Music Australia, the Pacific and Indian Oceans (lossy and lossless)");
-            AddCategoryMapping(1382, TorznabCatType.Audio, "      Folklore, Folk and World Music (Video)");
-            AddCategoryMapping(1383, TorznabCatType.Audio, "      Folklore, Folk and World Music (DVD Video)");
-            AddCategoryMapping(1384, TorznabCatType.Audio, "      Folklore, Folk and World Music (HD Video)");
-            AddCategoryMapping(1857, TorznabCatType.Audio, "      Folklore, Folk and World Music (own digitization)");
-            AddCategoryMapping(985, TorznabCatType.Audio, "   Reggae, Ska, Dub");
-            AddCategoryMapping(986, TorznabCatType.Audio, "      Rocksteady, Early Reggae, Ska-Jazz, Trad.Ska (lossy and lossless)");
-            AddCategoryMapping(987, TorznabCatType.Audio, "      Punky-Reggae, Rocksteady-Punk, Ska Revival (lossy)");
-            AddCategoryMapping(988, TorznabCatType.Audio, "      3rd Wave Ska (lossy)");
-            AddCategoryMapping(989, TorznabCatType.Audio, "      Ska-Punk, Ska-Core (lossy)");
-            AddCategoryMapping(990, TorznabCatType.Audio, "      Reggae (lossy)");
-            AddCategoryMapping(1026, TorznabCatType.Audio, "      Dub (lossy)");
-            AddCategoryMapping(991, TorznabCatType.Audio, "      Dancehall, Raggamuffin (lossy)");
-            AddCategoryMapping(992, TorznabCatType.Audio, "      Reggae, Dancehall, Dub (lossless)");
-            AddCategoryMapping(993, TorznabCatType.Audio, "      Ska, Ska-Punk, Ska-Jazz (lossless)");
-            AddCategoryMapping(994, TorznabCatType.Audio, "      Domestic reggae, dub (lossy and lossless)");
-            AddCategoryMapping(995, TorznabCatType.Audio, "      Domestic ska music (lossy and lossless)");
-            AddCategoryMapping(997, TorznabCatType.Audio, "      Reggae, Ska, Dub (own digitization)");
-            AddCategoryMapping(998, TorznabCatType.Audio, "      Reggae, Ska, Dub (compilation) (lossy)");
-            AddCategoryMapping(999, TorznabCatType.Audio, "      Reggae, Ska, Dub (Video)");
-            AddCategoryMapping(1000, TorznabCatType.Audio, "      Reggae, Ska, Dub (DVD and HD Video)");
-            AddCategoryMapping(1418, TorznabCatType.Audio, "   Sheet Music literature");
-            AddCategoryMapping(1419, TorznabCatType.Audio, "      Academic Music (Notes and Media CD)");
-            AddCategoryMapping(1420, TorznabCatType.Audio, "      More destinations (notes, tablature)");
-            AddCategoryMapping(1421, TorznabCatType.Audio, "      Self and School");
-            AddCategoryMapping(1422, TorznabCatType.Audio, "      Songbooks (Songbooks)");
-            AddCategoryMapping(1423, TorznabCatType.Audio, "      Music Literature and Theory");
-            AddCategoryMapping(1424, TorznabCatType.Audio, "      music magazines");
-            AddCategoryMapping(1602, TorznabCatType.Audio, "   Audio for Apple devices");
-            AddCategoryMapping(1603, TorznabCatType.Audio, "      Audiobooks (AAC, ALAC)");
-            AddCategoryMapping(1604, TorznabCatType.Audio, "      Music Lossless (ALAC)");
-            AddCategoryMapping(1605, TorznabCatType.Audio, "      Music Lossy (AAC)");
-            AddCategoryMapping(1606, TorznabCatType.Audio, "      Music Lossy (AAC) (Singles, EPs)");
-            AddCategoryMapping(113, TorznabCatType.Books, "Books, Audio Books, Journals");
-            AddCategoryMapping(561, TorznabCatType.Books, "   Books, Audio Books, Journals (General Discussion)");
-            AddCategoryMapping(316, TorznabCatType.Books, "      Archive (Books, Audio Books, Journals)");
-            AddCategoryMapping(1620, TorznabCatType.Books, "      Meditation");
-            AddCategoryMapping(1802, TorznabCatType.Books, "      Historiography");
-            AddCategoryMapping(116, TorznabCatType.AudioAudiobook, "   Audiobooks");
-            AddCategoryMapping(1231, TorznabCatType.AudioAudiobook, "      Audio, history, memoirs (Audiobooks)");
-            AddCategoryMapping(119, TorznabCatType.AudioAudiobook, "         Audio and literary readings (Audiobooks)");
-            AddCategoryMapping(1232, TorznabCatType.AudioAudiobook, "         Lots of great people (Audiobooks)");
-            AddCategoryMapping(1233, TorznabCatType.AudioAudiobook, "         Historical book (Audiobooks)");
-            AddCategoryMapping(321, TorznabCatType.AudioAudiobook, "      Science fiction, fantasy, mystery, horror, fanfiction (Audiobooks)");
-            AddCategoryMapping(1234, TorznabCatType.AudioAudiobook, "         Russian fiction, fantasy, mystery, horror, fanfiction (audiobook)");
-            AddCategoryMapping(1235, TorznabCatType.AudioAudiobook, "         Foreign fiction, fantasy, mystery, horror, fanfiction (audiobook)");
-            AddCategoryMapping(317, TorznabCatType.AudioAudiobook, "      Fiction (Audiobooks)");
-            AddCategoryMapping(1236, TorznabCatType.AudioAudiobook, "         Poetry (audiobook)");
-            AddCategoryMapping(118, TorznabCatType.AudioAudiobook, "         Foreign literature (audiobook)");
-            AddCategoryMapping(117, TorznabCatType.AudioAudiobook, "         Russian Literature (audiobook)");
-            AddCategoryMapping(120, TorznabCatType.AudioAudiobook, "         Children's Literature (audiobook)");
-            AddCategoryMapping(1237, TorznabCatType.AudioAudiobook, "         Detectives, Adventure, Thriller, Action (audiobook)");
-            AddCategoryMapping(318, TorznabCatType.AudioAudiobook, "            Detectives (audiobook)");
-            AddCategoryMapping(322, TorznabCatType.AudioAudiobook, "      Psychology. philosophy, religion (Audiobooks)");
-            AddCategoryMapping(1238, TorznabCatType.AudioAudiobook, "         Religion (Audio)");
-            AddCategoryMapping(1239, TorznabCatType.AudioAudiobook, "            Orthodox (Audio)");
-            AddCategoryMapping(1240, TorznabCatType.AudioAudiobook, "            Islam (Audio)");
-            AddCategoryMapping(1241, TorznabCatType.AudioAudiobook, "            Other traditional religion (Audio)");
-            AddCategoryMapping(1242, TorznabCatType.AudioAudiobook, "            Nontraditional religious philosophies (Audio)");
-            AddCategoryMapping(1243, TorznabCatType.AudioAudiobook, "      Educational, scientific and popular literature (Audio)");
-            AddCategoryMapping(1244, TorznabCatType.AudioAudiobook, "      Audiobooks in lossless-format");
-            AddCategoryMapping(323, TorznabCatType.AudioAudiobook, "      Business (Audio)");
-            AddCategoryMapping(319, TorznabCatType.AudioAudiobook, "      Historical literature (Audiobooks)");
-            AddCategoryMapping(1245, TorznabCatType.AudioAudiobook, "      Miscellaneous (Audiobooks)");
-            AddCategoryMapping(1622, TorznabCatType.AudioAudiobook, "      Meditation (Audio)");
-            AddCategoryMapping(1626, TorznabCatType.AudioAudiobook, "      publicism");
-            AddCategoryMapping(1627, TorznabCatType.AudioAudiobook, "      Satire, humor");
-            AddCategoryMapping(324, TorznabCatType.AudioAudiobook, "      Archive and nekonditsiya audiobooks");
-            AddCategoryMapping(670, TorznabCatType.Books, "   Books and magazines");
-            AddCategoryMapping(671, TorznabCatType.Books, "      Esoteric Tarot, Feng Shui");
-            AddCategoryMapping(885, TorznabCatType.Books, "      Film, TV, animation");
-            AddCategoryMapping(886, TorznabCatType.Books, "      Drawing, Graphic Design");
-            AddCategoryMapping(887, TorznabCatType.Books, "      Photo and video shooting");
-            AddCategoryMapping(888, TorznabCatType.Books, "      Astrology");
-            AddCategoryMapping(1865, TorznabCatType.Books, "      Fashion. Style. Etiquette");
-            AddCategoryMapping(889, TorznabCatType.Books, "      Celebrities and idols");
-            AddCategoryMapping(890, TorznabCatType.Books, "      Miscellaneous");
-            AddCategoryMapping(982, TorznabCatType.Books, "      Magazines and newspapers (general section)");
-            AddCategoryMapping(566, TorznabCatType.Books, "         Men's magazines");
-            AddCategoryMapping(1204, TorznabCatType.Books, "         For women (magazines and books)");
-            AddCategoryMapping(1793, TorznabCatType.Books, "         Popular science magazines");
-            AddCategoryMapping(1794, TorznabCatType.Books, "         Journals of Electrical and Electronics");
-            AddCategoryMapping(1795, TorznabCatType.Books, "         Housekeeping (logs)");
-            AddCategoryMapping(1796, TorznabCatType.Books, "         Hobbies (logs)");
-            AddCategoryMapping(1797, TorznabCatType.Books, "         Other magazines");
-            AddCategoryMapping(1205, TorznabCatType.Books, "      Travel and tourism");
-            AddCategoryMapping(258, TorznabCatType.Books, "      For children, parents and teachers");
-            AddCategoryMapping(1685, TorznabCatType.Books, "         Tutorials (General)");
-            AddCategoryMapping(681, TorznabCatType.Books, "         Textbooks for kindergarten and elementary school (up to class 4)");
-            AddCategoryMapping(682, TorznabCatType.Books, "         Textbooks for high school (grades 5-11)");
-            AddCategoryMapping(683, TorznabCatType.Books, "         Teachers and educators");
-            AddCategoryMapping(684, TorznabCatType.Books, "         Popular science and cognitive literature (for children)");
-            AddCategoryMapping(685, TorznabCatType.Books, "         Leisure and creativity");
-            AddCategoryMapping(686, TorznabCatType.Books, "         Education and development");
-            AddCategoryMapping(687, TorznabCatType.Books, "         Hood. lit-ra for preschool and elementary grades");
-            AddCategoryMapping(688, TorznabCatType.Books, "         Hood. lit-ra for the middle and upper classes");
-            AddCategoryMapping(731, TorznabCatType.Books, "      Sports, physical training, martial arts");
-            AddCategoryMapping(738, TorznabCatType.Books, "         Autosport. Motorcycling. Cycling (literature)");
-            AddCategoryMapping(737, TorznabCatType.Books, "         Martial arts, martial arts (literature)");
-            AddCategoryMapping(734, TorznabCatType.Books, "         Team sports (literature)");
-            AddCategoryMapping(1854, TorznabCatType.Books, "         Athletics. Swimming. Gymnastics. Weightlifting. Rowing (literature)");
-            AddCategoryMapping(739, TorznabCatType.Books, "         Sport Editions");
-            AddCategoryMapping(736, TorznabCatType.Books, "         Fitness, fitness, bodybuilding (literature)");
-            AddCategoryMapping(732, TorznabCatType.Books, "         Football (literature)");
-            AddCategoryMapping(733, TorznabCatType.Books, "         Hockey (literature)");
-            AddCategoryMapping(735, TorznabCatType.Books, "         Chess. Checkers (literature)");
-            AddCategoryMapping(1855, TorznabCatType.Books, "         Extreme sports (literature)");
-            AddCategoryMapping(649, TorznabCatType.Books, "      Humanitarian sciences");
-            AddCategoryMapping(650, TorznabCatType.Books, "         Arts. Cultural");
-            AddCategoryMapping(651, TorznabCatType.Books, "         Folklore. Epic. Mythology");
-            AddCategoryMapping(652, TorznabCatType.Books, "         literary criticism");
-            AddCategoryMapping(653, TorznabCatType.Books, "         Linguistics");
-            AddCategoryMapping(654, TorznabCatType.Books, "         Philosophy");
-            AddCategoryMapping(655, TorznabCatType.Books, "         Political science");
-            AddCategoryMapping(656, TorznabCatType.Books, "         Sociology");
-            AddCategoryMapping(657, TorznabCatType.Books, "         Journalism, Journalism");
-            AddCategoryMapping(658, TorznabCatType.Books, "         Business, Management");
-            AddCategoryMapping(659, TorznabCatType.Books, "         Marketing");
-            AddCategoryMapping(660, TorznabCatType.Books, "         Economy");
-            AddCategoryMapping(661, TorznabCatType.Books, "         Finance");
-            AddCategoryMapping(662, TorznabCatType.Books, "         Jurisprudence. Right. criminalistics");
-            AddCategoryMapping(664, TorznabCatType.Books, "      Historical sciences");
-            AddCategoryMapping(665, TorznabCatType.Books, "         Historical person");
-            AddCategoryMapping(807, TorznabCatType.Books, "         Historical sources");
-            AddCategoryMapping(808, TorznabCatType.Books, "         Alternative historical theories");
-            AddCategoryMapping(809, TorznabCatType.Books, "         Archeology");
-            AddCategoryMapping(810, TorznabCatType.Books, "         Ancient world. Antiquity");
-            AddCategoryMapping(811, TorznabCatType.Books, "         Middle Ages");
-            AddCategoryMapping(812, TorznabCatType.Books, "         The history of modern and contemporary");
-            AddCategoryMapping(813, TorznabCatType.Books, "         History of Europe");
-            AddCategoryMapping(814, TorznabCatType.Books, "         History of Asia and Africa");
-            AddCategoryMapping(815, TorznabCatType.Books, "         The history of America, Australia, Oceania");
-            AddCategoryMapping(816, TorznabCatType.Books, "         Russian history");
-            AddCategoryMapping(817, TorznabCatType.Books, "         The era of the Soviet Union");
-            AddCategoryMapping(818, TorznabCatType.Books, "         History of the former Soviet Union");
-            AddCategoryMapping(819, TorznabCatType.Books, "         Ethnography, anthropology");
-            AddCategoryMapping(820, TorznabCatType.Books, "         International relationships. Diplomacy");
-            AddCategoryMapping(1856, TorznabCatType.Books, "         Methodology and philosophy of history");
-            AddCategoryMapping(255, TorznabCatType.Books, "      Accurate, natural and engineering sciences");
-            AddCategoryMapping(648, TorznabCatType.Books, "         Geography / Geology / Geodesy");
-            AddCategoryMapping(672, TorznabCatType.Books, "         Physics");
-            AddCategoryMapping(723, TorznabCatType.Books, "         Astronomy");
-            AddCategoryMapping(725, TorznabCatType.Books, "         Aviation / Astronautics");
-            AddCategoryMapping(726, TorznabCatType.Books, "         Mathematics");
-            AddCategoryMapping(748, TorznabCatType.Books, "         Welding / Soldering / Non-Destructive Testing");
-            AddCategoryMapping(749, TorznabCatType.Books, "         Architecture / construction / engineering services");
-            AddCategoryMapping(750, TorznabCatType.Books, "         Biology / Ecology");
-            AddCategoryMapping(751, TorznabCatType.Books, "         Chemistry / Biochemistry");
-            AddCategoryMapping(821, TorznabCatType.Books, "         Electronics / Radio");
-            AddCategoryMapping(822, TorznabCatType.Books, "         Diagrams and service manuals (original documents)");
-            AddCategoryMapping(823, TorznabCatType.Books, "         engineering");
-            AddCategoryMapping(824, TorznabCatType.Books, "         Automation / Robotics");
-            AddCategoryMapping(825, TorznabCatType.Books, "         Metallurgy / Materials");
-            AddCategoryMapping(826, TorznabCatType.Books, "         Mechanics, Strength of Materials");
-            AddCategoryMapping(827, TorznabCatType.Books, "         Energy / Electrical");
-            AddCategoryMapping(828, TorznabCatType.Books, "         Oil, gas and chemical industry");
-            AddCategoryMapping(829, TorznabCatType.Books, "         Agriculture and food industry");
-            AddCategoryMapping(836, TorznabCatType.Books, "         Railway deal");
-            AddCategoryMapping(837, TorznabCatType.Books, "         Normative documents");
-            AddCategoryMapping(838, TorznabCatType.Books, "         Journals: scientific, popular, radio and others.");
-            AddCategoryMapping(668, TorznabCatType.Books, "      Warfare");
-            AddCategoryMapping(669, TorznabCatType.Books, "         History of the Second World War");
-            AddCategoryMapping(830, TorznabCatType.Books, "         Militaria");
-            AddCategoryMapping(831, TorznabCatType.Books, "         Military history");
-            AddCategoryMapping(832, TorznabCatType.Books, "         Military equipment");
-            AddCategoryMapping(833, TorznabCatType.Books, "         Weapon");
-            AddCategoryMapping(834, TorznabCatType.Books, "         Educational literature");
-            AddCategoryMapping(835, TorznabCatType.Books, "         The special services of the world");
-            AddCategoryMapping(666, TorznabCatType.Books, "      Faith and Religion");
-            AddCategoryMapping(667, TorznabCatType.Books, "         Christianity");
-            AddCategoryMapping(881, TorznabCatType.Books, "         Islam");
-            AddCategoryMapping(882, TorznabCatType.Books, "         Religions of India, Tibet and East Asia / Judaism");
-            AddCategoryMapping(883, TorznabCatType.Books, "         Nontraditional religious, spiritual and mystical teachings");
-            AddCategoryMapping(884, TorznabCatType.Books, "         Religious Studies. History of Religions. Atheism");
-            AddCategoryMapping(1206, TorznabCatType.Books, "      Psychology");
-            AddCategoryMapping(1207, TorznabCatType.Books, "         General and Applied Psychology");
-            AddCategoryMapping(1208, TorznabCatType.Books, "         Psychotherapy and counseling");
-            AddCategoryMapping(1209, TorznabCatType.Books, "         Psychological diagnostics and therapy");
-            AddCategoryMapping(1210, TorznabCatType.Books, "         Social psychology and psychology of relationships");
-            AddCategoryMapping(1211, TorznabCatType.Books, "         Training and Coaching");
-            AddCategoryMapping(1212, TorznabCatType.Books, "         Self-development and self-improvement");
-            AddCategoryMapping(1213, TorznabCatType.Books, "         Popular psychology");
-            AddCategoryMapping(1214, TorznabCatType.Books, "         Sexology. Relations between the sexes");
-            AddCategoryMapping(254, TorznabCatType.Books, "      Collecting, hobby and hobbies");
-            AddCategoryMapping(633, TorznabCatType.Books, "         Collecting and auxiliary ist. discipline");
-            AddCategoryMapping(634, TorznabCatType.Books, "         Embroidery");
-            AddCategoryMapping(635, TorznabCatType.Books, "         Knitting");
-            AddCategoryMapping(636, TorznabCatType.Books, "         Sewing, patchwork");
-            AddCategoryMapping(637, TorznabCatType.Books, "         lace");
-            AddCategoryMapping(638, TorznabCatType.Books, "         Beading");
-            AddCategoryMapping(639, TorznabCatType.Books, "         Paper art");
-            AddCategoryMapping(640, TorznabCatType.Books, "         Other arts and crafts");
-            AddCategoryMapping(641, TorznabCatType.Books, "         Pets and aquariums");
-            AddCategoryMapping(642, TorznabCatType.Books, "         Hunting and fishing");
-            AddCategoryMapping(598, TorznabCatType.Books, "         Cooking (Book)");
-            AddCategoryMapping(312, TorznabCatType.Books, "         Cooking (newspapers and magazines)");
-            AddCategoryMapping(643, TorznabCatType.Books, "         Modelling");
-            AddCategoryMapping(644, TorznabCatType.Books, "         Farmland / Floriculture");
-            AddCategoryMapping(645, TorznabCatType.Books, "         Repair, private construction, design of interiors");
-            AddCategoryMapping(1866, TorznabCatType.Books, "         Woodworking");
-            AddCategoryMapping(646, TorznabCatType.Books, "         Board games");
-            AddCategoryMapping(647, TorznabCatType.Books, "         Other hobbies");
-            AddCategoryMapping(1786, TorznabCatType.Books, "      Nonfiction");
-            AddCategoryMapping(623, TorznabCatType.Books, "      Fiction");
-            AddCategoryMapping(624, TorznabCatType.Books, "         Russian Literature (books)");
-            AddCategoryMapping(627, TorznabCatType.Books, "         The detective, thriller (book)");
-            AddCategoryMapping(1624, TorznabCatType.Books, "            Militants (Books)");
-            AddCategoryMapping(1625, TorznabCatType.Books, "            Detectives (Books)");
-            AddCategoryMapping(628, TorznabCatType.Books, "         Female Novel (Book)");
-            AddCategoryMapping(631, TorznabCatType.Books, "         Adventure (book)");
-            AddCategoryMapping(632, TorznabCatType.Books, "         Literary magazines");
-            AddCategoryMapping(1611, TorznabCatType.Books, "         Fiction / Fantasy / Mystic (book)");
-            AddCategoryMapping(629, TorznabCatType.Books, "            Domestic science fiction / fantasy / mystic");
-            AddCategoryMapping(630, TorznabCatType.Books, "            International science fiction / fantasy / mystic");
-            AddCategoryMapping(1612, TorznabCatType.Books, "         Foreign literature (books)");
-            AddCategoryMapping(625, TorznabCatType.Books, "            Foreign literature (up to 1900)");
-            AddCategoryMapping(626, TorznabCatType.Books, "            Foreign literature (XX and XXI century)");
-            AddCategoryMapping(1618, TorznabCatType.Books, "         Historical books");
-            AddCategoryMapping(1789, TorznabCatType.Books, "         Satire, humor (the book)");
-            AddCategoryMapping(257, TorznabCatType.Books, "      Computer books");
-            AddCategoryMapping(678, TorznabCatType.Books, "         Programming (Literature)");
-            AddCategoryMapping(714, TorznabCatType.Books, "         Programs from Microsoft (literature)");
-            AddCategoryMapping(715, TorznabCatType.Books, "         Other programs (literature)");
-            AddCategoryMapping(716, TorznabCatType.Books, "         Mac OS; Linux, FreeBSD and other * NIX (literature)");
-            AddCategoryMapping(717, TorznabCatType.Books, "         DBMS (literature)");
-            AddCategoryMapping(718, TorznabCatType.Books, "         Web Design and Programming (Literature)");
-            AddCategoryMapping(719, TorznabCatType.Books, "         Graphics, video processing (literature)");
-            AddCategoryMapping(720, TorznabCatType.Books, "         Network / VoIP (literature)");
-            AddCategoryMapping(721, TorznabCatType.Books, "         Hacking and Security (literature)");
-            AddCategoryMapping(722, TorznabCatType.Books, "         Iron (book on a PC)");
-            AddCategoryMapping(1215, TorznabCatType.Books, "         Engineering and science programs (literature)");
-            AddCategoryMapping(1216, TorznabCatType.Books, "         Computer magazines and annexes");
-            AddCategoryMapping(1791, TorznabCatType.Books, "            gaming magazines");
-            AddCategoryMapping(1792, TorznabCatType.Books, "            Computer magazines");
-            AddCategoryMapping(1217, TorznabCatType.Books, "         Disc applications to gaming magazines");
-            AddCategoryMapping(311, TorznabCatType.Books, "      Comics");
-            AddCategoryMapping(1218, TorznabCatType.Books, "         Comics in Russian");
-            AddCategoryMapping(1219, TorznabCatType.Books, "         Marvel Comics publishing");
-            AddCategoryMapping(1220, TorznabCatType.Books, "         DC Comics publishing");
-            AddCategoryMapping(1221, TorznabCatType.Books, "         Comics from other publishers");
-            AddCategoryMapping(1222, TorznabCatType.Books, "         Comics in other languages");
-            AddCategoryMapping(1223, TorznabCatType.Books, "         Substandard distribution (Comics)");
-            AddCategoryMapping(259, TorznabCatType.Books, "      Collections of books and libraries");
-            AddCategoryMapping(983, TorznabCatType.Books, "         Libraries (mirror network libraries / collections)");
-            AddCategoryMapping(984, TorznabCatType.Books, "         Thematic collections (collections)");
-            AddCategoryMapping(1224, TorznabCatType.Books, "         Multidisciplinary collection (compilation)");
-            AddCategoryMapping(1788, TorznabCatType.Books, "         Mnogoavtorskie collections, book series");
-            AddCategoryMapping(1787, TorznabCatType.Books, "      Encyclopedias and dictionaries");
-            AddCategoryMapping(1225, TorznabCatType.Books, "   Multimedia and online publications");
-            AddCategoryMapping(1226, TorznabCatType.Books, "      Multimedia encyclopedia");
-            AddCategoryMapping(1227, TorznabCatType.Books, "      Interactive tutorials and educational materials");
-            AddCategoryMapping(1228, TorznabCatType.Books, "      Educational publications for children");
-            AddCategoryMapping(1229, TorznabCatType.Books, "      Cooking. Floriculture. housekeeping");
-            AddCategoryMapping(1230, TorznabCatType.Books, "      Culture. Art. History");
-            AddCategoryMapping(497, TorznabCatType.Books, "training materials");
-            AddCategoryMapping(1246, TorznabCatType.Books, "   Learning foreign languages");
-            AddCategoryMapping(1248, TorznabCatType.Books, "      Foreign languages ??for children");
-            AddCategoryMapping(1249, TorznabCatType.Books, "         English (for children)");
-            AddCategoryMapping(1250, TorznabCatType.Books, "         Other European languages ??(for children)");
-            AddCategoryMapping(1251, TorznabCatType.Books, "         Oriental languages ??(for children)");
-            AddCategoryMapping(1252, TorznabCatType.Books, "         School books, the exam (for children)");
-            AddCategoryMapping(1253, TorznabCatType.Books, "      Fiction in foreign languages");
-            AddCategoryMapping(1254, TorznabCatType.Books, "         Fiction in English");
-            AddCategoryMapping(1255, TorznabCatType.Books, "         Fiction French");
-            AddCategoryMapping(1256, TorznabCatType.Books, "         Fiction in other European languages");
-            AddCategoryMapping(1257, TorznabCatType.Books, "         Fiction in oriental languages");
-            AddCategoryMapping(1258, TorznabCatType.Books, "      Foreign Language for Adults");
-            AddCategoryMapping(1259, TorznabCatType.Books, "         English (for adults)");
-            AddCategoryMapping(1260, TorznabCatType.Books, "         German");
-            AddCategoryMapping(1261, TorznabCatType.Books, "         French");
-            AddCategoryMapping(1262, TorznabCatType.Books, "         Spanish");
-            AddCategoryMapping(1263, TorznabCatType.Books, "         Italian language");
-            AddCategoryMapping(1264, TorznabCatType.Books, "         Other European languages");
-            AddCategoryMapping(1265, TorznabCatType.Books, "         Arabic language");
-            AddCategoryMapping(1266, TorznabCatType.Books, "         Chinese");
-            AddCategoryMapping(1267, TorznabCatType.Books, "         Japanese");
-            AddCategoryMapping(1268, TorznabCatType.Books, "         Other oriental languages");
-            AddCategoryMapping(1269, TorznabCatType.Books, "         Russian as a foreign language");
-            AddCategoryMapping(1270, TorznabCatType.Books, "         Multilanguage collections");
-            AddCategoryMapping(1271, TorznabCatType.Books, "         Miscellaneous (foreign languages)");
-            AddCategoryMapping(1867, TorznabCatType.Books, "         LIM-courses");
-            AddCategoryMapping(1272, TorznabCatType.Books, "      Audio Books in foreign languages");
-            AddCategoryMapping(1273, TorznabCatType.Books, "         Audiobooks in English");
-            AddCategoryMapping(1274, TorznabCatType.Books, "         Audiobooks in German");
-            AddCategoryMapping(1275, TorznabCatType.Books, "         Audiobooks in other languages");
-            AddCategoryMapping(1623, TorznabCatType.Books, "      Educational audio materials");
-            AddCategoryMapping(1247, TorznabCatType.Books, "   video tutorials");
-            AddCategoryMapping(933, TorznabCatType.Books, "      Video tutorials and interactive training DVD");
-            AddCategoryMapping(936, TorznabCatType.Books, "         Cooking (video tutorial)");
-            AddCategoryMapping(1276, TorznabCatType.Books, "         Sport");
-            AddCategoryMapping(934, TorznabCatType.Books, "         Fitness - Cardio, Strength Training");
-            AddCategoryMapping(1277, TorznabCatType.Books, "         Fitness - Mind and Body");
-            AddCategoryMapping(1278, TorznabCatType.Books, "         Extreme sports (video tutorial)");
-            AddCategoryMapping(935, TorznabCatType.Books, "         Playing guitar");
-            AddCategoryMapping(1279, TorznabCatType.Books, "         Body-building");
-            AddCategoryMapping(1280, TorznabCatType.Books, "         Health practice");
-            AddCategoryMapping(1281, TorznabCatType.Books, "         Yoga");
-            AddCategoryMapping(1282, TorznabCatType.Books, "         Video and Snapshots");
-            AddCategoryMapping(1283, TorznabCatType.Books, "         Personal care");
-            AddCategoryMapping(1284, TorznabCatType.Books, "         Painting");
-            AddCategoryMapping(1286, TorznabCatType.Books, "         Percussion instruments");
-            AddCategoryMapping(1287, TorznabCatType.Books, "         Other musical instruments");
-            AddCategoryMapping(1288, TorznabCatType.Books, "         Playing bass guitar");
-            AddCategoryMapping(1289, TorznabCatType.Books, "         Ballroom dancing");
-            AddCategoryMapping(1290, TorznabCatType.Books, "         Belly dance");
-            AddCategoryMapping(1291, TorznabCatType.Books, "         Street and club dances");
-            AddCategoryMapping(1292, TorznabCatType.Books, "         Dancing, miscellaneous");
-            AddCategoryMapping(1295, TorznabCatType.Books, "         Tricks and stunts");
-            AddCategoryMapping(1296, TorznabCatType.Books, "         Education");
-            AddCategoryMapping(1297, TorznabCatType.Books, "         Business, Economics and Finance");
-            AddCategoryMapping(1299, TorznabCatType.Books, "         Pregnancy, childbirth, motherhood");
-            AddCategoryMapping(1300, TorznabCatType.Books, "         Educational video for children");
-            AddCategoryMapping(1301, TorznabCatType.Books, "         Psychology (video)");
-            AddCategoryMapping(1302, TorznabCatType.Books, "         Spirituality, self-development");
-            AddCategoryMapping(1303, TorznabCatType.Books, "         Pickup, love");
-            AddCategoryMapping(1304, TorznabCatType.Books, "         Construction, renovation and design");
-            AddCategoryMapping(1305, TorznabCatType.Books, "         Wood and metal");
-            AddCategoryMapping(1306, TorznabCatType.Books, "         Plants and Animals");
-            AddCategoryMapping(1676, TorznabCatType.Books, "         Fishing and hunting");
-            AddCategoryMapping(1293, TorznabCatType.Books, "            Hunting");
-            AddCategoryMapping(1294, TorznabCatType.Books, "            Fishing and spearfishing");
-            AddCategoryMapping(1307, TorznabCatType.Books, "         Miscellaneous (Video tutorials and educational interactive DVD)");
-            AddCategoryMapping(1309, TorznabCatType.Books, "      Martial Arts (Video Tutorials)");
-            AddCategoryMapping(1310, TorznabCatType.Books, "         Aikido and Aiki-jutsu");
-            AddCategoryMapping(1311, TorznabCatType.Books, "         Wing Chun");
-            AddCategoryMapping(1312, TorznabCatType.Books, "         Jujutsu");
-            AddCategoryMapping(1313, TorznabCatType.Books, "         Judo and Sambo");
-            AddCategoryMapping(1314, TorznabCatType.Books, "         Karate");
-            AddCategoryMapping(1315, TorznabCatType.Books, "         knife fight");
-            AddCategoryMapping(1316, TorznabCatType.Books, "         Work with weapon");
-            AddCategoryMapping(1317, TorznabCatType.Books, "         Russian style");
-            AddCategoryMapping(1318, TorznabCatType.Books, "         dogfight");
-            AddCategoryMapping(1319, TorznabCatType.Books, "         composite style");
-            AddCategoryMapping(1320, TorznabCatType.Books, "         shock styles");
-            AddCategoryMapping(1321, TorznabCatType.Books, "         Wushu");
-            AddCategoryMapping(1322, TorznabCatType.Books, "         Miscellaneous (Video Tutorials)");
-            AddCategoryMapping(1323, TorznabCatType.Books, "      Computer video tutorials and interactive training DVD");
-            AddCategoryMapping(1324, TorznabCatType.Books, "         Computer networks and security (video tutorial)");
-            AddCategoryMapping(1325, TorznabCatType.Books, "         OS and Microsoft server software (video tutorial)");
-            AddCategoryMapping(1326, TorznabCatType.Books, "         Microsoft Office software (video tutorial)");
-            AddCategoryMapping(1327, TorznabCatType.Books, "         OS and UNIX-program (video tutorial)");
-            AddCategoryMapping(1329, TorznabCatType.Books, "         Adobe Photoshop (video tutorial)");
-            AddCategoryMapping(1330, TorznabCatType.Books, "         Autodesk Maya (video tutorial)");
-            AddCategoryMapping(1331, TorznabCatType.Books, "         Autodesk 3ds Max (video tutorial)");
-            AddCategoryMapping(1332, TorznabCatType.Books, "         Autodesk Softimage (XSI) (video tutorial)");
-            AddCategoryMapping(1333, TorznabCatType.Books, "         ZBrush (video tutorial)");
-            AddCategoryMapping(1334, TorznabCatType.Books, "         Flash, Flex and ActionScript (video tutorial)");
-            AddCategoryMapping(1335, TorznabCatType.Books, "         2D-graphics (video tutorial)");
-            AddCategoryMapping(1336, TorznabCatType.Books, "         3D-graphics (video tutorial)");
-            AddCategoryMapping(1337, TorznabCatType.Books, "         Engineering and science programs (video tutorial)");
-            AddCategoryMapping(1338, TorznabCatType.Books, "         Web-design (video tutorial)");
-            AddCategoryMapping(1339, TorznabCatType.Books, "         Programming (video tutorial)");
-            AddCategoryMapping(1340, TorznabCatType.Books, "         Software for Mac OS (video tutorial)");
-            AddCategoryMapping(1341, TorznabCatType.Books, "         Working with video (video tutorial)");
-            AddCategoryMapping(1342, TorznabCatType.Books, "         Working with sound (video tutorial)");
-            AddCategoryMapping(1343, TorznabCatType.Books, "         Miscellaneous (Computer video tutorials)");
-            AddCategoryMapping(1530, TorznabCatType.Other, "Subject forums");
-            AddCategoryMapping(698, TorznabCatType.Other, "   Auto and Moto");
-            AddCategoryMapping(699, TorznabCatType.Other, "      Repair and maintenance of vehicles");
-            AddCategoryMapping(772, TorznabCatType.Other, "         The original selection of spare parts catalogs");
-            AddCategoryMapping(1344, TorznabCatType.Other, "         Non-original spare parts catalogs for selection");
-            AddCategoryMapping(1345, TorznabCatType.Other, "         diagnostic and repair programs");
-            AddCategoryMapping(1346, TorznabCatType.Other, "         Tuning, chip tuning, tuning");
-            AddCategoryMapping(700, TorznabCatType.Other, "         Books for repair / maintenance / operation of the vehicle");
-            AddCategoryMapping(1349, TorznabCatType.Other, "         Multimediyki repair / maintenance / operation of the vehicle");
-            AddCategoryMapping(1350, TorznabCatType.Other, "         Accounting, utilities, etc.");
-            AddCategoryMapping(1351, TorznabCatType.Other, "         Virtual Driving School");
-            AddCategoryMapping(1352, TorznabCatType.Other, "         Video lessons on driving vehicles");
-            AddCategoryMapping(1353, TorznabCatType.Other, "         Video lessons on repair of vehicles");
-            AddCategoryMapping(1354, TorznabCatType.Other, "         Magazines Auto / Moto");
-            AddCategoryMapping(1355, TorznabCatType.Other, "         Water transport");
-            AddCategoryMapping(1356, TorznabCatType.Other, "      Movies and television shows, car / moto");
-            AddCategoryMapping(1357, TorznabCatType.Other, "         Documentary / educational films");
-            AddCategoryMapping(1358, TorznabCatType.Other, "         entertainment shows");
-            AddCategoryMapping(1359, TorznabCatType.Other, "         Top Gear / Top Gear");
-            AddCategoryMapping(1360, TorznabCatType.Other, "         Test Drive / Reviews / Motor");
-            AddCategoryMapping(1361, TorznabCatType.Other, "         Tuning / Fast and the Furious");
-            AddCategoryMapping(600, TorznabCatType.Other, "   Medicine and Health");
-            AddCategoryMapping(601, TorznabCatType.Other, "      Books, magazines and on medicine and health program");
-            AddCategoryMapping(603, TorznabCatType.Other, "         Clinical medicine until 1980");
-            AddCategoryMapping(604, TorznabCatType.Other, "         Clinical Medicine from 1980 to 2000");
-            AddCategoryMapping(605, TorznabCatType.Other, "         Clinical Medicine since 2000");
-            AddCategoryMapping(606, TorznabCatType.Other, "         The popular medical periodicals (newspapers and magazines)");
-            AddCategoryMapping(607, TorznabCatType.Other, "         The scientific medical periodicals (newspapers and magazines)");
-            AddCategoryMapping(608, TorznabCatType.Other, "         Life Sciences");
-            AddCategoryMapping(609, TorznabCatType.Other, "         Pharmacy and Pharmacology");
-            AddCategoryMapping(610, TorznabCatType.Other, "         Non-traditional, traditional medicine and popular books on health");
-            AddCategoryMapping(611, TorznabCatType.Other, "         Veterinary, miscellaneous");
-            AddCategoryMapping(612, TorznabCatType.Other, "         Thematic collections of books");
-            AddCategoryMapping(613, TorznabCatType.Other, "         Audiobooks on medicine");
-            AddCategoryMapping(614, TorznabCatType.Other, "         Medical software");
-            AddCategoryMapping(602, TorznabCatType.Other, "      Tutorials, Doc. movies and TV shows on medicine");
-            AddCategoryMapping(615, TorznabCatType.Other, "         Medicine and Dentistry");
-            AddCategoryMapping(616, TorznabCatType.Other, "         Psychotherapy and clinical psychology");
-            AddCategoryMapping(617, TorznabCatType.Other, "         Massage");
-            AddCategoryMapping(618, TorznabCatType.Other, "         Health");
-            AddCategoryMapping(619, TorznabCatType.Other, "         Documentary movies and TV shows on medicine");
-            AddCategoryMapping(560, TorznabCatType.Other, "other");
-            AddCategoryMapping(578, TorznabCatType.Other, "   Economy and Life");
-            AddCategoryMapping(1558, TorznabCatType.Other, "   psychoactive audio programs");
-            AddCategoryMapping(1560, TorznabCatType.Other, "   Avatars, Icons, Smileys, painting, drawing, sculpture, pictures, wallpaper, Photography, Digital Art");
-            AddCategoryMapping(1651, TorznabCatType.Other, "      reproductions of paintings");
-            AddCategoryMapping(1652, TorznabCatType.Other, "      Art photography");
-            AddCategoryMapping(1653, TorznabCatType.Other, "      Contemporary photography");
-            AddCategoryMapping(1654, TorznabCatType.Other, "      Collections of works of modern art painters");
-            AddCategoryMapping(1655, TorznabCatType.Other, "      hand-drawn graphics");
-            AddCategoryMapping(1656, TorznabCatType.Other, "      Computer graphics");
-            AddCategoryMapping(1657, TorznabCatType.Other, "      Illustrations");
-            AddCategoryMapping(1659, TorznabCatType.Other, "      Graphics (Other)");
-            AddCategoryMapping(1562, TorznabCatType.Other, "      Amateur photos");
-            AddCategoryMapping(1561, TorznabCatType.Other, "      Pictures");
-            AddCategoryMapping(1563, TorznabCatType.Other, "      Photos of celebrities");
-            AddCategoryMapping(996, TorznabCatType.Other, "      Desktop Wallpaper \\ Wallpapers");
-            AddCategoryMapping(1578, TorznabCatType.Other, "      Wallpapers and themes for mobile devices");
-            AddCategoryMapping(1559, TorznabCatType.Other, "      Avatars, Icons, Smileys");
-            AddCategoryMapping(1564, TorznabCatType.Other, "   Audio");
-            AddCategoryMapping(1801, TorznabCatType.Other, "      Mobile Audio");
-            AddCategoryMapping(1565, TorznabCatType.Other, "   Video (Other)");
-            AddCategoryMapping(1566, TorznabCatType.Other, "   Publications and educational materials (texts)");
-            AddCategoryMapping(1567, TorznabCatType.Other, "   Sports (video)");
+            AddCategoryMapping(30, TorznabCatType.Movies, "Video content");
+            AddCategoryMapping(31, TorznabCatType.TVDocumentary, "   Documentary films, TV and other video");
+            AddCategoryMapping(127, TorznabCatType.TVDocumentary, "      Documentary movies and TV shows");
+            AddCategoryMapping(1071, TorznabCatType.TVDocumentary, "         Documentary (DVD)");
+            AddCategoryMapping(1069, TorznabCatType.TVDocumentary, "         Documentary (HD Video)");
+            AddCategoryMapping(1070, TorznabCatType.TVDocumentary, "            TV shows (HD Video), non-documentary");
+            AddCategoryMapping(1843, TorznabCatType.TVDocumentary, "            Biographies. Personality and idols (HD Video)");
+            AddCategoryMapping(1844, TorznabCatType.TVDocumentary, "            Military Science (HD Video)");
+            AddCategoryMapping(1845, TorznabCatType.TVDocumentary, "            Natural science, science and technology (HD Video)");
+            AddCategoryMapping(1846, TorznabCatType.TVDocumentary, "            Travel and Tourism (HD Video)");
+            AddCategoryMapping(1847, TorznabCatType.TVDocumentary, "            Flora and fauna (HD Video)");
+            AddCategoryMapping(1848, TorznabCatType.TVDocumentary, "            History (HD Video)");
+            AddCategoryMapping(1849, TorznabCatType.TVDocumentary, "            BBC, Discovery, National Geographic (HD Video)");
+            AddCategoryMapping(1850, TorznabCatType.TVDocumentary, "            Crime Documentary (HD Video)");
+            AddCategoryMapping(1072, TorznabCatType.TVDocumentary, "         Biographies. Personality and idols");
+            AddCategoryMapping(1073, TorznabCatType.TVDocumentary, "         Documentary movies and TV shows on film and animation (including biographies)");
+            AddCategoryMapping(1074, TorznabCatType.TVDocumentary, "         Art, Art History");
+            AddCategoryMapping(1075, TorznabCatType.TVDocumentary, "         Documentaries and television music (including biographies)");
+            AddCategoryMapping(1076, TorznabCatType.TVDocumentary, "         criminal documentary");
+            AddCategoryMapping(1077, TorznabCatType.TVDocumentary, "         Secrets of the Ages / Special Services / Conspiracy Theory");
+            AddCategoryMapping(1078, TorznabCatType.TVDocumentary, "         Movies and TV shows on military issues");
+            AddCategoryMapping(1079, TorznabCatType.TVDocumentary, "            The Second World War");
+            AddCategoryMapping(1675, TorznabCatType.TVDocumentary, "            Fleet");
+            AddCategoryMapping(1080, TorznabCatType.TVDocumentary, "         Accidents / Accidents / Disasters");
+            AddCategoryMapping(1081, TorznabCatType.TVDocumentary, "         Aviation (video)");
+            AddCategoryMapping(1674, TorznabCatType.TVDocumentary, "            Wings of Russia");
+            AddCategoryMapping(1082, TorznabCatType.TVDocumentary, "         Space (Video)");
+            AddCategoryMapping(576, TorznabCatType.TVDocumentary, "         Popular-science film");
+            AddCategoryMapping(1083, TorznabCatType.TVDocumentary, "         The flora and fauna of the (video)");
+            AddCategoryMapping(1084, TorznabCatType.TVDocumentary, "         Travel and Tourism (video)");
+            AddCategoryMapping(1085, TorznabCatType.TVDocumentary, "         Social talk show");
+            AddCategoryMapping(1086, TorznabCatType.TVDocumentary, "         Information-analytical and socio-political programs");
+            AddCategoryMapping(1087, TorznabCatType.TVDocumentary, "         Architecture and Construction (video)");
+            AddCategoryMapping(1088, TorznabCatType.TVDocumentary, "         All about home, life and design");
+            AddCategoryMapping(1094, TorznabCatType.TVDocumentary, "         The era of the Soviet Union (video)");
+            AddCategoryMapping(1095, TorznabCatType.TVDocumentary, "         Battle of psychics / Theory improbability / Seekers / Galileo");
+            AddCategoryMapping(1096, TorznabCatType.TVDocumentary, "         Russian sensation / Program Maximum / Profession Reporter / Ukrainian sensation");
+            AddCategoryMapping(1097, TorznabCatType.TVDocumentary, "         Paranormal activity");
+            AddCategoryMapping(1098, TorznabCatType.TVDocumentary, "         Alternative history, Science (video)");
+            AddCategoryMapping(1099, TorznabCatType.TVDocumentary, "         Vnezhanrovaya documentary");
+            AddCategoryMapping(1660, TorznabCatType.TVDocumentary, "         Foreign TV-brands");
+            AddCategoryMapping(1089, TorznabCatType.TVDocumentary, "            BBC");
+            AddCategoryMapping(1090, TorznabCatType.TVDocumentary, "            Discovery");
+            AddCategoryMapping(1091, TorznabCatType.TVDocumentary, "            National Geographic");
+            AddCategoryMapping(1661, TorznabCatType.TVDocumentary, "            Animal Planet");
+            AddCategoryMapping(1662, TorznabCatType.TVDocumentary, "            Da Vinci Learning");
+            AddCategoryMapping(1663, TorznabCatType.TVDocumentary, "            History Channel");
+            AddCategoryMapping(1664, TorznabCatType.TVDocumentary, "            PBS");
+            AddCategoryMapping(1665, TorznabCatType.TVDocumentary, "            Readers Digest");
+            AddCategoryMapping(1666, TorznabCatType.TVDocumentary, "            I wonder about everything");
+            AddCategoryMapping(1667, TorznabCatType.TVDocumentary, "            Mega-Projects");
+            AddCategoryMapping(1668, TorznabCatType.TVDocumentary, "            Prehistoric world");
+            AddCategoryMapping(1669, TorznabCatType.TVDocumentary, "            World of Tomorrow");
+            AddCategoryMapping(1670, TorznabCatType.TVDocumentary, "            Jacques Cousteau Odyssey");
+            AddCategoryMapping(1671, TorznabCatType.TVDocumentary, "            Secrets and Mysteries");
+            AddCategoryMapping(1672, TorznabCatType.TVDocumentary, "         History");
+            AddCategoryMapping(1092, TorznabCatType.TVDocumentary, "            History: Ancient World / Antiquity / Middle Ages (video)");
+            AddCategoryMapping(1093, TorznabCatType.TVDocumentary, "            History: modern and contemporary times");
+            AddCategoryMapping(1673, TorznabCatType.TVDocumentary, "         Relax, landscape film");
+            AddCategoryMapping(1100, TorznabCatType.TVDocumentary, "         Miscellaneous / nekonditsiya (documentary and transfer)");
+            AddCategoryMapping(569, TorznabCatType.TV, "      Entertaining TV programs and shows, fun and humor");
+            AddCategoryMapping(1101, TorznabCatType.TV, "         Mind games and quizzes");
+            AddCategoryMapping(1102, TorznabCatType.TV, "         Reality and talk show host / category / impressions");
+            AddCategoryMapping(1103, TorznabCatType.TV, "         children's TV Shows");
+            AddCategoryMapping(1104, TorznabCatType.TV, "         KVN");
+            AddCategoryMapping(1105, TorznabCatType.TV, "         Drink Post");
+            AddCategoryMapping(1106, TorznabCatType.TV, "         Distorting Mirror / town / in the town");
+            AddCategoryMapping(1107, TorznabCatType.TV, "         ice show");
+            AddCategoryMapping(1108, TorznabCatType.TV, "         Thank God you came!");
+            AddCategoryMapping(1109, TorznabCatType.TV, "         dinner Party");
+            AddCategoryMapping(1110, TorznabCatType.TV, "         Good jokes");
+            AddCategoryMapping(1111, TorznabCatType.TV, "         Evening Quarter");
+            AddCategoryMapping(1112, TorznabCatType.TV, "         Films with a funny transfer (parody)");
+            AddCategoryMapping(1113, TorznabCatType.TV, "         Stand-up comedy");
+            AddCategoryMapping(1114, TorznabCatType.TV, "         Moment of glory");
+            AddCategoryMapping(1115, TorznabCatType.TV, "         Ukrainian Show");
+            AddCategoryMapping(1116, TorznabCatType.TV, "         Star Factory");
+            AddCategoryMapping(1117, TorznabCatType.TV, "         Dance shows, concerts, performances");
+            AddCategoryMapping(1118, TorznabCatType.TV, "         Circus");
+            AddCategoryMapping(1119, TorznabCatType.TV, "         School for Scandal");
+            AddCategoryMapping(1120, TorznabCatType.TV, "         Satirists and humorists");
+            AddCategoryMapping(1873, TorznabCatType.TV, "         Musical show");
+            AddCategoryMapping(1121, TorznabCatType.TV, "         Humorous audio transmission");
+            AddCategoryMapping(1122, TorznabCatType.TV, "         Audio and video clips (Jokes and humor)");
+            AddCategoryMapping(32, TorznabCatType.Movies, "   Foreign movies");
+            AddCategoryMapping(567, TorznabCatType.Movies, "      Foreign films 2016");
+            AddCategoryMapping(37, TorznabCatType.Movies, "      Foreign films 2011 - 2015 the year");
+            AddCategoryMapping(38, TorznabCatType.Movies, "      Foreign films of the year 2006-2010");
+            AddCategoryMapping(39, TorznabCatType.Movies, "      Foreign films of the year 2001-2005");
+            AddCategoryMapping(40, TorznabCatType.Movies, "      Foreign films 1991-2000");
+            AddCategoryMapping(1031, TorznabCatType.Movies, "      Foreign films until 1990");
+            AddCategoryMapping(41, TorznabCatType.Movies, "      Classic foreign film");
+            AddCategoryMapping(1044, TorznabCatType.Movies, "         Classic foreign film (DVD Video)");
+            AddCategoryMapping(1042, TorznabCatType.Movies, "         Classic foreign film (HD Video)");
+            AddCategoryMapping(1051, TorznabCatType.Movies, "      Foreign films (DVD)");
+            AddCategoryMapping(43, TorznabCatType.Movies, "      Foreign films (HD Video)");
+            AddCategoryMapping(773, TorznabCatType.Movies, "      Grindhouse");
+            AddCategoryMapping(1040, TorznabCatType.Movies, "         Grindhouse DVD and HD Video");
+            AddCategoryMapping(913, TorznabCatType.Movies, "      Asian movies");
+            AddCategoryMapping(1010, TorznabCatType.MoviesSD, "         Asian movies (DVD Video)");
+            AddCategoryMapping(1052, TorznabCatType.MoviesHD, "         Asian films (HD Video)");
+            AddCategoryMapping(1032, TorznabCatType.Movies, "      Indian film");
+            AddCategoryMapping(1043, TorznabCatType.Movies, "         Indian Cinema DVD and HD Video");
+            AddCategoryMapping(1039, TorznabCatType.Movies, "      Shorts");
+            AddCategoryMapping(1041, TorznabCatType.Movies, "      Sound track and Translations");
+            AddCategoryMapping(1804, TorznabCatType.Movies, "      Foreign films without translation");
+            AddCategoryMapping(1805, TorznabCatType.Movies, "         Foreign films in the original");
+            AddCategoryMapping(1806, TorznabCatType.Movies, "            Foreign films in the original (HD)");
+            AddCategoryMapping(1807, TorznabCatType.Movies, "         Foreign films with translation into other languages");
+            AddCategoryMapping(33, TorznabCatType.Movies, "   national cinema");
+            AddCategoryMapping(568, TorznabCatType.Movies, "      Domestic films 2016");
+            AddCategoryMapping(44, TorznabCatType.Movies, "      Domestic films of 2011 - 2015 the year");
+            AddCategoryMapping(45, TorznabCatType.Movies, "      Domestic films of the year 2006-2010");
+            AddCategoryMapping(46, TorznabCatType.Movies, "      Domestic films of the year 2001-2005");
+            AddCategoryMapping(47, TorznabCatType.Movies, "      Domestic films of the year 1992-2000");
+            AddCategoryMapping(48, TorznabCatType.Movies, "      Cinema of the USSR, Soviet Russia, the Russian republic (1917-1991)");
+            AddCategoryMapping(1609, TorznabCatType.Movies, "      Films of the Russian Empire (until 1917)");
+            AddCategoryMapping(1048, TorznabCatType.Movies, "      National cinema (DVD)");
+            AddCategoryMapping(49, TorznabCatType.Movies, "      National cinema (HD Video)");
+            AddCategoryMapping(1046, TorznabCatType.Movies, "      Author debuts");
+            AddCategoryMapping(1047, TorznabCatType.Movies, "      Child domestic films");
+            AddCategoryMapping(1011, TorznabCatType.Movies, "   Art-house cinema and author");
+            AddCategoryMapping(1012, TorznabCatType.Movies, "      Art-house and auteur cinema (DVD)");
+            AddCategoryMapping(1038, TorznabCatType.Movies, "      Art-house and auteur cinema (HD Video)");
+            AddCategoryMapping(1033, TorznabCatType.Movies, "      Author cinema");
+            AddCategoryMapping(1035, TorznabCatType.Movies, "      Shorts (Art-house cinema and author)");
+            AddCategoryMapping(1036, TorznabCatType.Movies, "      Documentaries (Art-house cinema and author)");
+            AddCategoryMapping(1037, TorznabCatType.Movies, "      Animation (Art-house cinema and author)");
+            AddCategoryMapping(1617, TorznabCatType.Movies, "      Intelligent movie");
+            AddCategoryMapping(34, TorznabCatType.TV, "   TV series");
+            AddCategoryMapping(51, TorznabCatType.TV, "      Domestic series");
+            AddCategoryMapping(1860, TorznabCatType.TV, "         Domestic series 2016");
+            AddCategoryMapping(1810, TorznabCatType.TV, "         Domestic series 2015");
+            AddCategoryMapping(574, TorznabCatType.TV, "         Domestic series 2014");
+            AddCategoryMapping(50, TorznabCatType.TV, "      Foreign TV series");
+            AddCategoryMapping(1861, TorznabCatType.TV, "         Foreign series 2016");
+            AddCategoryMapping(1809, TorznabCatType.TV, "         Foreign series 2015");
+            AddCategoryMapping(575, TorznabCatType.TV, "         Foreign series 2014");
+            AddCategoryMapping(1181, TorznabCatType.TV, "         Foreign TV shows (HD Video)");
+            AddCategoryMapping(1184, TorznabCatType.TV, "         Soaps Spain, Italy, Latin America, Turkey and India");
+            AddCategoryMapping(1185, TorznabCatType.TV, "            Indian series");
+            AddCategoryMapping(1186, TorznabCatType.TV, "            spanish series");
+            AddCategoryMapping(1187, TorznabCatType.TV, "            Italian TV series");
+            AddCategoryMapping(1615, TorznabCatType.TV, "            Latin American soap operas");
+            AddCategoryMapping(1189, TorznabCatType.TV, "               Official short version Latin American serials");
+            AddCategoryMapping(1190, TorznabCatType.TV, "               Latin American soap operas with the voice acting (folders distribution)");
+            AddCategoryMapping(1191, TorznabCatType.TV, "               Latin American serials with subtitles");
+            AddCategoryMapping(1188, TorznabCatType.TV, "            turkish TV series");
+            AddCategoryMapping(1192, TorznabCatType.TV, "            Serials OST Spain, Italy, Latin America, Turkey and India");
+            AddCategoryMapping(1193, TorznabCatType.TV, "            For sub-standard hands");
+            AddCategoryMapping(1194, TorznabCatType.TV, "         Asian series");
+            AddCategoryMapping(1195, TorznabCatType.TV, "            Chinese serials with subtitles");
+            AddCategoryMapping(1196, TorznabCatType.TV, "            Korean soap operas with the voice acting");
+            AddCategoryMapping(1197, TorznabCatType.TV, "            Korean serials with subtitles");
+            AddCategoryMapping(1198, TorznabCatType.TV, "            Other Asian series with the voice acting");
+            AddCategoryMapping(1199, TorznabCatType.TV, "            Taiwanese serials with subtitles");
+            AddCategoryMapping(1200, TorznabCatType.TV, "            Japanese serials with subtitles");
+            AddCategoryMapping(1201, TorznabCatType.TV, "            Japanese TV series with the voice acting");
+            AddCategoryMapping(1202, TorznabCatType.TV, "            VMV and others. Videos");
+            AddCategoryMapping(1203, TorznabCatType.TV, "            OST Asian series");
+            AddCategoryMapping(1616, TorznabCatType.TV, "         Soaps with Ukrainian sound track");
+            AddCategoryMapping(1049, TorznabCatType.TV, "   Theater");
+            AddCategoryMapping(1050, TorznabCatType.TV, "      Benefit. Master of Arts of Russian theater and cinema.");
+            AddCategoryMapping(1053, TorznabCatType.Movies3D, "   3D / Stereo (Cinema, Animation, Video, TV &amp; Sports)");
+            AddCategoryMapping(1054, TorznabCatType.Movies3D, "      3D Movies");
+            AddCategoryMapping(581, TorznabCatType.Movies3D, "         Foreign Movies 3D");
+            AddCategoryMapping(1614, TorznabCatType.Movies3D, "            Asian Movies 3D");
+            AddCategoryMapping(1613, TorznabCatType.Movies3D, "         Domestic 3D Movies");
+            AddCategoryMapping(586, TorznabCatType.Movies3D, "      3D Animation");
+            AddCategoryMapping(1055, TorznabCatType.Movies3D, "      3D Documentaries");
+            AddCategoryMapping(1056, TorznabCatType.Movies3D, "      3D Sports");
+            AddCategoryMapping(1057, TorznabCatType.Movies3D, "      3D Clips, Music Videos, Movie Trailers");
+            AddCategoryMapping(53, TorznabCatType.TVAnime, "   Animation and cartoons");
+            AddCategoryMapping(341, TorznabCatType.TVAnime, "      Foreign cartoons");
+            AddCategoryMapping(344, TorznabCatType.TVAnime, "         Foreign cartoons (DVD)");
+            AddCategoryMapping(342, TorznabCatType.TVAnime, "      Domestic cartoons");
+            AddCategoryMapping(1062, TorznabCatType.TVAnime, "         Domestic full-length cartoons");
+            AddCategoryMapping(1061, TorznabCatType.TVAnime, "         Domestic cartoons (DVD)");
+            AddCategoryMapping(346, TorznabCatType.TVAnime, "      short cartoons");
+            AddCategoryMapping(1058, TorznabCatType.TVAnime, "         Short Film (HD Video)");
+            AddCategoryMapping(1060, TorznabCatType.TVAnime, "         Foreign short cartoons");
+            AddCategoryMapping(1059, TorznabCatType.TVAnime, "         Foreign Short Film (DVD)");
+            AddCategoryMapping(345, TorznabCatType.TVAnime, "      Cartoons HD-Video");
+            AddCategoryMapping(1063, TorznabCatType.TVAnime, "      cartoon Puzzle");
+            AddCategoryMapping(343, TorznabCatType.TVAnime, "      Serial cartoons");
+            AddCategoryMapping(1813, TorznabCatType.TVAnime, "      Cartoons and cartoons without translation");
+            AddCategoryMapping(1814, TorznabCatType.TVAnime, "         Cartoons and cartoons with the Ukrainian sound track");
+            AddCategoryMapping(1064, TorznabCatType.TVAnime, "      Archive and nekonditsiya cartoons and animated series");
+            AddCategoryMapping(54, TorznabCatType.TVAnime, "   Anime and everything associated with him");
+            AddCategoryMapping(55, TorznabCatType.TVAnime, "      Anime (Main)");
+            AddCategoryMapping(976, TorznabCatType.TVAnime, "      Anime (pleerny subsection)");
+            AddCategoryMapping(977, TorznabCatType.TVAnime, "      Anime (QC subsection)");
+            AddCategoryMapping(333, TorznabCatType.TVAnime, "      Anime DVD-Video");
+            AddCategoryMapping(334, TorznabCatType.TVAnime, "      Anime (HD and Blu-ray)");
+            AddCategoryMapping(1815, TorznabCatType.TVAnime, "      OST to Anime");
+            AddCategoryMapping(979, TorznabCatType.TVAnime, "         Anime OST to (lossless)");
+            AddCategoryMapping(335, TorznabCatType.TVAnime, "         OST to Anime (mp3 and others lossy-format)");
+            AddCategoryMapping(336, TorznabCatType.TVAnime, "      Manga and other art");
+            AddCategoryMapping(474, TorznabCatType.TVAnime, "         Manga");
+            AddCategoryMapping(680, TorznabCatType.TVAnime, "         Wallpapers, artbook, and others.");
+            AddCategoryMapping(60, TorznabCatType.TVAnime, "      Anime (Hentai)");
+            AddCategoryMapping(978, TorznabCatType.TVAnime, "      AMV etc. Videos");
+            AddCategoryMapping(980, TorznabCatType.TVAnime, "      Japanese cartoons");
+            AddCategoryMapping(1065, TorznabCatType.TVAnime, "      Archive and nekonditsiya Anime");
+            AddCategoryMapping(922, TorznabCatType.Movies, "   Faith and Religion (Video)");
+            AddCategoryMapping(1068, TorznabCatType.Movies, "      Islam (video)");
+            AddCategoryMapping(1067, TorznabCatType.Movies, "      Cults and new religious movements (video)");
+            AddCategoryMapping(1066, TorznabCatType.Movies, "      Religions of India, Tibet and East Asia (video)");
+            AddCategoryMapping(923, TorznabCatType.Movies, "      Christianity (video)");
+            AddCategoryMapping(577, TorznabCatType.TVSport, "   Health &amp; Sports (sports tournaments, films and programs etc)");
+            AddCategoryMapping(583, TorznabCatType.TVSport, "      wrestling");
+            AddCategoryMapping(740, TorznabCatType.TVSport, "         Professional Wrestling");
+            AddCategoryMapping(1176, TorznabCatType.TVSport, "         Independent Wrestling");
+            AddCategoryMapping(1177, TorznabCatType.TVSport, "         International Wrestling");
+            AddCategoryMapping(1178, TorznabCatType.TVSport, "         Oldschool Wrestling");
+            AddCategoryMapping(1179, TorznabCatType.TVSport, "         Documentary Wrestling");
+            AddCategoryMapping(677, TorznabCatType.TVSport, "      cycle racing");
+            AddCategoryMapping(724, TorznabCatType.TVSport, "      Tennis");
+            AddCategoryMapping(925, TorznabCatType.TVSport, "      Athletics / Water Sports");
+            AddCategoryMapping(926, TorznabCatType.TVSport, "      motorcycling");
+            AddCategoryMapping(930, TorznabCatType.TVSport, "      Hockey");
+            AddCategoryMapping(1171, TorznabCatType.TVSport, "         Hockey / Bandy");
+            AddCategoryMapping(1172, TorznabCatType.TVSport, "         International hockey tournaments");
+            AddCategoryMapping(1173, TorznabCatType.TVSport, "         KXL");
+            AddCategoryMapping(932, TorznabCatType.TVSport, "         NHL (until 2011/12)");
+            AddCategoryMapping(931, TorznabCatType.TVSport, "         NHL (2013)");
+            AddCategoryMapping(1174, TorznabCatType.TVSport, "         USSR - Canada");
+            AddCategoryMapping(1175, TorznabCatType.TVSport, "         Documentaries and Analysis (hockey)");
+            AddCategoryMapping(1123, TorznabCatType.TVSport, "      Motorsports");
+            AddCategoryMapping(1125, TorznabCatType.TVSport, "      Formula 1");
+            AddCategoryMapping(1126, TorznabCatType.TVSport, "         Formula 1 2012-2015");
+            AddCategoryMapping(1127, TorznabCatType.TVSport, "         Formula January 2016");
+            AddCategoryMapping(1128, TorznabCatType.TVSport, "      Volleyball / Handball");
+            AddCategoryMapping(1129, TorznabCatType.TVSport, "      Billiards");
+            AddCategoryMapping(1130, TorznabCatType.TVSport, "      Poker");
+            AddCategoryMapping(1131, TorznabCatType.TVSport, "      Bodybuilding / Power Sports");
+            AddCategoryMapping(1132, TorznabCatType.TVSport, "      Boxing");
+            AddCategoryMapping(1133, TorznabCatType.TVSport, "      Classic arts");
+            AddCategoryMapping(1134, TorznabCatType.TVSport, "      MMA and K-1");
+            AddCategoryMapping(1135, TorznabCatType.TVSport, "      American football");
+            AddCategoryMapping(1136, TorznabCatType.TVSport, "      Rugby");
+            AddCategoryMapping(1137, TorznabCatType.TVSport, "      Baseball");
+            AddCategoryMapping(1138, TorznabCatType.TVSport, "      Badminton / Table Tennis");
+            AddCategoryMapping(1139, TorznabCatType.TVSport, "      Gymnastics / Dance Competitions");
+            AddCategoryMapping(1140, TorznabCatType.TVSport, "      Winter sports");
+            AddCategoryMapping(1141, TorznabCatType.TVSport, "      Figure skating");
+            AddCategoryMapping(1142, TorznabCatType.TVSport, "      Biathlon");
+            AddCategoryMapping(1143, TorznabCatType.TVSport, "      Extreme sports");
+            AddCategoryMapping(1144, TorznabCatType.TVSport, "      Football");
+            AddCategoryMapping(1146, TorznabCatType.TVSport, "         Russia 2015-2016");
+            AddCategoryMapping(1145, TorznabCatType.TVSport, "         Russia 2014-2015");
+            AddCategoryMapping(1147, TorznabCatType.TVSport, "         Russia / USSR");
+            AddCategoryMapping(1148, TorznabCatType.TVSport, "         England");
+            AddCategoryMapping(1149, TorznabCatType.TVSport, "         Spain");
+            AddCategoryMapping(1150, TorznabCatType.TVSport, "         Italy");
+            AddCategoryMapping(1151, TorznabCatType.TVSport, "         Germany");
+            AddCategoryMapping(1851, TorznabCatType.TVSport, "         France");
+            AddCategoryMapping(1152, TorznabCatType.TVSport, "         Ukraine");
+            AddCategoryMapping(1153, TorznabCatType.TVSport, "         Other national championships and cups");
+            AddCategoryMapping(1154, TorznabCatType.TVSport, "         International football tournaments");
+            AddCategoryMapping(1157, TorznabCatType.TVSport, "         European Cups");
+            AddCategoryMapping(1156, TorznabCatType.TVSport, "            Eurocup 2011-2014");
+            AddCategoryMapping(1155, TorznabCatType.TVSport, "            Eurocup 2014-2015");
+            AddCategoryMapping(1161, TorznabCatType.TVSport, "            Eurocup 2015-2016");
+            AddCategoryMapping(1158, TorznabCatType.TVSport, "         European Championships");
+            AddCategoryMapping(1159, TorznabCatType.TVSport, "            European Championship 2016");
+            AddCategoryMapping(1863, TorznabCatType.TVSport, "               European Championships 2016 (Selection section)");
+            AddCategoryMapping(1864, TorznabCatType.TVSport, "               European Championship 2016 (the final part)");
+            AddCategoryMapping(1160, TorznabCatType.TVSport, "         World Championships");
+            AddCategoryMapping(1852, TorznabCatType.TVSport, "            World Championship 2018");
+            AddCategoryMapping(1162, TorznabCatType.TVSport, "         Friendly tournaments and matches");
+            AddCategoryMapping(1163, TorznabCatType.TVSport, "         The survey and analysis of transmission");
+            AddCategoryMapping(1853, TorznabCatType.TVSport, "            The survey and analytical programs 2014-2016");
+            AddCategoryMapping(1164, TorznabCatType.TVSport, "         Mini Soccer / Football");
+            AddCategoryMapping(1165, TorznabCatType.TVSport, "      Basketball");
+            AddCategoryMapping(1166, TorznabCatType.TVSport, "         International competitions");
+            AddCategoryMapping(1167, TorznabCatType.TVSport, "         NBA / NCAA (until 2000)");
+            AddCategoryMapping(1168, TorznabCatType.TVSport, "         NBA / NCAA (2000-2010 biennium).");
+            AddCategoryMapping(1169, TorznabCatType.TVSport, "         NBA / NCAA (2010-2016 biennium).");
+            AddCategoryMapping(1170, TorznabCatType.TVSport, "         European club basketball");
+            AddCategoryMapping(1885, TorznabCatType.TVSport, "      XXXI Summer Olympic Games. Rio de Janeiro 2016");
+            AddCategoryMapping(1886, TorznabCatType.TVSport, "         Football");
+            AddCategoryMapping(1887, TorznabCatType.TVSport, "         Basketball");
+            AddCategoryMapping(1888, TorznabCatType.TVSport, "         Volleyball / Beach Volleyball / Handball / Water Polo");
+            AddCategoryMapping(1889, TorznabCatType.TVSport, "         Athletics");
+            AddCategoryMapping(1890, TorznabCatType.TVSport, "         Tennis / Table Tennis / Badminton");
+            AddCategoryMapping(1891, TorznabCatType.TVSport, "         Boxing / Martial Arts and Martial Arts / Weightlifting");
+            AddCategoryMapping(1892, TorznabCatType.TVSport, "         Water Sports / Boating");
+            AddCategoryMapping(1893, TorznabCatType.TVSport, "         cycle racing");
+            AddCategoryMapping(1894, TorznabCatType.TVSport, "         Gymnastics");
+            AddCategoryMapping(1895, TorznabCatType.TVSport, "         Other Sports");
+            AddCategoryMapping(1896, TorznabCatType.TVSport, "         The survey and analysis of transmission");
+            AddCategoryMapping(1897, TorznabCatType.Books, "         Books, manuals, periodicals on the Olympic theme");
+            AddCategoryMapping(1575, TorznabCatType.Movies, "   Video for mobile devices");
+            AddCategoryMapping(1576, TorznabCatType.Movies, "      Video for Smartphones and PDAs");
+            AddCategoryMapping(1577, TorznabCatType.Movies, "      Mobile Video (3GP)");
+            AddCategoryMapping(1589, TorznabCatType.Movies, "   Video for Apple devices");
+            AddCategoryMapping(1590, TorznabCatType.Movies, "      Video (Apple)");
+            AddCategoryMapping(1592, TorznabCatType.MoviesSD, "         Movies for iPod, iPhone, iPad");
+            AddCategoryMapping(1593, TorznabCatType.MoviesSD, "         Soaps for iPod, iPhone, iPad");
+            AddCategoryMapping(1594, TorznabCatType.MoviesSD, "         Cartoons to iPod, iPhone, iPad");
+            AddCategoryMapping(1595, TorznabCatType.MoviesSD, "         Anime for iPod, iPhone, iPad");
+            AddCategoryMapping(1596, TorznabCatType.MoviesSD, "         The music video for iPod, iPhone, iPad");
+            AddCategoryMapping(1591, TorznabCatType.MoviesHD, "      Videos HD (Apple)");
+            AddCategoryMapping(1597, TorznabCatType.MoviesHD, "         HD Movies to Apple TV");
+            AddCategoryMapping(1598, TorznabCatType.MoviesHD, "         HD TV Shows on Apple TV");
+            AddCategoryMapping(1599, TorznabCatType.MoviesHD, "         Cartoon HD for Apple TV");
+            AddCategoryMapping(1600, TorznabCatType.MoviesHD, "         Documentary HD video for Apple TV");
+            AddCategoryMapping(1601, TorznabCatType.MoviesHD, "         Music HD video for Apple TV");
+            AddCategoryMapping(1568, TorznabCatType.Movies, "   Trailers and additional materials for films");
+            AddCategoryMapping(1549, TorznabCatType.Movies, "   Video consoles");
+            AddCategoryMapping(1550, TorznabCatType.Movies, "      Video for PSVita");
+            AddCategoryMapping(1551, TorznabCatType.Movies, "      Movies for PSP");
+            AddCategoryMapping(1552, TorznabCatType.Movies, "      for PSP TV Shows");
+            AddCategoryMapping(1553, TorznabCatType.Movies, "      Cartoons for PSP");
+            AddCategoryMapping(1554, TorznabCatType.Movies, "      Drama for PSP");
+            AddCategoryMapping(1555, TorznabCatType.Movies, "      Anime for PSP");
+            AddCategoryMapping(1556, TorznabCatType.Movies, "      Video to PSP");
+            AddCategoryMapping(1557, TorznabCatType.Movies, "      Videos for the PS3 and other consoles");
+            AddCategoryMapping(165, TorznabCatType.Movies, "   video Game");
+            AddCategoryMapping(1544, TorznabCatType.Movies, "      Walkthroughs");
+            AddCategoryMapping(1545, TorznabCatType.Movies, "      Lineage II Movies");
+            AddCategoryMapping(1546, TorznabCatType.Movies, "      World of Warcraft Movies");
+            AddCategoryMapping(1547, TorznabCatType.Movies, "      Counter Strike Movies");
+            AddCategoryMapping(1045, TorznabCatType.Movies, "   Video on moderation");
+            AddCategoryMapping(1607, TorznabCatType.MoviesSD, "      DVD Video on moderation");
+            AddCategoryMapping(1608, TorznabCatType.MoviesHD, "      HD Video on moderation");
+            AddCategoryMapping(1837, TorznabCatType.PCGames, "Releases SE7ENKILLS");
+            AddCategoryMapping(1839, TorznabCatType.PCGames, "   Games");
+            AddCategoryMapping(1840, TorznabCatType.PCGames, "      Patches");
+            AddCategoryMapping(1841, TorznabCatType.PCGames, "   Frequently asked questions about cs: go");
+            AddCategoryMapping(1182, TorznabCatType.PCGames, "Games");
+            AddCategoryMapping(158, TorznabCatType.PCGames, "   Games General Section");
+            AddCategoryMapping(68, TorznabCatType.PCGames, "   Games for PC");
+            AddCategoryMapping(69, TorznabCatType.PCGames, "      Hot New Releases Games");
+            AddCategoryMapping(1030, TorznabCatType.PCGames, "         Games without pills");
+            AddCategoryMapping(70, TorznabCatType.PCGames, "      Action");
+            AddCategoryMapping(148, TorznabCatType.PCGames, "         FPS (1st Person)");
+            AddCategoryMapping(149, TorznabCatType.PCGames, "         TPS (3rd Person)");
+            AddCategoryMapping(150, TorznabCatType.PCGames, "         Stealth Action");
+            AddCategoryMapping(151, TorznabCatType.PCGames, "         Tactical shooter");
+            AddCategoryMapping(71, TorznabCatType.PCGames, "      RPG");
+            AddCategoryMapping(72, TorznabCatType.PCGames, "      Strategy");
+            AddCategoryMapping(152, TorznabCatType.PCGames, "         RTS (real time strategy)");
+            AddCategoryMapping(153, TorznabCatType.PCGames, "         TBS (turn-based strategy)");
+            AddCategoryMapping(154, TorznabCatType.PCGames, "         Wargame");
+            AddCategoryMapping(155, TorznabCatType.PCGames, "         Economic strategies");
+            AddCategoryMapping(73, TorznabCatType.PCGames, "      Simulations");
+            AddCategoryMapping(74, TorznabCatType.PCGames, "         Autos and Racing");
+            AddCategoryMapping(75, TorznabCatType.PCGames, "         Sports simulators");
+            AddCategoryMapping(464, TorznabCatType.PCGames, "         Other simulators");
+            AddCategoryMapping(1531, TorznabCatType.PCGames, "         Space and flight simulators");
+            AddCategoryMapping(76, TorznabCatType.PCGames, "            Aviasimulators");
+            AddCategoryMapping(463, TorznabCatType.PCGames, "            space Simulation");
+            AddCategoryMapping(1540, TorznabCatType.PCGames, "            Microsoft Flight Simulator add-ons, and for him");
+            AddCategoryMapping(1541, TorznabCatType.PCGames, "               Scripts, meshes and airports");
+            AddCategoryMapping(1542, TorznabCatType.PCGames, "               Airplanes and helicopters");
+            AddCategoryMapping(1543, TorznabCatType.PCGames, "               Mission, traffic sounds, packs and tools");
+            AddCategoryMapping(1899, TorznabCatType.PCGames, "               Scenarios (FSX-P3D)");
+            AddCategoryMapping(77, TorznabCatType.PCGames, "      Arcade");
+            AddCategoryMapping(459, TorznabCatType.PCGames, "         Arcade (various)");
+            AddCategoryMapping(461, TorznabCatType.PCGames, "         Board &amp; Card Arcade");
+            AddCategoryMapping(78, TorznabCatType.PCGames, "      Adventure Quests");
+            AddCategoryMapping(746, TorznabCatType.PCGames, "         Quest-style \"search objects\"");
+            AddCategoryMapping(79, TorznabCatType.PCGames, "      Online Games");
+            AddCategoryMapping(743, TorznabCatType.PCGames, "         Free");
+            AddCategoryMapping(744, TorznabCatType.PCGames, "         paid");
+            AddCategoryMapping(742, TorznabCatType.PCGames, "         Other online gaming");
+            AddCategoryMapping(157, TorznabCatType.PCGames, "      For the little ones");
+            AddCategoryMapping(465, TorznabCatType.PCGames, "      Old games for PC");
+            AddCategoryMapping(466, TorznabCatType.PCGames, "         Arcade and Puzzle Games (old games)");
+            AddCategoryMapping(1871, TorznabCatType.PCGames, "            Arcade (Old Games)");
+            AddCategoryMapping(1872, TorznabCatType.PCGames, "            Puzzle games (old games)");
+            AddCategoryMapping(467, TorznabCatType.PCGames, "         Adventure quests (old games)");
+            AddCategoryMapping(468, TorznabCatType.PCGames, "         Action (old games)");
+            AddCategoryMapping(469, TorznabCatType.PCGames, "         Strategy (old games)");
+            AddCategoryMapping(470, TorznabCatType.PCGames, "         RPG (old games)");
+            AddCategoryMapping(471, TorznabCatType.PCGames, "         Simulations (old games)");
+            AddCategoryMapping(1532, TorznabCatType.PCGames, "            Autos and Racing (old games)");
+            AddCategoryMapping(1533, TorznabCatType.PCGames, "            Space simulators, flight simulators and aviaigry (old games)");
+            AddCategoryMapping(1534, TorznabCatType.PCGames, "            Sports simulators (old games)");
+            AddCategoryMapping(1535, TorznabCatType.PCGames, "            Other simulators (Old Games)");
+            AddCategoryMapping(472, TorznabCatType.PCGames, "         Multi-genre compilations (old games)");
+            AddCategoryMapping(1536, TorznabCatType.PCGames, "         Erotic games (old games)");
+            AddCategoryMapping(1537, TorznabCatType.PCGames, "         For the little ones (Old Games)");
+            AddCategoryMapping(1538, TorznabCatType.PCGames, "         Puzzle Games (Old Games)");
+            AddCategoryMapping(1539, TorznabCatType.PCGames, "         IBM PC are not compatible (old games)");
+            AddCategoryMapping(473, TorznabCatType.PCGames, "      Erotic games");
+            AddCategoryMapping(745, TorznabCatType.PCGames, "      Chess");
+            AddCategoryMapping(924, TorznabCatType.PCGames, "      game Collections");
+            AddCategoryMapping(970, TorznabCatType.PCGames, "      Other for PC-games");
+            AddCategoryMapping(1803, TorznabCatType.PCGames, "         Patches");
+            AddCategoryMapping(80, TorznabCatType.PCGames, "            Official patches");
+            AddCategoryMapping(1790, TorznabCatType.PCGames, "         Fashion, plug-ins, add-ons");
+            AddCategoryMapping(972, TorznabCatType.PCGames, "            Official mode, plug-ins, add-ons");
+            AddCategoryMapping(162, TorznabCatType.PCGames, "            Informal fashion, plugins, add-ons");
+            AddCategoryMapping(161, TorznabCatType.PCGames, "         Fun");
+            AddCategoryMapping(973, TorznabCatType.PCGames, "         Editors, emulators and other gaming utility");
+            AddCategoryMapping(160, TorznabCatType.PCGames, "         NoCD / NoDVD");
+            AddCategoryMapping(974, TorznabCatType.PCGames, "         Conservation games");
+            AddCategoryMapping(971, TorznabCatType.PCGames, "         Cheat program and trainers");
+            AddCategoryMapping(164, TorznabCatType.PCGames, "         Guidelines and passing");
+            AddCategoryMapping(163, TorznabCatType.PCGames, "         The bonus disc for the games");
+            AddCategoryMapping(159, TorznabCatType.PCGames, "      The demo version of the game and with early access");
+            AddCategoryMapping(975, TorznabCatType.PCGames, "      Anime Games");
+            AddCategoryMapping(1025, TorznabCatType.PCGames, "      Fighting");
+            AddCategoryMapping(460, TorznabCatType.PCGames, "      Logic games");
+            AddCategoryMapping(462, TorznabCatType.PCGames, "      Mini / Flash games");
+            AddCategoryMapping(1029, TorznabCatType.PCGames, "      Indie Game");
+            AddCategoryMapping(111, TorznabCatType.Console, "   Games for consoles");
+            AddCategoryMapping(458, TorznabCatType.Console, "      Portable and Console Games (general section of games for different platforms)");
+            AddCategoryMapping(129, TorznabCatType.ConsoleXbox, "      Xbox");
+            AddCategoryMapping(131, TorznabCatType.ConsoleXbox360, "         XBox360 | Games");
+            AddCategoryMapping(132, TorznabCatType.ConsoleXbox360, "         XBox360 | GOD Games");
+            AddCategoryMapping(133, TorznabCatType.ConsoleXbox360, "         XBox360 | JTAG");
+            AddCategoryMapping(134, TorznabCatType.ConsoleXbox360, "         XBox360 | 360E");
+            AddCategoryMapping(135, TorznabCatType.ConsoleXbox360, "         XBox360 | Demo");
+            AddCategoryMapping(136, TorznabCatType.ConsoleXbox360, "         XBox360 | Soft");
+            AddCategoryMapping(137, TorznabCatType.ConsoleXbox, "         Original XBox | Games");
+            AddCategoryMapping(138, TorznabCatType.ConsolePS4, "      PlayStation");
+            AddCategoryMapping(621, TorznabCatType.ConsolePS3, "         PS");
+            AddCategoryMapping(141, TorznabCatType.ConsolePS3, "         PS2 | Games");
+            AddCategoryMapping(112, TorznabCatType.ConsolePS3, "         PS3 | Games");
+            AddCategoryMapping(142, TorznabCatType.ConsolePS3, "         PS3 | Other");
+            AddCategoryMapping(139, TorznabCatType.ConsolePS4, "         PSN | Games");
+            AddCategoryMapping(140, TorznabCatType.ConsolePSP, "         PSP | Games");
+            AddCategoryMapping(622, TorznabCatType.ConsolePSP, "         PS1 games for PSP");
+            AddCategoryMapping(143, TorznabCatType.ConsolePSP, "         PSP | Programs | Other");
+            AddCategoryMapping(1548, TorznabCatType.ConsolePSP, "            Software for PSP (Homebrew)");
+            AddCategoryMapping(455, TorznabCatType.ConsolePSVita, "         PS Vita | Games");
+            AddCategoryMapping(130, TorznabCatType.ConsoleOther, "      Nintendo");
+            AddCategoryMapping(144, TorznabCatType.ConsoleNDS, "         NDS | Games");
+            AddCategoryMapping(145, TorznabCatType.ConsoleWii, "         Wii | Games");
+            AddCategoryMapping(146, TorznabCatType.ConsoleWiiwareVC, "         WiiWare | Games");
+            AddCategoryMapping(147, TorznabCatType.ConsoleOther, "         GameCube | Games");
+            AddCategoryMapping(456, TorznabCatType.ConsoleOther, "      Sega");
+            AddCategoryMapping(588, TorznabCatType.ConsoleOther, "         Dreamcast");
+            AddCategoryMapping(457, TorznabCatType.ConsoleOther, "      Games for older consoles");
+            AddCategoryMapping(589, TorznabCatType.ConsoleOther, "      Games for the DVD player");
+            AddCategoryMapping(928, TorznabCatType.PCGames, "   Games for Linux");
+            AddCategoryMapping(1868, TorznabCatType.PCGames, "      Native games for Linux");
+            AddCategoryMapping(1869, TorznabCatType.PCGames, "      Ported games for Linux");
+            AddCategoryMapping(1870, TorznabCatType.PCGames, "      Archive for Linux games");
+            AddCategoryMapping(81, TorznabCatType.PC0day, "Software");
+            AddCategoryMapping(570, TorznabCatType.PC0day, "   General Section for software");
+            AddCategoryMapping(109, TorznabCatType.PCPhoneOther, "   Software for smart phones, mobile phones and PDAs");
+            AddCategoryMapping(899, TorznabCatType.PCPhoneOther, "      Java");
+            AddCategoryMapping(900, TorznabCatType.PCPhoneOther, "         Games for Java");
+            AddCategoryMapping(901, TorznabCatType.PCPhoneOther, "         Applications for Java");
+            AddCategoryMapping(590, TorznabCatType.PCPhoneAndroid, "      Android");
+            AddCategoryMapping(592, TorznabCatType.PCPhoneAndroid, "         Games for Android");
+            AddCategoryMapping(1017, TorznabCatType.PCPhoneAndroid, "            Games for Android [Eng]");
+            AddCategoryMapping(895, TorznabCatType.PCPhoneAndroid, "         Apps for Android OS");
+            AddCategoryMapping(1018, TorznabCatType.PCPhoneAndroid, "            Applications for Android [Eng]");
+            AddCategoryMapping(480, TorznabCatType.PCPhoneIOS, "      Apple Mobile Device Software");
+            AddCategoryMapping(481, TorznabCatType.PCPhoneIOS, "         Firmware (iPhone / iPod Touch / iPad / Apple TV)");
+            AddCategoryMapping(482, TorznabCatType.PCPhoneIOS, "         Programs for iOS (iPhone / iPod Touch / iPad)");
+            AddCategoryMapping(483, TorznabCatType.PCPhoneIOS, "         Games for iOS (iPhone / iPod Touch / iPad)");
+            AddCategoryMapping(485, TorznabCatType.PCPhoneIOS, "         Miscellaneous iOS (iPhone / iPod Touch / iPad)");
+            AddCategoryMapping(896, TorznabCatType.PCPhoneOther, "      Symbian");
+            AddCategoryMapping(897, TorznabCatType.PCPhoneOther, "         Games for Symbian");
+            AddCategoryMapping(898, TorznabCatType.PCPhoneOther, "         Applications for Symbian");
+            AddCategoryMapping(902, TorznabCatType.PCPhoneOther, "      Windows Mobile, Palm OS, BlackBerry etc");
+            AddCategoryMapping(903, TorznabCatType.PCPhoneOther, "         Games for Windows Mobile, Palm OS, BlackBerry etc");
+            AddCategoryMapping(904, TorznabCatType.PCPhoneOther, "         Applications for Windows Mobile, Palm OS, BlackBerry etc");
+            AddCategoryMapping(1579, TorznabCatType.PCPhoneOther, "      Windows Phone 7,8");
+            AddCategoryMapping(1580, TorznabCatType.PCPhoneOther, "         Games for Windows Phone 7,8");
+            AddCategoryMapping(1581, TorznabCatType.PCPhoneOther, "         Applications for Windows Phone 7,8");
+            AddCategoryMapping(1582, TorznabCatType.PCPhoneOther, "      Software for your phone");
+            AddCategoryMapping(1583, TorznabCatType.PCPhoneOther, "      Firmware for phones");
+            AddCategoryMapping(106, TorznabCatType.PC0day, "   On Linux, Unix etc");
+            AddCategoryMapping(282, TorznabCatType.PC0day, "      Operating Systems (Linux, Unix)");
+            AddCategoryMapping(1574, TorznabCatType.PC0day, "      Program (Linux, Unix)");
+            AddCategoryMapping(284, TorznabCatType.PC0day, "      Other operating systems and software for them");
+            AddCategoryMapping(287, TorznabCatType.PC0day, "      Archive (Linux OS, Unix etc)");
+            AddCategoryMapping(276, TorznabCatType.PCMac, "   Apple OS");
+            AddCategoryMapping(277, TorznabCatType.PCMac, "      Mac OS [for Macintosh]");
+            AddCategoryMapping(278, TorznabCatType.PCMac, "      Mac OS [PC-Hackintosh]");
+            AddCategoryMapping(591, TorznabCatType.PCMac, "      Games Mac OS");
+            AddCategoryMapping(1019, TorznabCatType.PCMac, "         Mac Games [ENG]");
+            AddCategoryMapping(1021, TorznabCatType.PCMac, "      Program for viewing and video processing (Mac OS)");
+            AddCategoryMapping(1022, TorznabCatType.PCMac, "      Programs for creating and processing graphs (Mac OS)");
+            AddCategoryMapping(1023, TorznabCatType.PCMac, "      Plug-ins for Adobe's software (Mac OS)");
+            AddCategoryMapping(1584, TorznabCatType.PCMac, "      Audio editor and converter (Mac OS)");
+            AddCategoryMapping(1585, TorznabCatType.PCMac, "      System software (Mac OS)");
+            AddCategoryMapping(1586, TorznabCatType.PCMac, "      Office software (Mac OS)");
+            AddCategoryMapping(1587, TorznabCatType.PCMac, "      Programs for the Internet and network (Mac OS)");
+            AddCategoryMapping(1588, TorznabCatType.PCMac, "      Other software (Mac OS)");
+            AddCategoryMapping(103, TorznabCatType.PC0day, "   Microsoft OS");
+            AddCategoryMapping(104, TorznabCatType.PC0day, "      Desktop operating system from Microsoft (released prior to Windows XP)");
+            AddCategoryMapping(105, TorznabCatType.PC0day, "      Desktop operating system from Microsoft (since Windows XP)");
+            AddCategoryMapping(1629, TorznabCatType.PC0day, "         Windows XP");
+            AddCategoryMapping(1628, TorznabCatType.PC0day, "         Windows Vista");
+            AddCategoryMapping(981, TorznabCatType.PC0day, "         Windows 7");
+            AddCategoryMapping(1610, TorznabCatType.PC0day, "         Windows 8");
+            AddCategoryMapping(1811, TorznabCatType.PC0day, "         Windows 10");
+            AddCategoryMapping(274, TorznabCatType.PC0day, "      Windows Server");
+            AddCategoryMapping(927, TorznabCatType.PC0day, "      Other (Operating Systems from Microsoft)");
+            AddCategoryMapping(275, TorznabCatType.PC0day, "      Archive (OS from Microsoft)");
+            AddCategoryMapping(84, TorznabCatType.PC0day, "   System programs");
+            AddCategoryMapping(86, TorznabCatType.PC0day, "      Programs for configuring and optimizing OS");
+            AddCategoryMapping(87, TorznabCatType.PC0day, "      Archivers and File Managers");
+            AddCategoryMapping(1630, TorznabCatType.PC0day, "      Safety protection system and PC");
+            AddCategoryMapping(93, TorznabCatType.PC0day, "         Software to protect your computer (antivirus software, firewalls)");
+            AddCategoryMapping(580, TorznabCatType.PC0day, "            Keys and Activation");
+            AddCategoryMapping(94, TorznabCatType.PC0day, "         Anti-spyware and anti-trojan");
+            AddCategoryMapping(95, TorznabCatType.PC0day, "         Programs for the protection of information");
+            AddCategoryMapping(88, TorznabCatType.PC0day, "      Backup");
+            AddCategoryMapping(89, TorznabCatType.PC0day, "      Service computer service");
+            AddCategoryMapping(1631, TorznabCatType.PC0day, "         LiveCD / DVD / Flash etc");
+            AddCategoryMapping(90, TorznabCatType.PC0day, "      Work with data carriers");
+            AddCategoryMapping(91, TorznabCatType.PC0day, "      Information and Diagnostics");
+            AddCategoryMapping(92, TorznabCatType.PC0day, "      Programs for Internet and networks");
+            AddCategoryMapping(96, TorznabCatType.PC0day, "      Drivers and Firmware");
+            AddCategoryMapping(97, TorznabCatType.PC0day, "      Original disks to computers and accessories");
+            AddCategoryMapping(98, TorznabCatType.PC0day, "      Server Software for Windows");
+            AddCategoryMapping(99, TorznabCatType.PC0day, "      Change the Windows interface");
+            AddCategoryMapping(101, TorznabCatType.PC0day, "      Screensavers");
+            AddCategoryMapping(85, TorznabCatType.PC0day, "      Work with hard drive");
+            AddCategoryMapping(102, TorznabCatType.PC0day, "      Miscellaneous (System programs on Windows)");
+            AddCategoryMapping(82, TorznabCatType.PC0day, "   Systems for business, office, research and project work");
+            AddCategoryMapping(83, TorznabCatType.PC0day, "      Business Systems");
+            AddCategoryMapping(585, TorznabCatType.PC0day, "         The company's products 1C");
+            AddCategoryMapping(1829, TorznabCatType.PC0day, "            typical configuration");
+            AddCategoryMapping(1830, TorznabCatType.PC0day, "            industry configuration");
+            AddCategoryMapping(1831, TorznabCatType.PC0day, "            ITS 2015");
+            AddCategoryMapping(1832, TorznabCatType.PC0day, "            ITS 2014");
+            AddCategoryMapping(1833, TorznabCatType.PC0day, "            ITS 2013");
+            AddCategoryMapping(1834, TorznabCatType.PC0day, "            ITS 2012");
+            AddCategoryMapping(1835, TorznabCatType.PC0day, "            ITS 2011");
+            AddCategoryMapping(1836, TorznabCatType.PC0day, "            Archive (Products 1C)");
+            AddCategoryMapping(270, TorznabCatType.PC0day, "      Office systems");
+            AddCategoryMapping(266, TorznabCatType.PC0day, "      Dictionaries, translators");
+            AddCategoryMapping(272, TorznabCatType.PC0day, "      Recognition of text, sound and speech synthesis");
+            AddCategoryMapping(269, TorznabCatType.PC0day, "      Miscellaneous (business systems, office, research and project work)");
+            AddCategoryMapping(302, TorznabCatType.PC0day, "      CAD software for architects");
+            AddCategoryMapping(593, TorznabCatType.PC0day, "         CAD (general and engineering)");
+            AddCategoryMapping(594, TorznabCatType.PC0day, "         CAD (electronics, automation, GAP)");
+            AddCategoryMapping(940, TorznabCatType.PC0day, "         Programs for architects and builders");
+            AddCategoryMapping(937, TorznabCatType.PC0day, "      All for house: dressmaking, sewing, cooking");
+            AddCategoryMapping(938, TorznabCatType.PC0day, "      Work with PDF and DjVu");
+            AddCategoryMapping(939, TorznabCatType.PC0day, "      Systems for scientific work");
+            AddCategoryMapping(941, TorznabCatType.PC0day, "      Libraries and projects for architects and interior designers");
+            AddCategoryMapping(942, TorznabCatType.PC0day, "      Other reference systems");
+            AddCategoryMapping(107, TorznabCatType.PC0day, "   Web Development and Programming");
+            AddCategoryMapping(293, TorznabCatType.PC0day, "      Search / Offer");
+            AddCategoryMapping(943, TorznabCatType.PC0day, "      WYSIWYG editors for web design");
+            AddCategoryMapping(496, TorznabCatType.PC0day, "      Database Management Systems (DBMS)");
+            AddCategoryMapping(494, TorznabCatType.PC0day, "      programming environments, compilers and software tools");
+            AddCategoryMapping(290, TorznabCatType.PC0day, "      The components for the development of media");
+            AddCategoryMapping(495, TorznabCatType.PC0day, "      Text editors Illuminated");
+            AddCategoryMapping(291, TorznabCatType.PC0day, "      Scripting engines and websites, CMS and extensions to it");
+            AddCategoryMapping(944, TorznabCatType.PC0day, "      Templates for websites and CMS");
+            AddCategoryMapping(292, TorznabCatType.PC0day, "      Miscellaneous (Web Development and Programming)");
+            AddCategoryMapping(294, TorznabCatType.PC0day, "      Archive (Web Development and Programming)");
+            AddCategoryMapping(108, TorznabCatType.PC0day, "   Programs to work with multimedia and 3D");
+            AddCategoryMapping(487, TorznabCatType.PC0day, "      Software kits");
+            AddCategoryMapping(488, TorznabCatType.PC0day, "      Plug-ins for Adobe's programs");
+            AddCategoryMapping(491, TorznabCatType.PC0day, "      3D modeling, rendering and plugins for them");
+            AddCategoryMapping(489, TorznabCatType.PC0day, "      Graphic editor");
+            AddCategoryMapping(303, TorznabCatType.PC0day, "      Editors video");
+            AddCategoryMapping(305, TorznabCatType.PC0day, "      Virtual Studios, sequencers and audio editor");
+            AddCategoryMapping(492, TorznabCatType.PC0day, "      Animation");
+            AddCategoryMapping(490, TorznabCatType.PC0day, "      Programs for typesetting, printing, and working with fonts");
+            AddCategoryMapping(304, TorznabCatType.PC0day, "      Video, Audio Conversion");
+            AddCategoryMapping(493, TorznabCatType.PC0day, "      Creating a BD / HD / DVD-Video");
+            AddCategoryMapping(306, TorznabCatType.PC0day, "      Plug-ins for sound processing");
+            AddCategoryMapping(308, TorznabCatType.PC0day, "      Archive (Programme for multimedia and 3D)");
+            AddCategoryMapping(595, TorznabCatType.PC0day, "      Miscellaneous (Programme for multimedia and 3D)");
+            AddCategoryMapping(596, TorznabCatType.PC0day, "      Miscellaneous (Programs for working with audio)");
+            AddCategoryMapping(597, TorznabCatType.PC0day, "      Virtual instruments and synthesizers");
+            AddCategoryMapping(264, TorznabCatType.PC0day, "      Audio and video, players and catalogers");
+            AddCategoryMapping(263, TorznabCatType.PC0day, "      Cataloging and graphics viewers");
+            AddCategoryMapping(348, TorznabCatType.PC0day, "   Materials for Multimedia and Design");
+            AddCategoryMapping(945, TorznabCatType.PC0day, "      Author's works");
+            AddCategoryMapping(946, TorznabCatType.PC0day, "      Official collection vector clipart");
+            AddCategoryMapping(948, TorznabCatType.PC0day, "      Other vector cliparts");
+            AddCategoryMapping(949, TorznabCatType.PC0day, "      Photostosks");
+            AddCategoryMapping(950, TorznabCatType.PC0day, "      The costumes for the photomontage");
+            AddCategoryMapping(350, TorznabCatType.PC0day, "      Frames and Vignettes for processing photos");
+            AddCategoryMapping(352, TorznabCatType.PC0day, "      Other raster clipart");
+            AddCategoryMapping(1634, TorznabCatType.PC0day, "         backgrounds");
+            AddCategoryMapping(1635, TorznabCatType.PC0day, "         Templates");
+            AddCategoryMapping(1637, TorznabCatType.PC0day, "         Raster Graphics (photos)");
+            AddCategoryMapping(1638, TorznabCatType.PC0day, "         Raster Graphics (elements)");
+            AddCategoryMapping(1639, TorznabCatType.PC0day, "         Raster Graphics (illustrations)");
+            AddCategoryMapping(353, TorznabCatType.PC0day, "      3D models, scenes and materials");
+            AddCategoryMapping(1633, TorznabCatType.PC0day, "         Textures");
+            AddCategoryMapping(354, TorznabCatType.PC0day, "      Footage");
+            AddCategoryMapping(951, TorznabCatType.PC0day, "      Other collections footage");
+            AddCategoryMapping(952, TorznabCatType.PC0day, "      music library");
+            AddCategoryMapping(355, TorznabCatType.PC0day, "      Sound effects");
+            AddCategoryMapping(953, TorznabCatType.PC0day, "      sample Libraries");
+            AddCategoryMapping(954, TorznabCatType.PC0day, "      Libraries and saundbanki for samplers, synth presets");
+            AddCategoryMapping(955, TorznabCatType.PC0day, "      Multitracks");
+            AddCategoryMapping(956, TorznabCatType.PC0day, "      Materials for creating menus and DVD covers");
+            AddCategoryMapping(351, TorznabCatType.PC0day, "      Styles, brushes, shapes and patterns for Adobe Photoshop");
+            AddCategoryMapping(356, TorznabCatType.PC0day, "      Fonts");
+            AddCategoryMapping(358, TorznabCatType.PC0day, "      Miscellaneous (Materials for Multimedia and Design)");
+            AddCategoryMapping(1632, TorznabCatType.PC0day, "      Digital Juice");
+            AddCategoryMapping(1874, TorznabCatType.PC0day, "      Projects");
+            AddCategoryMapping(1875, TorznabCatType.PC0day, "         Children (projects)");
+            AddCategoryMapping(1876, TorznabCatType.PC0day, "         Wedding and romantic (projects)");
+            AddCategoryMapping(1877, TorznabCatType.PC0day, "         Holiday (projects)");
+            AddCategoryMapping(1878, TorznabCatType.PC0day, "         Presentations (projects)");
+            AddCategoryMapping(1879, TorznabCatType.PC0day, "         Sport (projects)");
+            AddCategoryMapping(1880, TorznabCatType.PC0day, "         Logos (projects)");
+            AddCategoryMapping(1881, TorznabCatType.PC0day, "         Slideshow (projects)");
+            AddCategoryMapping(1882, TorznabCatType.PC0day, "         Titles (projects)");
+            AddCategoryMapping(1883, TorznabCatType.PC0day, "         Items (Projects)");
+            AddCategoryMapping(1884, TorznabCatType.PC0day, "         Miscellaneous (projects)");
+            AddCategoryMapping(1898, TorznabCatType.PC0day, "         Trailers (projects)");
+            AddCategoryMapping(295, TorznabCatType.PC0day, "   Reference and legal system");
+            AddCategoryMapping(296, TorznabCatType.PC0day, "      Consultant Plus");
+            AddCategoryMapping(584, TorznabCatType.PC0day, "         Consultant Accountant");
+            AddCategoryMapping(755, TorznabCatType.PC0day, "         Archive irrelevant hands");
+            AddCategoryMapping(297, TorznabCatType.PC0day, "      code");
+            AddCategoryMapping(298, TorznabCatType.PC0day, "      Guarantee");
+            AddCategoryMapping(299, TorznabCatType.PC0day, "      other");
+            AddCategoryMapping(300, TorznabCatType.PC0day, "      Archive (Reference and legal system)");
+            AddCategoryMapping(301, TorznabCatType.PC0day, "      RG PCA - a hidden forum");
+            AddCategoryMapping(587, TorznabCatType.PC0day, "   Collections of programs and WPI");
+            AddCategoryMapping(929, TorznabCatType.PC0day, "   Test drives to adjust the audio / video equipment");
+            AddCategoryMapping(957, TorznabCatType.PC0day, "   GIS, navigation systems and maps");
+            AddCategoryMapping(958, TorznabCatType.PC0day, "      GIS (Geographic Information Systems)");
+            AddCategoryMapping(959, TorznabCatType.PC0day, "      Maps provided with the program shell");
+            AddCategoryMapping(960, TorznabCatType.PC0day, "      Atlases and maps modern (after 1950)");
+            AddCategoryMapping(961, TorznabCatType.PC0day, "      Atlases and maps of old (pre-1950)");
+            AddCategoryMapping(962, TorznabCatType.PC0day, "      Cards Other (astronomical, historical, thematic)");
+            AddCategoryMapping(963, TorznabCatType.PC0day, "      Built-in car navigation");
+            AddCategoryMapping(964, TorznabCatType.PC0day, "      Garmin");
+            AddCategoryMapping(965, TorznabCatType.PC0day, "      Ozi");
+            AddCategoryMapping(966, TorznabCatType.PC0day, "      TomTom");
+            AddCategoryMapping(967, TorznabCatType.PC0day, "      Navigon / Navitel");
+            AddCategoryMapping(968, TorznabCatType.PC0day, "      Igo");
+            AddCategoryMapping(969, TorznabCatType.PC0day, "      Miscellaneous - navigation and maps");
+            AddCategoryMapping(61, TorznabCatType.Audio, "Music and music videos");
+            AddCategoryMapping(579, TorznabCatType.Audio, "   Total music section");
+            AddCategoryMapping(537, TorznabCatType.AudioVideo, "      General Discussion unsorted music video");
+            AddCategoryMapping(538, TorznabCatType.AudioVideo, "         Music video (HD / DVD)");
+            AddCategoryMapping(544, TorznabCatType.AudioVideo, "         Concert recording");
+            AddCategoryMapping(1781, TorznabCatType.AudioVideo, "            Concerts (DVD)");
+            AddCategoryMapping(1782, TorznabCatType.AudioVideo, "            Concerts (HD)");
+            AddCategoryMapping(1784, TorznabCatType.AudioVideo, "         Opera, Ballet, Musicals");
+            AddCategoryMapping(1785, TorznabCatType.AudioVideo, "         Music videos (transit)");
+            AddCategoryMapping(501, TorznabCatType.AudioLossless, "      unsorted Lossless");
+            AddCategoryMapping(532, TorznabCatType.Audio, "      Multi-channel HD Audio and Music");
+            AddCategoryMapping(533, TorznabCatType.Audio, "         DVD-Audio, SACD, Audio-DVD");
+            AddCategoryMapping(1687, TorznabCatType.Audio, "            DVD-Audio");
+            AddCategoryMapping(1688, TorznabCatType.Audio, "            SACD-R");
+            AddCategoryMapping(534, TorznabCatType.Audio, "         DTS");
+            AddCategoryMapping(535, TorznabCatType.Audio, "         Vinyl-Rip and Hand-Made");
+            AddCategoryMapping(536, TorznabCatType.Audio, "         Hi-Res stereo");
+            AddCategoryMapping(529, TorznabCatType.Audio, "      discography");
+            AddCategoryMapping(530, TorznabCatType.Audio, "         Domestic");
+            AddCategoryMapping(531, TorznabCatType.Audio, "         foreign");
+            AddCategoryMapping(1679, TorznabCatType.Audio, "      Jazz, Blues, Soul (transit)");
+            AddCategoryMapping(1680, TorznabCatType.Audio, "         Jazz (transit lossless)");
+            AddCategoryMapping(1681, TorznabCatType.Audio, "         Jazz (transit lossy)");
+            AddCategoryMapping(1682, TorznabCatType.Audio, "         Blues, Soul (transit lossless)");
+            AddCategoryMapping(1683, TorznabCatType.Audio, "         Blues, Soul (transit lossy)");
+            AddCategoryMapping(525, TorznabCatType.Audio, "         Jazz, Blues, Soul (transit lossless)");
+            AddCategoryMapping(1689, TorznabCatType.Audio, "      Rock, Alternative, Punk, Metal (transit)");
+            AddCategoryMapping(521, TorznabCatType.Audio, "         Rock (transit Lossless)");
+            AddCategoryMapping(1691, TorznabCatType.Audio, "         Rock (transit Lossy)");
+            AddCategoryMapping(1692, TorznabCatType.Audio, "         Alternative, Punk (transit Lossless)");
+            AddCategoryMapping(1693, TorznabCatType.Audio, "         Alternative, Punk (transit Lossy)");
+            AddCategoryMapping(1694, TorznabCatType.Audio, "         Hard Rock (transit Lossless)");
+            AddCategoryMapping(1695, TorznabCatType.Audio, "         Hard Rock (transit Lossy)");
+            AddCategoryMapping(506, TorznabCatType.Audio, "         Metal (transit Lossless)");
+            AddCategoryMapping(1697, TorznabCatType.Audio, "         Metal (transit Lossy)");
+            AddCategoryMapping(1698, TorznabCatType.Audio, "         Russian Rock (transit Lossless)");
+            AddCategoryMapping(1699, TorznabCatType.Audio, "         Russian Rock (transit Lossy)");
+            AddCategoryMapping(1817, TorznabCatType.Audio, "         Rock, Alternative, Punk, Metal (transit Lossless)");
+            AddCategoryMapping(1700, TorznabCatType.Audio, "      Popular music (transit)");
+            AddCategoryMapping(1701, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (transit Lossless)");
+            AddCategoryMapping(1702, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (transit Lossy)");
+            AddCategoryMapping(1703, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (transit Lossless)");
+            AddCategoryMapping(1704, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (transit Lossy)");
+            AddCategoryMapping(1705, TorznabCatType.Audio, "         Patriotic Pop (transit lossless)");
+            AddCategoryMapping(1706, TorznabCatType.Audio, "         Patriotic Pop (transit Lossy)");
+            AddCategoryMapping(1707, TorznabCatType.Audio, "         Soviet stage, Retro (transit Lossless)");
+            AddCategoryMapping(1708, TorznabCatType.Audio, "         Soviet stage, Retro (transit Lossy)");
+            AddCategoryMapping(1709, TorznabCatType.Audio, "         Foreign pop music (transit Lossless)");
+            AddCategoryMapping(1710, TorznabCatType.Audio, "         Foreign pop music (transit Lossy)");
+            AddCategoryMapping(1818, TorznabCatType.Audio, "         Popular music (transit Lossless)");
+            AddCategoryMapping(1711, TorznabCatType.Audio, "      Electronic music (transit)");
+            AddCategoryMapping(1712, TorznabCatType.Audio, "         Trance (transit Lossless)");
+            AddCategoryMapping(1713, TorznabCatType.Audio, "         Trance (transit Lossy)");
+            AddCategoryMapping(1714, TorznabCatType.Audio, "         House, Techno, Electro, Minimal (transit Lossless)");
+            AddCategoryMapping(1715, TorznabCatType.Audio, "         House (transit Lossy)");
+            AddCategoryMapping(1716, TorznabCatType.Audio, "         Techno, Electro, Minimal (transit Lossy)");
+            AddCategoryMapping(1717, TorznabCatType.Audio, "         Easy listening (transit Lossless)");
+            AddCategoryMapping(1718, TorznabCatType.Audio, "         Easy listening (transit Lossy)");
+            AddCategoryMapping(1719, TorznabCatType.Audio, "         Experimental, Industrial, EBM, Dark Electro (Lossless)");
+            AddCategoryMapping(1720, TorznabCatType.Audio, "         Experimental Electronic (transit Lossy)");
+            AddCategoryMapping(1721, TorznabCatType.Audio, "         Industrial, EBM, Dark Electro (transit Lossy)");
+            AddCategoryMapping(1722, TorznabCatType.Audio, "         Synthpop, New Wave (Lossless transit)");
+            AddCategoryMapping(1723, TorznabCatType.Audio, "         Synthpop, New Wave (transit Lossy)");
+            AddCategoryMapping(1724, TorznabCatType.Audio, "         Drum'n'Bass, Jungle, Breaks, Breakbeat, Dubstep (transit Lossless)");
+            AddCategoryMapping(1725, TorznabCatType.Audio, "         Drum'n'Bass, Jungle, Breaks, Breakbeat, Dubstep (transit Lossy)");
+            AddCategoryMapping(1726, TorznabCatType.Audio, "         Hardstyle, Jumpstyle, Hardcore (transit Lossless)");
+            AddCategoryMapping(1727, TorznabCatType.Audio, "         Hardstyle, Jumpstyle, Hardcore (transit Lossy)");
+            AddCategoryMapping(1728, TorznabCatType.Audio, "         Psychedelic, psytrance, fullon (transit Lossless)");
+            AddCategoryMapping(1729, TorznabCatType.Audio, "         Psychedelic, psytrance, fullon (transit Lossy)");
+            AddCategoryMapping(1730, TorznabCatType.Audio, "         Radioshow, Live Mixes (transit Lossy)");
+            AddCategoryMapping(1820, TorznabCatType.Audio, "         Electronic music (transit Lossless)");
+            AddCategoryMapping(1731, TorznabCatType.Audio, "      Rap, Hip-hop, RnB, Reggae (transit)");
+            AddCategoryMapping(1732, TorznabCatType.Audio, "         Rap, Hip-hop overseas (transit Lossless)");
+            AddCategoryMapping(1733, TorznabCatType.Audio, "         Rap, Hip-hop overseas (transit Lossy)");
+            AddCategoryMapping(1734, TorznabCatType.Audio, "         Rap, Hip-hop domestic (Lossless)");
+            AddCategoryMapping(1735, TorznabCatType.Audio, "         Rap, Hip-hop domestic (transit Lossy)");
+            AddCategoryMapping(1736, TorznabCatType.Audio, "         RnB, Reggae (transit Lossless)");
+            AddCategoryMapping(1737, TorznabCatType.Audio, "         RnB, Reggae (transit Lossy)");
+            AddCategoryMapping(1819, TorznabCatType.Audio, "         Rap, Hip-hop, RnB (transit Lossless)");
+            AddCategoryMapping(1738, TorznabCatType.Audio, "      East Asian Music (transit)");
+            AddCategoryMapping(1739, TorznabCatType.Audio, "         Asian Traditional, Ethnic (transit Lossless)");
+            AddCategoryMapping(1740, TorznabCatType.Audio, "         Asian Traditional, Ethnic (transit Lossy)");
+            AddCategoryMapping(1741, TorznabCatType.Audio, "         Asian Pop (transit Lossless)");
+            AddCategoryMapping(1742, TorznabCatType.Audio, "         Asian Pop (transit Lossy)");
+            AddCategoryMapping(1743, TorznabCatType.Audio, "         Asian Rock, Metal (transit Lossless)");
+            AddCategoryMapping(1744, TorznabCatType.Audio, "         Asian Rock, Metal (transit Lossy)");
+            AddCategoryMapping(1745, TorznabCatType.Audio, "         Doujin Music (transit Lossless)");
+            AddCategoryMapping(1746, TorznabCatType.Audio, "         Doujin Music (transit Lossy)");
+            AddCategoryMapping(1747, TorznabCatType.Audio, "         Other Asian (transit Lossless)");
+            AddCategoryMapping(1748, TorznabCatType.Audio, "         Other Asian (transit Lossy)");
+            AddCategoryMapping(1749, TorznabCatType.Audio, "      Other Styles (transit)");
+            AddCategoryMapping(1750, TorznabCatType.Audio, "         Instrumental (transit Lossless)");
+            AddCategoryMapping(1751, TorznabCatType.Audio, "         Instrumental (transit Lossy)");
+            AddCategoryMapping(1752, TorznabCatType.Audio, "         New Age / Meditative / Relax (transit Lossless)");
+            AddCategoryMapping(1753, TorznabCatType.Audio, "         New Age / Meditative / Relax (transit Lossy)");
+            AddCategoryMapping(1754, TorznabCatType.Audio, "         Classical Crossover / Neoclassical (transit Lossless)");
+            AddCategoryMapping(1755, TorznabCatType.Audio, "         Classical Crossover / Neoclassical (transit Lossy)");
+            AddCategoryMapping(1756, TorznabCatType.Audio, "         Folk (transit Lossless)");
+            AddCategoryMapping(1757, TorznabCatType.Audio, "         Folk (transit Lossy)");
+            AddCategoryMapping(1758, TorznabCatType.Audio, "         Other (transit Lossless)");
+            AddCategoryMapping(1759, TorznabCatType.Audio, "         Other (transit Lossy)");
+            AddCategoryMapping(1821, TorznabCatType.Audio, "            Folklore / Folk / Folk / World Music (transit Lossy)");
+            AddCategoryMapping(1822, TorznabCatType.Audio, "            Compilations Folklore / Folk / Folk / World Music (transit Lossy)");
+            AddCategoryMapping(1823, TorznabCatType.Audio, "            Country &amp; Folk (transit Lossy)");
+            AddCategoryMapping(1760, TorznabCatType.Audio, "         OST (transit Lossless)");
+            AddCategoryMapping(1761, TorznabCatType.Audio, "         OST (transit Lossy)");
+            AddCategoryMapping(1762, TorznabCatType.Audio, "      Classic (transit)");
+            AddCategoryMapping(1763, TorznabCatType.Audio, "         Notes (transit)");
+            AddCategoryMapping(1764, TorznabCatType.Audio, "         Complete Works (transit)");
+            AddCategoryMapping(1765, TorznabCatType.Audio, "         Vocals (transit)");
+            AddCategoryMapping(1766, TorznabCatType.Audio, "         Concerts (transit)");
+            AddCategoryMapping(1767, TorznabCatType.Audio, "         Orchestral (transit)");
+            AddCategoryMapping(1768, TorznabCatType.Audio, "         Chamber (transit)");
+            AddCategoryMapping(1769, TorznabCatType.Audio, "         Piano (transit)");
+            AddCategoryMapping(1770, TorznabCatType.Audio, "         Compilations (transit)");
+            AddCategoryMapping(1771, TorznabCatType.Audio, "         In processing (transit)");
+            AddCategoryMapping(1783, TorznabCatType.Audio, "         Classic (transit Lossless)");
+            AddCategoryMapping(1800, TorznabCatType.Audio, "      Author and military songs");
+            AddCategoryMapping(1798, TorznabCatType.Audio, "         Author and war songs (transit Lossless)");
+            AddCategoryMapping(1799, TorznabCatType.Audio, "         Author and war songs (transit Lossy)");
+            AddCategoryMapping(1772, TorznabCatType.Audio, "      Unofficial collections (transit)");
+            AddCategoryMapping(1773, TorznabCatType.Audio, "         Jazz, Blues, Soul (transit collections)");
+            AddCategoryMapping(1774, TorznabCatType.Audio, "         Chanson, Author and war songs (collections transit)");
+            AddCategoryMapping(1775, TorznabCatType.Audio, "         Rock, Alternative, Punk, Metal (collections of transit)");
+            AddCategoryMapping(1776, TorznabCatType.Audio, "         Pop (transit collections)");
+            AddCategoryMapping(1777, TorznabCatType.Audio, "         Electronic (transit collections)");
+            AddCategoryMapping(1778, TorznabCatType.Audio, "         Rap, Hip-hop, RnB, Reggae (transit collections)");
+            AddCategoryMapping(1779, TorznabCatType.Audio, "         Instrumental / New Age / Meditative / Relax (transit collections)");
+            AddCategoryMapping(1780, TorznabCatType.Audio, "         Other (transit collections)");
+            AddCategoryMapping(1816, TorznabCatType.Audio, "      Chanson, Author and war songs (transit)");
+            AddCategoryMapping(1677, TorznabCatType.Audio, "         Chanson, Author and war songs (transit lossless)");
+            AddCategoryMapping(1678, TorznabCatType.Audio, "         Chanson, Author and war songs (transit lossy)");
+            AddCategoryMapping(63, TorznabCatType.Audio, "   Electonic music");
+            AddCategoryMapping(784, TorznabCatType.Audio, "      Chillout, Lounge, Downtempo, Trip-Hop");
+            AddCategoryMapping(785, TorznabCatType.Audio, "         Chillout, Lounge, Downtempo (lossless)");
+            AddCategoryMapping(225, TorznabCatType.Audio, "         Chillout, Lounge, Downtempo (lossy)");
+            AddCategoryMapping(786, TorznabCatType.Audio, "         Nu Jazz, Acid Jazz, Future Jazz (lossless)");
+            AddCategoryMapping(787, TorznabCatType.Audio, "         Nu Jazz, Acid Jazz, Future Jazz (lossy)");
+            AddCategoryMapping(788, TorznabCatType.Audio, "         Trip Hop, Abstract Hip-Hop (lossless)");
+            AddCategoryMapping(789, TorznabCatType.Audio, "         Trip Hop, Abstract Hip-Hop (lossy)");
+            AddCategoryMapping(800, TorznabCatType.Audio, "      Drum &amp; Bass, Jungle, Breakbeat, Dubstep, IDM, Electro");
+            AddCategoryMapping(801, TorznabCatType.Audio, "         Dubstep (lossy)");
+            AddCategoryMapping(224, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (lossy)");
+            AddCategoryMapping(803, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (lossless)");
+            AddCategoryMapping(804, TorznabCatType.Audio, "         Drum &amp; Bass, Jungle (Radioshows, Podcasts, Livesets, Mixes)");
+            AddCategoryMapping(805, TorznabCatType.Audio, "         Breakbeat (lossless)");
+            AddCategoryMapping(806, TorznabCatType.Audio, "         Breakbeat (lossy)");
+            AddCategoryMapping(1517, TorznabCatType.Audio, "         Electro, Electro-Freestyle, Nu Electro (lossless)");
+            AddCategoryMapping(1518, TorznabCatType.Audio, "         Electro, Electro-Freestyle, Nu Electro (lossy)");
+            AddCategoryMapping(1519, TorznabCatType.Audio, "         Dubstep (lossless)");
+            AddCategoryMapping(1520, TorznabCatType.Audio, "         Breakbeat, Dubstep (Radioshows, Podcasts, Livesets, Mixes)");
+            AddCategoryMapping(1521, TorznabCatType.Audio, "         IDM (lossless)");
+            AddCategoryMapping(1522, TorznabCatType.Audio, "         IDM (lossy)");
+            AddCategoryMapping(1523, TorznabCatType.Audio, "         IDM Discography &amp; Collections (lossy)");
+            AddCategoryMapping(227, TorznabCatType.Audio, "      Industrial, Noise, EBM, Dark Electro, Aggrotech, Synthpop, New Wave");
+            AddCategoryMapping(774, TorznabCatType.Audio, "         EBM, Dark Electro, Aggrotech (lossless)");
+            AddCategoryMapping(775, TorznabCatType.Audio, "         EBM, Dark Electro, Aggrotech (lossy)");
+            AddCategoryMapping(776, TorznabCatType.Audio, "         Industrial, Noise (lossless)");
+            AddCategoryMapping(777, TorznabCatType.Audio, "         Industrial, Noise (lossy)");
+            AddCategoryMapping(778, TorznabCatType.Audio, "         Synthpop, New Wave (lossless)");
+            AddCategoryMapping(779, TorznabCatType.Audio, "         Synthpop, New Wave (lossy)");
+            AddCategoryMapping(780, TorznabCatType.Audio, "         Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossless)");
+            AddCategoryMapping(781, TorznabCatType.Audio, "         Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossy)");
+            AddCategoryMapping(752, TorznabCatType.Audio, "      House, Techno, Hardcore, Hardstyle, Jumpstyle");
+            AddCategoryMapping(760, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (lossy)");
+            AddCategoryMapping(759, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (lossless)");
+            AddCategoryMapping(753, TorznabCatType.Audio, "         Hardcore, Hardstyle, Jumpstyle (vinyl, web)");
+            AddCategoryMapping(223, TorznabCatType.Audio, "         House (lossy)");
+            AddCategoryMapping(756, TorznabCatType.Audio, "         House (lossless)");
+            AddCategoryMapping(770, TorznabCatType.Audio, "         House (Radioshow, Podcast, Liveset, Mixes)");
+            AddCategoryMapping(754, TorznabCatType.Audio, "         House (Singles, EPs) (lossy)");
+            AddCategoryMapping(771, TorznabCatType.Audio, "         House (Promorelizy, collections)");
+            AddCategoryMapping(757, TorznabCatType.Audio, "         Techno (lossy)");
+            AddCategoryMapping(758, TorznabCatType.Audio, "         Techno (lossless)");
+            AddCategoryMapping(769, TorznabCatType.Audio, "         Techno (Radioshows, Podcasts, Livesets, Mixes)");
+            AddCategoryMapping(761, TorznabCatType.Audio, "         Techno (Singles, EPs) (lossy)");
+            AddCategoryMapping(790, TorznabCatType.Audio, "      Trance, Goa Trance, Psy-Trance, PsyChill, Ambient Dub");
+            AddCategoryMapping(792, TorznabCatType.Audio, "         Goa Trance, Psy-Trance (lossless)");
+            AddCategoryMapping(793, TorznabCatType.Audio, "         Goa Trance, Psy-Trance (lossy)");
+            AddCategoryMapping(798, TorznabCatType.Audio, "         Goa / Psy-Trance, PsyChill and Ambient Dub (Radioshows, Livesets, Mixes) (lossy)");
+            AddCategoryMapping(791, TorznabCatType.Audio, "         Trance (lossless)");
+            AddCategoryMapping(222, TorznabCatType.Audio, "         Trance (lossy)");
+            AddCategoryMapping(795, TorznabCatType.Audio, "         Trance (Radioshows, Podcasts, Live Sets, Mixes) (lossy)");
+            AddCategoryMapping(794, TorznabCatType.Audio, "         Trance (Singles, EPs) (lossy)");
+            AddCategoryMapping(796, TorznabCatType.Audio, "         PsyChill, Ambient Dub (lossless)");
+            AddCategoryMapping(797, TorznabCatType.Audio, "         PsyChill, Ambient Dub (lossy)");
+            AddCategoryMapping(762, TorznabCatType.Audio, "      Traditional Electronic, Ambient, Modern Classical, Electroacoustic, Experimental");
+            AddCategoryMapping(768, TorznabCatType.Audio, "         8-bit, Chiptune (lossy &amp; lossless)");
+            AddCategoryMapping(679, TorznabCatType.Audio, "         Experimental (lossy)");
+            AddCategoryMapping(764, TorznabCatType.Audio, "         Experimental (lossless)");
+            AddCategoryMapping(767, TorznabCatType.Audio, "         Modern Classical, Electroacoustic (lossy)");
+            AddCategoryMapping(766, TorznabCatType.Audio, "         Modern Classical, Electroacoustic (lossless)");
+            AddCategoryMapping(226, TorznabCatType.Audio, "         Traditional Electronic, Ambient (lossy)");
+            AddCategoryMapping(763, TorznabCatType.Audio, "         Traditional Electronic, Ambient (lossless)");
+            AddCategoryMapping(799, TorznabCatType.Audio, "      Label Packs (lossless)");
+            AddCategoryMapping(802, TorznabCatType.Audio, "      Label packs, Scene packs (lossy)");
+            AddCategoryMapping(782, TorznabCatType.Audio, "      Electronic music (Video, DVD Video / Audio, HD Video, DTS, SACD)");
+            AddCategoryMapping(783, TorznabCatType.Audio, "         Electronic music (own digitization)");
+            AddCategoryMapping(914, TorznabCatType.Audio, "         Electronic music (Video)");
+            AddCategoryMapping(1524, TorznabCatType.Audio, "         Electronic music (Official DVD Video)");
+            AddCategoryMapping(1525, TorznabCatType.Audio, "         Electronic music (Informal amateur DVD Video)");
+            AddCategoryMapping(1526, TorznabCatType.Audio, "         Electronic Music (Hi-Res stereo)");
+            AddCategoryMapping(1527, TorznabCatType.Audio, "         Multichannel music (Electronics)");
+            AddCategoryMapping(1528, TorznabCatType.Audio, "         Electronic music (HD Video)");
+            AddCategoryMapping(64, TorznabCatType.Audio, "   Rap, Hip-Hop, R'n'B");
+            AddCategoryMapping(213, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (lossy)");
+            AddCategoryMapping(214, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop (lossy)");
+            AddCategoryMapping(692, TorznabCatType.Audio, "      Foreign R'n'B (lossy)");
+            AddCategoryMapping(894, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (lossless)");
+            AddCategoryMapping(1387, TorznabCatType.Audio, "      Minus (Instrumentals)");
+            AddCategoryMapping(1388, TorznabCatType.Audio, "      Domestic R'n'B (lossy)");
+            AddCategoryMapping(1389, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop, R'n'B (lossless)");
+            AddCategoryMapping(1390, TorznabCatType.Audio, "      Domestic Rap, Hip-Hop (Video)");
+            AddCategoryMapping(1391, TorznabCatType.Audio, "      Domestic R'n'B (Video)");
+            AddCategoryMapping(1392, TorznabCatType.Audio, "      Foreign R'n'B (lossless)");
+            AddCategoryMapping(1393, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (own digitization)");
+            AddCategoryMapping(1394, TorznabCatType.Audio, "      Foreign Rap, Hip-Hop (Video)");
+            AddCategoryMapping(1395, TorznabCatType.Audio, "      Foreign R'n'B (Video)");
+            AddCategoryMapping(1396, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (DVD Video)");
+            AddCategoryMapping(1397, TorznabCatType.Audio, "      Rap, Hip-Hop, R'n'B (HD Video)");
+            AddCategoryMapping(65, TorznabCatType.Audio, "   Pop music");
+            AddCategoryMapping(196, TorznabCatType.Audio, "      International Pop Music");
+            AddCategoryMapping(689, TorznabCatType.Audio, "         Foreign pop music (lossy)");
+            AddCategoryMapping(712, TorznabCatType.Audio, "         Foreign pop music (lossless)");
+            AddCategoryMapping(1429, TorznabCatType.Audio, "         Foreign pop music (collections) (lossy)");
+            AddCategoryMapping(711, TorznabCatType.Audio, "         East Asian pop music (lossy)");
+            AddCategoryMapping(1432, TorznabCatType.Audio, "         East Asian pop music (lossless)");
+            AddCategoryMapping(879, TorznabCatType.Audio, "      Domestic Pop");
+            AddCategoryMapping(197, TorznabCatType.Audio, "         Patriotic Pop (lossy)");
+            AddCategoryMapping(1425, TorznabCatType.Audio, "         Patriotic Pop (lossless)");
+            AddCategoryMapping(1426, TorznabCatType.Audio, "         Patriotic Pop music (collections) (lossy)");
+            AddCategoryMapping(1427, TorznabCatType.Audio, "         Soviet stage, Retro (lossy)");
+            AddCategoryMapping(1428, TorznabCatType.Audio, "         Soviet stage, Retro (lossless)");
+            AddCategoryMapping(198, TorznabCatType.Audio, "      Eurodance, Disco, Hi-NRG");
+            AddCategoryMapping(703, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (lossy)");
+            AddCategoryMapping(877, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (lossless)");
+            AddCategoryMapping(199, TorznabCatType.Audio, "         Eurodance, Euro-House, Technopop (collections) (lossy)");
+            AddCategoryMapping(704, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossy)");
+            AddCategoryMapping(878, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossless)");
+            AddCategoryMapping(1433, TorznabCatType.Audio, "         Disco, Italo-Disco, Euro-Disco, Hi-NRG (collections) (lossy)");
+            AddCategoryMapping(1434, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Pop)");
+            AddCategoryMapping(1435, TorznabCatType.Audio, "         Patriotic Pop (Video)");
+            AddCategoryMapping(1436, TorznabCatType.Audio, "         Patriotic Pop (DVD Video)");
+            AddCategoryMapping(1437, TorznabCatType.Audio, "         Soviet stage, Retro (video)");
+            AddCategoryMapping(1438, TorznabCatType.Audio, "         Soviet stage, Retro (DVD Video)");
+            AddCategoryMapping(1439, TorznabCatType.Audio, "         Foreign pop music (Video)");
+            AddCategoryMapping(1440, TorznabCatType.Audio, "         Foreign pop music (DVD Video)");
+            AddCategoryMapping(1441, TorznabCatType.Audio, "         Eurodance, Disco (video)");
+            AddCategoryMapping(1442, TorznabCatType.Audio, "         Eurodance, Disco (DVD Video)");
+            AddCategoryMapping(1443, TorznabCatType.Audio, "         East Asian pop music (Video)");
+            AddCategoryMapping(1444, TorznabCatType.Audio, "         East Asian pop music (DVD Video)");
+            AddCategoryMapping(1447, TorznabCatType.Audio, "         Patriotic Pop (National concerts, Doc. Video) (Video and DVD)");
+            AddCategoryMapping(1448, TorznabCatType.Audio, "         Foreign pop music (National concerts, Doc. Video) (Video and DVD)");
+            AddCategoryMapping(1449, TorznabCatType.Audio, "         International Pop Music, Chanson, Eurodance, Disco (HD Video)");
+            AddCategoryMapping(1450, TorznabCatType.Audio, "         Patriotic Pop Music, Chanson, Eurodance, Disco (HD Video)");
+            AddCategoryMapping(1451, TorznabCatType.Audio, "      The multi-channel music and own digitization (pop music)");
+            AddCategoryMapping(1452, TorznabCatType.Audio, "         Foreign pop music (own digitization)");
+            AddCategoryMapping(1453, TorznabCatType.Audio, "         Eastern pop music (own digitization)");
+            AddCategoryMapping(1454, TorznabCatType.Audio, "         Patriotic Pop (own digitization)");
+            AddCategoryMapping(1455, TorznabCatType.Audio, "         Instrumental Pop (own digitization)");
+            AddCategoryMapping(1456, TorznabCatType.Audio, "         Multichannel music (pop music)");
+            AddCategoryMapping(1457, TorznabCatType.Audio, "         Foreign pop music (Hi-Res stereo)");
+            AddCategoryMapping(66, TorznabCatType.Audio, "   Soundtracks, Karaoke and Minus");
+            AddCategoryMapping(917, TorznabCatType.Audio, "      The arrangements of music from the game (lossy and lossless)");
+            AddCategoryMapping(1400, TorznabCatType.Audio, "      Minus (lossy and lossless)");
+            AddCategoryMapping(1824, TorznabCatType.Audio, "      Soundtracks");
+            AddCategoryMapping(232, TorznabCatType.Audio, "         Soundtracks to movies and cartoons (mp3)");
+            AddCategoryMapping(234, TorznabCatType.Audio, "         Soundtracks for games (lossy)");
+            AddCategoryMapping(693, TorznabCatType.Audio, "         Soundtracks to foreign films (lossy)");
+            AddCategoryMapping(880, TorznabCatType.Audio, "         Soundtracks to foreign films (lossless)");
+            AddCategoryMapping(915, TorznabCatType.Audio, "         Soundtracks for games (lossless)");
+            AddCategoryMapping(916, TorznabCatType.Audio, "         Informal soundtracks for games (lossy)");
+            AddCategoryMapping(918, TorznabCatType.Audio, "         Informal soundtracks for films and TV series (lossy)");
+            AddCategoryMapping(919, TorznabCatType.Audio, "         Soundtracks for domestic films (lossy)");
+            AddCategoryMapping(920, TorznabCatType.Audio, "         Soundtracks for domestic films (lossless)");
+            AddCategoryMapping(921, TorznabCatType.Audio, "         Soundtracks (own digitization)");
+            AddCategoryMapping(1825, TorznabCatType.Audio, "      Karaoke");
+            AddCategoryMapping(1398, TorznabCatType.Audio, "         Karaoke (Audio)");
+            AddCategoryMapping(1399, TorznabCatType.Audio, "         Karaoke (Video)");
+            AddCategoryMapping(67, TorznabCatType.Audio, "   Music of other genres");
+            AddCategoryMapping(694, TorznabCatType.Audio, "      Proper sampling (music of other genres)");
+            AddCategoryMapping(695, TorznabCatType.Audio, "      Patriotic music of other genres (lossy)");
+            AddCategoryMapping(696, TorznabCatType.Audio, "      Patriotic music of other genres (lossless)");
+            AddCategoryMapping(697, TorznabCatType.Audio, "      Foreign music of other genres (lossy)");
+            AddCategoryMapping(1408, TorznabCatType.Audio, "      Foreign music of other genres (lossless)");
+            AddCategoryMapping(1409, TorznabCatType.Audio, "      Music for ballroom dancing (lossy and lossless)");
+            AddCategoryMapping(1410, TorznabCatType.Audio, "      Orthodox chants (lossy)");
+            AddCategoryMapping(1411, TorznabCatType.Audio, "      Orthodox chants (lossless)");
+            AddCategoryMapping(1412, TorznabCatType.Audio, "      A collection of songs for children (lossy and lossless)");
+            AddCategoryMapping(1686, TorznabCatType.Audio, "         Classics for mothers and babies");
+            AddCategoryMapping(1413, TorznabCatType.Audio, "      Video (Music from other genres)");
+            AddCategoryMapping(1414, TorznabCatType.Audio, "      DVD Video (Music from other genres)");
+            AddCategoryMapping(1415, TorznabCatType.Audio, "      Musical (lossy and lossless)");
+            AddCategoryMapping(1416, TorznabCatType.Audio, "      Musical (Video and DVD Video)");
+            AddCategoryMapping(1417, TorznabCatType.Audio, "      Informal and vnezhanrovye collections (lossy)");
+            AddCategoryMapping(172, TorznabCatType.Audio, "   Classical and contemporary academic music");
+            AddCategoryMapping(705, TorznabCatType.Audio, "      Vocal music (lossless)");
+            AddCategoryMapping(706, TorznabCatType.Audio, "      Orchestral music (lossless)");
+            AddCategoryMapping(707, TorznabCatType.Audio, "      Concerto for instrument and orchestra (lossless)");
+            AddCategoryMapping(708, TorznabCatType.Audio, "      Chamber instrumental music (lossless)");
+            AddCategoryMapping(709, TorznabCatType.Audio, "      Solo instrumental music (lossless)");
+            AddCategoryMapping(710, TorznabCatType.Audio, "      Vocal and choral music (lossy)");
+            AddCategoryMapping(1001, TorznabCatType.Audio, "      Proper digitization (Classical Music)");
+            AddCategoryMapping(1002, TorznabCatType.Audio, "      Multichannel music (Classic and classic with a modern twist)");
+            AddCategoryMapping(1003, TorznabCatType.Audio, "      Classic and classic in modern processing (Hi-Res stereo)");
+            AddCategoryMapping(1008, TorznabCatType.Audio, "      Classical Music (Video)");
+            AddCategoryMapping(1009, TorznabCatType.Audio, "      Classical Music (DVD and HD Video)");
+            AddCategoryMapping(1362, TorznabCatType.Audio, "      Opera (Video)");
+            AddCategoryMapping(1363, TorznabCatType.Audio, "      Opera (DVD and HD Video)");
+            AddCategoryMapping(1364, TorznabCatType.Audio, "      Ballet and modern choreography (Video, DVD and HD Video)");
+            AddCategoryMapping(1365, TorznabCatType.Audio, "      The complete collection of works and multi-disc edition (lossless)");
+            AddCategoryMapping(1366, TorznabCatType.Audio, "      Opera (lossless)");
+            AddCategoryMapping(1367, TorznabCatType.Audio, "      Choral music (lossless)");
+            AddCategoryMapping(1368, TorznabCatType.Audio, "      The complete collection of works and multi-disc edition (lossy)");
+            AddCategoryMapping(1369, TorznabCatType.Audio, "      Orchestral music (lossy)");
+            AddCategoryMapping(1370, TorznabCatType.Audio, "      Chamber and solo instrumental music (lossy)");
+            AddCategoryMapping(1371, TorznabCatType.Audio, "      Classics in modern processing, Classical Crossover (lossy and lossless)");
+            AddCategoryMapping(175, TorznabCatType.Audio, "   Jazz, Blues");
+            AddCategoryMapping(178, TorznabCatType.Audio, "      foreign Jazz");
+            AddCategoryMapping(747, TorznabCatType.Audio, "         Avant-Garde Jazz, Free Improvisation (lossless)");
+            AddCategoryMapping(741, TorznabCatType.Audio, "         Bop (lossless)");
+            AddCategoryMapping(842, TorznabCatType.Audio, "         Early Jazz, Swing, Gypsy (lossless)");
+            AddCategoryMapping(847, TorznabCatType.Audio, "         Funk, Soul, R &amp; B (lossless)");
+            AddCategoryMapping(843, TorznabCatType.Audio, "         Jazz Fusion (lossless)");
+            AddCategoryMapping(599, TorznabCatType.Audio, "         Mainstream Jazz, Cool (lossless)");
+            AddCategoryMapping(845, TorznabCatType.Audio, "         Modern Creative, Third Stream (lossless)");
+            AddCategoryMapping(846, TorznabCatType.Audio, "         Smooth, Jazz-Pop (lossless)");
+            AddCategoryMapping(620, TorznabCatType.Audio, "         Vocal Jazz (lossless)");
+            AddCategoryMapping(844, TorznabCatType.Audio, "         World Fusion, Ethnic Jazz (lossless)");
+            AddCategoryMapping(673, TorznabCatType.Audio, "         Foreign jazz (lossy)");
+            AddCategoryMapping(848, TorznabCatType.Audio, "         Collections of foreign jazz (lossless)");
+            AddCategoryMapping(690, TorznabCatType.Audio, "      foreign blues");
+            AddCategoryMapping(839, TorznabCatType.Audio, "         Blues-rock (lossless)");
+            AddCategoryMapping(713, TorznabCatType.Audio, "         Blues (Texas, Chicago, Modern and Others) (lossless)");
+            AddCategoryMapping(840, TorznabCatType.Audio, "         Roots, Pre-War Blues, Early R &amp; B, Gospel (lossless)");
+            AddCategoryMapping(691, TorznabCatType.Audio, "         Foreign blues (lossy)");
+            AddCategoryMapping(841, TorznabCatType.Audio, "         Foreign blues (collections; Tribute VA) (lossless)");
+            AddCategoryMapping(849, TorznabCatType.Audio, "      Domestic jazz and blues");
+            AddCategoryMapping(850, TorznabCatType.Audio, "         Domestic Jazz (lossless)");
+            AddCategoryMapping(851, TorznabCatType.Audio, "         Domestic jazz (lossy)");
+            AddCategoryMapping(853, TorznabCatType.Audio, "         Domestic Blues (lossless)");
+            AddCategoryMapping(854, TorznabCatType.Audio, "         Domestic Blues (lossy)");
+            AddCategoryMapping(1013, TorznabCatType.Audio, "      The multi-channel music and own digitization (Jazz and Blues)");
+            AddCategoryMapping(1014, TorznabCatType.Audio, "         Multichannel music (Jazz and Blues)");
+            AddCategoryMapping(1015, TorznabCatType.Audio, "         Foreign Jazz and Blues (Hi-Res stereo)");
+            AddCategoryMapping(1016, TorznabCatType.Audio, "         Proper digitization (Jazz and Blues)");
+            AddCategoryMapping(1458, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Jazz and Blues)");
+            AddCategoryMapping(1459, TorznabCatType.Audio, "         Jazz and Blues (Video)");
+            AddCategoryMapping(1460, TorznabCatType.Audio, "         Jazz and Blues (DVD Video)");
+            AddCategoryMapping(1461, TorznabCatType.Audio, "         Jazz and Blues (HD Video)");
+            AddCategoryMapping(204, TorznabCatType.Audio, "   New Age, Relax, Meditative &amp; Flamenco");
+            AddCategoryMapping(207, TorznabCatType.Audio, "      NewAge &amp; Meditative (lossy)");
+            AddCategoryMapping(1004, TorznabCatType.Audio, "      NewAge &amp; Meditative (lossless)");
+            AddCategoryMapping(1005, TorznabCatType.Audio, "      Flamenco and acoustic guitar (lossy)");
+            AddCategoryMapping(1006, TorznabCatType.Audio, "      Flamenco and acoustic guitar (lossless)");
+            AddCategoryMapping(1385, TorznabCatType.Audio, "      New Age, Relax, Meditative &amp; Flamenco (Video)");
+            AddCategoryMapping(1386, TorznabCatType.Audio, "      New Age, Relax, Meditative &amp; Flamenco (DVD and HD Video)");
+            AddCategoryMapping(1007, TorznabCatType.Audio, "      Sounds of nature");
+            AddCategoryMapping(701, TorznabCatType.Audio, "   Chanson, Author and military songs");
+            AddCategoryMapping(702, TorznabCatType.Audio, "      Domestic chanson (lossy)");
+            AddCategoryMapping(891, TorznabCatType.Audio, "      Domestic chanson (lossless)");
+            AddCategoryMapping(892, TorznabCatType.Audio, "      Military song (lossy)");
+            AddCategoryMapping(893, TorznabCatType.Audio, "      Chanson (lossy)");
+            AddCategoryMapping(1401, TorznabCatType.Audio, "      Collections domestic chanson (lossy)");
+            AddCategoryMapping(1402, TorznabCatType.Audio, "      Military song (lossless)");
+            AddCategoryMapping(1403, TorznabCatType.Audio, "      Chanson (lossless)");
+            AddCategoryMapping(1404, TorznabCatType.Audio, "      Minstrels and roleviki (lossy and lossless)");
+            AddCategoryMapping(1405, TorznabCatType.Audio, "      Proper digitization (Chanson, and Bards) lossless");
+            AddCategoryMapping(1406, TorznabCatType.Audio, "      Videos (Chanson, and Bards)");
+            AddCategoryMapping(1407, TorznabCatType.Audio, "      DVD Video (Chanson, and Bards)");
+            AddCategoryMapping(1430, TorznabCatType.Audio, "      Foreign chanson (lossy)");
+            AddCategoryMapping(1431, TorznabCatType.Audio, "      Foreign chanson (lossless)");
+            AddCategoryMapping(1445, TorznabCatType.Audio, "      Foreign chanson (Video)");
+            AddCategoryMapping(1446, TorznabCatType.Audio, "      Foreign chanson (DVD Video)");
+            AddCategoryMapping(865, TorznabCatType.Audio, "   Rock music");
+            AddCategoryMapping(62, TorznabCatType.Audio, "      foreign Rock");
+            AddCategoryMapping(859, TorznabCatType.Audio, "         AOR (Melodic Hard Rock, Arena rock) (lossless)");
+            AddCategoryMapping(860, TorznabCatType.Audio, "         AOR (Melodic Hard Rock, Arena rock) (lossy)");
+            AddCategoryMapping(855, TorznabCatType.Audio, "         Classic Rock &amp; Hard Rock (lossless)");
+            AddCategoryMapping(856, TorznabCatType.Audio, "         Classic Rock &amp; Hard Rock (lossy)");
+            AddCategoryMapping(864, TorznabCatType.Audio, "         Instrumental Guitar Rock (lossy)");
+            AddCategoryMapping(1027, TorznabCatType.Audio, "         Instrumental Guitar Rock (lossless)");
+            AddCategoryMapping(858, TorznabCatType.Audio, "         Folk-Rock (lossless)");
+            AddCategoryMapping(675, TorznabCatType.Audio, "         Folk-Rock (lossy)");
+            AddCategoryMapping(861, TorznabCatType.Audio, "         Pop-Rock &amp; Soft Rock (lossless)");
+            AddCategoryMapping(676, TorznabCatType.Audio, "         Pop-Rock &amp; Soft Rock (lossy)");
+            AddCategoryMapping(857, TorznabCatType.Audio, "         Progressive &amp; Art-Rock (lossless)");
+            AddCategoryMapping(674, TorznabCatType.Audio, "         Progressive &amp; Art-Rock (lossy)");
+            AddCategoryMapping(863, TorznabCatType.Audio, "         Rockabilly, Psychobilly, Rock'n'Roll (lossless)");
+            AddCategoryMapping(730, TorznabCatType.Audio, "         Rockabilly, Psychobilly, Rock'n'Roll (lossy)");
+            AddCategoryMapping(1028, TorznabCatType.Audio, "         East Asian Rock (lossless)");
+            AddCategoryMapping(862, TorznabCatType.Audio, "         East Asian rock (lossy)");
+            AddCategoryMapping(1858, TorznabCatType.Audio, "         Collections of foreign rock (lossless)");
+            AddCategoryMapping(1859, TorznabCatType.Audio, "         Collections of foreign rock (lossy)");
+            AddCategoryMapping(187, TorznabCatType.Audio, "      Domestic Rock");
+            AddCategoryMapping(872, TorznabCatType.Audio, "         Rock, Punk, Alternative (lossless)");
+            AddCategoryMapping(190, TorznabCatType.Audio, "         Rock, Punk, Alternative (lossy)");
+            AddCategoryMapping(1489, TorznabCatType.Audio, "         Metal (lossless)");
+            AddCategoryMapping(191, TorznabCatType.Audio, "         Metal (lossy)");
+            AddCategoryMapping(1490, TorznabCatType.Audio, "         Rock on the languages ??of the peoples xUSSR (lossless)");
+            AddCategoryMapping(1491, TorznabCatType.Audio, "         Rock on the languages ??of the peoples xUSSR (lossy)");
+            AddCategoryMapping(866, TorznabCatType.Audio, "      foreign Metal");
+            AddCategoryMapping(727, TorznabCatType.Audio, "         Black (lossy)");
+            AddCategoryMapping(728, TorznabCatType.Audio, "         Death, Doom (lossy)");
+            AddCategoryMapping(729, TorznabCatType.Audio, "         Heavy, Power, Progressive (lossy)");
+            AddCategoryMapping(871, TorznabCatType.Audio, "         Heavy, Power, Progressive (lossless)");
+            AddCategoryMapping(1462, TorznabCatType.Audio, "         Avant-garde, Experimental Metal (lossless)");
+            AddCategoryMapping(1463, TorznabCatType.Audio, "         Avant-garde, Experimental Metal (lossy)");
+            AddCategoryMapping(1464, TorznabCatType.Audio, "         Black (lossless)");
+            AddCategoryMapping(1466, TorznabCatType.Audio, "         Death, Doom (lossless)");
+            AddCategoryMapping(1468, TorznabCatType.Audio, "         Folk, Pagan, Viking (lossless)");
+            AddCategoryMapping(1469, TorznabCatType.Audio, "         Folk, Pagan, Viking (lossy)");
+            AddCategoryMapping(1470, TorznabCatType.Audio, "         Gothic Metal (lossless)");
+            AddCategoryMapping(1471, TorznabCatType.Audio, "         Gothic Metal (lossy)");
+            AddCategoryMapping(1472, TorznabCatType.Audio, "         Grind, Brutal Death (lossless)");
+            AddCategoryMapping(1473, TorznabCatType.Audio, "         Grind, Brutal Death (lossy)");
+            AddCategoryMapping(1474, TorznabCatType.Audio, "         Sludge, Stoner, Post-Metal (lossless)");
+            AddCategoryMapping(1475, TorznabCatType.Audio, "         Sludge, Stoner, Post-Metal (lossy)");
+            AddCategoryMapping(1476, TorznabCatType.Audio, "         Thrash, Speed ??(lossless)");
+            AddCategoryMapping(1477, TorznabCatType.Audio, "         Thrash, Speed ??(lossy)");
+            AddCategoryMapping(1478, TorznabCatType.Audio, "         Collections \"Foreign Metal\" (lossless)");
+            AddCategoryMapping(1479, TorznabCatType.Audio, "         Collections \"Foreign Metal\" (lossy)");
+            AddCategoryMapping(867, TorznabCatType.Audio, "      Foreign Alternative, Punk, Independent");
+            AddCategoryMapping(185, TorznabCatType.Audio, "         Alternative &amp; Nu-metal (lossless)");
+            AddCategoryMapping(868, TorznabCatType.Audio, "         Alternative &amp; Nu-metal (lossy)");
+            AddCategoryMapping(869, TorznabCatType.Audio, "         Indie, Post-Rock &amp; Post-Punk (lossless)");
+            AddCategoryMapping(870, TorznabCatType.Audio, "         Indie, Post-Rock &amp; Post-Punk (lossy)");
+            AddCategoryMapping(873, TorznabCatType.Audio, "         Avant-garde, Experimental Rock (lossy)");
+            AddCategoryMapping(874, TorznabCatType.Audio, "         Punk (lossy)");
+            AddCategoryMapping(875, TorznabCatType.Audio, "         Punk (lossless)");
+            AddCategoryMapping(876, TorznabCatType.Audio, "         Avant-garde, Experimental Rock (lossless)");
+            AddCategoryMapping(1480, TorznabCatType.Audio, "         Hardcore (lossless)");
+            AddCategoryMapping(1481, TorznabCatType.Audio, "         Hardcore (lossy)");
+            AddCategoryMapping(1482, TorznabCatType.Audio, "         Industrial &amp; Post-industrial (lossless)");
+            AddCategoryMapping(1483, TorznabCatType.Audio, "         Industrial &amp; Post-industrial (lossy)");
+            AddCategoryMapping(1484, TorznabCatType.Audio, "         Emocore, Post-hardcore, Metalcore (lossless)");
+            AddCategoryMapping(1485, TorznabCatType.Audio, "         Emocore, Post-hardcore, Metalcore (lossy)");
+            AddCategoryMapping(1486, TorznabCatType.Audio, "         Gothic Rock &amp; Dark Folk (lossless)");
+            AddCategoryMapping(1487, TorznabCatType.Audio, "         Gothic Rock &amp; Dark Folk (lossy)");
+            AddCategoryMapping(1492, TorznabCatType.Audio, "      The multi-channel music and own digitization (Rock)");
+            AddCategoryMapping(1493, TorznabCatType.Audio, "         Foreign rock (own digitization)");
+            AddCategoryMapping(1494, TorznabCatType.Audio, "         Domestic Rock (own digitization)");
+            AddCategoryMapping(1495, TorznabCatType.Audio, "         Foreign and domestic rock (multichannel music)");
+            AddCategoryMapping(1496, TorznabCatType.Audio, "         Foreign rock (Hi-Res stereo)");
+            AddCategoryMapping(1497, TorznabCatType.Audio, "         Conversion Quadraphonic (multichannel music)");
+            AddCategoryMapping(1498, TorznabCatType.Audio, "         Conversion SACD (multi-channel music)");
+            AddCategoryMapping(1499, TorznabCatType.Audio, "         Conversions in Blu-Ray (multichannel music)");
+            AddCategoryMapping(1500, TorznabCatType.Audio, "         Apmiksy-Upmixes / downmix-Downmix (multi-channel and Hi-Res stereo music)");
+            AddCategoryMapping(1501, TorznabCatType.Audio, "      Video, DVD Video, HD Video (Rock)");
+            AddCategoryMapping(1502, TorznabCatType.Audio, "         Rock (Video)");
+            AddCategoryMapping(1503, TorznabCatType.Audio, "         Rock (DVD Video)");
+            AddCategoryMapping(1504, TorznabCatType.Audio, "         Rock (Unofficial DVD Video)");
+            AddCategoryMapping(1505, TorznabCatType.Audio, "         Metal (Video)");
+            AddCategoryMapping(1506, TorznabCatType.Audio, "         Metal (DVD Video)");
+            AddCategoryMapping(1507, TorznabCatType.Audio, "         Metal (Unofficial DVD Video)");
+            AddCategoryMapping(1508, TorznabCatType.Audio, "         Alternative, Punk, Independent (Video)");
+            AddCategoryMapping(1509, TorznabCatType.Audio, "         Alternative, Punk, Independent (DVD Video)");
+            AddCategoryMapping(1510, TorznabCatType.Audio, "         Alternative, Punk, Independent (Unofficial DVD Video)");
+            AddCategoryMapping(1511, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative (Video)");
+            AddCategoryMapping(1512, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative (DVD Video)");
+            AddCategoryMapping(1513, TorznabCatType.Audio, "         Domestic Metal (Video)");
+            AddCategoryMapping(1514, TorznabCatType.Audio, "         Domestic Metal (DVD Video)");
+            AddCategoryMapping(1515, TorznabCatType.Audio, "         Domestic Rock, Punk, Alternative, Metal (Unofficial DVD Video)");
+            AddCategoryMapping(1516, TorznabCatType.Audio, "         Rock (HD Video)");
+            AddCategoryMapping(905, TorznabCatType.Audio, "   Folklore, Folk and World Music");
+            AddCategoryMapping(906, TorznabCatType.Audio, "      Eastern European Folk (lossy)");
+            AddCategoryMapping(907, TorznabCatType.Audio, "      Eastern European Folk (lossless)");
+            AddCategoryMapping(908, TorznabCatType.Audio, "      Western European folk (lossy)");
+            AddCategoryMapping(909, TorznabCatType.Audio, "      Western European folk (lossless)");
+            AddCategoryMapping(910, TorznabCatType.Audio, "      Klezmer and Jewish folklore (lossy and lossless)");
+            AddCategoryMapping(911, TorznabCatType.Audio, "      Country, Bluegrass (lossy)");
+            AddCategoryMapping(912, TorznabCatType.Audio, "      Country, Bluegrass (lossless)");
+            AddCategoryMapping(1372, TorznabCatType.Audio, "      World Music Siberia, Central Asia and East Asia (lossy)");
+            AddCategoryMapping(1373, TorznabCatType.Audio, "      World Music Siberia, Central Asia and East Asia (lossless)");
+            AddCategoryMapping(1374, TorznabCatType.Audio, "      World Music India (lossy)");
+            AddCategoryMapping(1375, TorznabCatType.Audio, "      World Music India (lossless)");
+            AddCategoryMapping(1376, TorznabCatType.Audio, "      World Music Africa and the Middle East (lossy)");
+            AddCategoryMapping(1377, TorznabCatType.Audio, "      World Music Africa and the Middle East (lossless)");
+            AddCategoryMapping(1378, TorznabCatType.Audio, "      Ethnic Caucasus and Transcaucasia music (lossy and lossless)");
+            AddCategoryMapping(1379, TorznabCatType.Audio, "      World Music Americas (lossy)");
+            AddCategoryMapping(1380, TorznabCatType.Audio, "      World Music Americas (lossless)");
+            AddCategoryMapping(1381, TorznabCatType.Audio, "      World Music Australia, the Pacific and Indian Oceans (lossy and lossless)");
+            AddCategoryMapping(1382, TorznabCatType.Audio, "      Folklore, Folk and World Music (Video)");
+            AddCategoryMapping(1383, TorznabCatType.Audio, "      Folklore, Folk and World Music (DVD Video)");
+            AddCategoryMapping(1384, TorznabCatType.Audio, "      Folklore, Folk and World Music (HD Video)");
+            AddCategoryMapping(1857, TorznabCatType.Audio, "      Folklore, Folk and World Music (own digitization)");
+            AddCategoryMapping(985, TorznabCatType.Audio, "   Reggae, Ska, Dub");
+            AddCategoryMapping(986, TorznabCatType.Audio, "      Rocksteady, Early Reggae, Ska-Jazz, Trad.Ska (lossy and lossless)");
+            AddCategoryMapping(987, TorznabCatType.Audio, "      Punky-Reggae, Rocksteady-Punk, Ska Revival (lossy)");
+            AddCategoryMapping(988, TorznabCatType.Audio, "      3rd Wave Ska (lossy)");
+            AddCategoryMapping(989, TorznabCatType.Audio, "      Ska-Punk, Ska-Core (lossy)");
+            AddCategoryMapping(990, TorznabCatType.Audio, "      Reggae (lossy)");
+            AddCategoryMapping(1026, TorznabCatType.Audio, "      Dub (lossy)");
+            AddCategoryMapping(991, TorznabCatType.Audio, "      Dancehall, Raggamuffin (lossy)");
+            AddCategoryMapping(992, TorznabCatType.Audio, "      Reggae, Dancehall, Dub (lossless)");
+            AddCategoryMapping(993, TorznabCatType.Audio, "      Ska, Ska-Punk, Ska-Jazz (lossless)");
+            AddCategoryMapping(994, TorznabCatType.Audio, "      Domestic reggae, dub (lossy and lossless)");
+            AddCategoryMapping(995, TorznabCatType.Audio, "      Domestic ska music (lossy and lossless)");
+            AddCategoryMapping(997, TorznabCatType.Audio, "      Reggae, Ska, Dub (own digitization)");
+            AddCategoryMapping(998, TorznabCatType.Audio, "      Reggae, Ska, Dub (compilation) (lossy)");
+            AddCategoryMapping(999, TorznabCatType.Audio, "      Reggae, Ska, Dub (Video)");
+            AddCategoryMapping(1000, TorznabCatType.Audio, "      Reggae, Ska, Dub (DVD and HD Video)");
+            AddCategoryMapping(1418, TorznabCatType.Audio, "   Sheet Music literature");
+            AddCategoryMapping(1419, TorznabCatType.Audio, "      Academic Music (Notes and Media CD)");
+            AddCategoryMapping(1420, TorznabCatType.Audio, "      More destinations (notes, tablature)");
+            AddCategoryMapping(1421, TorznabCatType.Audio, "      Self and School");
+            AddCategoryMapping(1422, TorznabCatType.Audio, "      Songbooks (Songbooks)");
+            AddCategoryMapping(1423, TorznabCatType.Audio, "      Music Literature and Theory");
+            AddCategoryMapping(1424, TorznabCatType.Audio, "      music magazines");
+            AddCategoryMapping(1602, TorznabCatType.Audio, "   Audio for Apple devices");
+            AddCategoryMapping(1603, TorznabCatType.Audio, "      Audiobooks (AAC, ALAC)");
+            AddCategoryMapping(1604, TorznabCatType.Audio, "      Music Lossless (ALAC)");
+            AddCategoryMapping(1605, TorznabCatType.Audio, "      Music Lossy (AAC)");
+            AddCategoryMapping(1606, TorznabCatType.Audio, "      Music Lossy (AAC) (Singles, EPs)");
+            AddCategoryMapping(113, TorznabCatType.Books, "Books, Audio Books, Journals");
+            AddCategoryMapping(561, TorznabCatType.Books, "   Books, Audio Books, Journals (General Discussion)");
+            AddCategoryMapping(316, TorznabCatType.Books, "      Archive (Books, Audio Books, Journals)");
+            AddCategoryMapping(1620, TorznabCatType.Books, "      Meditation");
+            AddCategoryMapping(1802, TorznabCatType.Books, "      Historiography");
+            AddCategoryMapping(116, TorznabCatType.AudioAudiobook, "   Audiobooks");
+            AddCategoryMapping(1231, TorznabCatType.AudioAudiobook, "      Audio, history, memoirs (Audiobooks)");
+            AddCategoryMapping(119, TorznabCatType.AudioAudiobook, "         Audio and literary readings (Audiobooks)");
+            AddCategoryMapping(1232, TorznabCatType.AudioAudiobook, "         Lots of great people (Audiobooks)");
+            AddCategoryMapping(1233, TorznabCatType.AudioAudiobook, "         Historical book (Audiobooks)");
+            AddCategoryMapping(321, TorznabCatType.AudioAudiobook, "      Science fiction, fantasy, mystery, horror, fanfiction (Audiobooks)");
+            AddCategoryMapping(1234, TorznabCatType.AudioAudiobook, "         Russian fiction, fantasy, mystery, horror, fanfiction (audiobook)");
+            AddCategoryMapping(1235, TorznabCatType.AudioAudiobook, "         Foreign fiction, fantasy, mystery, horror, fanfiction (audiobook)");
+            AddCategoryMapping(317, TorznabCatType.AudioAudiobook, "      Fiction (Audiobooks)");
+            AddCategoryMapping(1236, TorznabCatType.AudioAudiobook, "         Poetry (audiobook)");
+            AddCategoryMapping(118, TorznabCatType.AudioAudiobook, "         Foreign literature (audiobook)");
+            AddCategoryMapping(117, TorznabCatType.AudioAudiobook, "         Russian Literature (audiobook)");
+            AddCategoryMapping(120, TorznabCatType.AudioAudiobook, "         Children's Literature (audiobook)");
+            AddCategoryMapping(1237, TorznabCatType.AudioAudiobook, "         Detectives, Adventure, Thriller, Action (audiobook)");
+            AddCategoryMapping(318, TorznabCatType.AudioAudiobook, "            Detectives (audiobook)");
+            AddCategoryMapping(322, TorznabCatType.AudioAudiobook, "      Psychology. philosophy, religion (Audiobooks)");
+            AddCategoryMapping(1238, TorznabCatType.AudioAudiobook, "         Religion (Audio)");
+            AddCategoryMapping(1239, TorznabCatType.AudioAudiobook, "            Orthodox (Audio)");
+            AddCategoryMapping(1240, TorznabCatType.AudioAudiobook, "            Islam (Audio)");
+            AddCategoryMapping(1241, TorznabCatType.AudioAudiobook, "            Other traditional religion (Audio)");
+            AddCategoryMapping(1242, TorznabCatType.AudioAudiobook, "            Nontraditional religious philosophies (Audio)");
+            AddCategoryMapping(1243, TorznabCatType.AudioAudiobook, "      Educational, scientific and popular literature (Audio)");
+            AddCategoryMapping(1244, TorznabCatType.AudioAudiobook, "      Audiobooks in lossless-format");
+            AddCategoryMapping(323, TorznabCatType.AudioAudiobook, "      Business (Audio)");
+            AddCategoryMapping(319, TorznabCatType.AudioAudiobook, "      Historical literature (Audiobooks)");
+            AddCategoryMapping(1245, TorznabCatType.AudioAudiobook, "      Miscellaneous (Audiobooks)");
+            AddCategoryMapping(1622, TorznabCatType.AudioAudiobook, "      Meditation (Audio)");
+            AddCategoryMapping(1626, TorznabCatType.AudioAudiobook, "      publicism");
+            AddCategoryMapping(1627, TorznabCatType.AudioAudiobook, "      Satire, humor");
+            AddCategoryMapping(324, TorznabCatType.AudioAudiobook, "      Archive and nekonditsiya audiobooks");
+            AddCategoryMapping(670, TorznabCatType.Books, "   Books and magazines");
+            AddCategoryMapping(671, TorznabCatType.Books, "      Esoteric Tarot, Feng Shui");
+            AddCategoryMapping(885, TorznabCatType.Books, "      Film, TV, animation");
+            AddCategoryMapping(886, TorznabCatType.Books, "      Drawing, Graphic Design");
+            AddCategoryMapping(887, TorznabCatType.Books, "      Photo and video shooting");
+            AddCategoryMapping(888, TorznabCatType.Books, "      Astrology");
+            AddCategoryMapping(1865, TorznabCatType.Books, "      Fashion. Style. Etiquette");
+            AddCategoryMapping(889, TorznabCatType.Books, "      Celebrities and idols");
+            AddCategoryMapping(890, TorznabCatType.Books, "      Miscellaneous");
+            AddCategoryMapping(982, TorznabCatType.Books, "      Magazines and newspapers (general section)");
+            AddCategoryMapping(566, TorznabCatType.Books, "         Men's magazines");
+            AddCategoryMapping(1204, TorznabCatType.Books, "         For women (magazines and books)");
+            AddCategoryMapping(1793, TorznabCatType.Books, "         Popular science magazines");
+            AddCategoryMapping(1794, TorznabCatType.Books, "         Journals of Electrical and Electronics");
+            AddCategoryMapping(1795, TorznabCatType.Books, "         Housekeeping (logs)");
+            AddCategoryMapping(1796, TorznabCatType.Books, "         Hobbies (logs)");
+            AddCategoryMapping(1797, TorznabCatType.Books, "         Other magazines");
+            AddCategoryMapping(1205, TorznabCatType.Books, "      Travel and tourism");
+            AddCategoryMapping(258, TorznabCatType.Books, "      For children, parents and teachers");
+            AddCategoryMapping(1685, TorznabCatType.Books, "         Tutorials (General)");
+            AddCategoryMapping(681, TorznabCatType.Books, "         Textbooks for kindergarten and elementary school (up to class 4)");
+            AddCategoryMapping(682, TorznabCatType.Books, "         Textbooks for high school (grades 5-11)");
+            AddCategoryMapping(683, TorznabCatType.Books, "         Teachers and educators");
+            AddCategoryMapping(684, TorznabCatType.Books, "         Popular science and cognitive literature (for children)");
+            AddCategoryMapping(685, TorznabCatType.Books, "         Leisure and creativity");
+            AddCategoryMapping(686, TorznabCatType.Books, "         Education and development");
+            AddCategoryMapping(687, TorznabCatType.Books, "         Hood. lit-ra for preschool and elementary grades");
+            AddCategoryMapping(688, TorznabCatType.Books, "         Hood. lit-ra for the middle and upper classes");
+            AddCategoryMapping(731, TorznabCatType.Books, "      Sports, physical training, martial arts");
+            AddCategoryMapping(738, TorznabCatType.Books, "         Autosport. Motorcycling. Cycling (literature)");
+            AddCategoryMapping(737, TorznabCatType.Books, "         Martial arts, martial arts (literature)");
+            AddCategoryMapping(734, TorznabCatType.Books, "         Team sports (literature)");
+            AddCategoryMapping(1854, TorznabCatType.Books, "         Athletics. Swimming. Gymnastics. Weightlifting. Rowing (literature)");
+            AddCategoryMapping(739, TorznabCatType.Books, "         Sport Editions");
+            AddCategoryMapping(736, TorznabCatType.Books, "         Fitness, fitness, bodybuilding (literature)");
+            AddCategoryMapping(732, TorznabCatType.Books, "         Football (literature)");
+            AddCategoryMapping(733, TorznabCatType.Books, "         Hockey (literature)");
+            AddCategoryMapping(735, TorznabCatType.Books, "         Chess. Checkers (literature)");
+            AddCategoryMapping(1855, TorznabCatType.Books, "         Extreme sports (literature)");
+            AddCategoryMapping(649, TorznabCatType.Books, "      Humanitarian sciences");
+            AddCategoryMapping(650, TorznabCatType.Books, "         Arts. Cultural");
+            AddCategoryMapping(651, TorznabCatType.Books, "         Folklore. Epic. Mythology");
+            AddCategoryMapping(652, TorznabCatType.Books, "         literary criticism");
+            AddCategoryMapping(653, TorznabCatType.Books, "         Linguistics");
+            AddCategoryMapping(654, TorznabCatType.Books, "         Philosophy");
+            AddCategoryMapping(655, TorznabCatType.Books, "         Political science");
+            AddCategoryMapping(656, TorznabCatType.Books, "         Sociology");
+            AddCategoryMapping(657, TorznabCatType.Books, "         Journalism, Journalism");
+            AddCategoryMapping(658, TorznabCatType.Books, "         Business, Management");
+            AddCategoryMapping(659, TorznabCatType.Books, "         Marketing");
+            AddCategoryMapping(660, TorznabCatType.Books, "         Economy");
+            AddCategoryMapping(661, TorznabCatType.Books, "         Finance");
+            AddCategoryMapping(662, TorznabCatType.Books, "         Jurisprudence. Right. criminalistics");
+            AddCategoryMapping(664, TorznabCatType.Books, "      Historical sciences");
+            AddCategoryMapping(665, TorznabCatType.Books, "         Historical person");
+            AddCategoryMapping(807, TorznabCatType.Books, "         Historical sources");
+            AddCategoryMapping(808, TorznabCatType.Books, "         Alternative historical theories");
+            AddCategoryMapping(809, TorznabCatType.Books, "         Archeology");
+            AddCategoryMapping(810, TorznabCatType.Books, "         Ancient world. Antiquity");
+            AddCategoryMapping(811, TorznabCatType.Books, "         Middle Ages");
+            AddCategoryMapping(812, TorznabCatType.Books, "         The history of modern and contemporary");
+            AddCategoryMapping(813, TorznabCatType.Books, "         History of Europe");
+            AddCategoryMapping(814, TorznabCatType.Books, "         History of Asia and Africa");
+            AddCategoryMapping(815, TorznabCatType.Books, "         The history of America, Australia, Oceania");
+            AddCategoryMapping(816, TorznabCatType.Books, "         Russian history");
+            AddCategoryMapping(817, TorznabCatType.Books, "         The era of the Soviet Union");
+            AddCategoryMapping(818, TorznabCatType.Books, "         History of the former Soviet Union");
+            AddCategoryMapping(819, TorznabCatType.Books, "         Ethnography, anthropology");
+            AddCategoryMapping(820, TorznabCatType.Books, "         International relationships. Diplomacy");
+            AddCategoryMapping(1856, TorznabCatType.Books, "         Methodology and philosophy of history");
+            AddCategoryMapping(255, TorznabCatType.Books, "      Accurate, natural and engineering sciences");
+            AddCategoryMapping(648, TorznabCatType.Books, "         Geography / Geology / Geodesy");
+            AddCategoryMapping(672, TorznabCatType.Books, "         Physics");
+            AddCategoryMapping(723, TorznabCatType.Books, "         Astronomy");
+            AddCategoryMapping(725, TorznabCatType.Books, "         Aviation / Astronautics");
+            AddCategoryMapping(726, TorznabCatType.Books, "         Mathematics");
+            AddCategoryMapping(748, TorznabCatType.Books, "         Welding / Soldering / Non-Destructive Testing");
+            AddCategoryMapping(749, TorznabCatType.Books, "         Architecture / construction / engineering services");
+            AddCategoryMapping(750, TorznabCatType.Books, "         Biology / Ecology");
+            AddCategoryMapping(751, TorznabCatType.Books, "         Chemistry / Biochemistry");
+            AddCategoryMapping(821, TorznabCatType.Books, "         Electronics / Radio");
+            AddCategoryMapping(822, TorznabCatType.Books, "         Diagrams and service manuals (original documents)");
+            AddCategoryMapping(823, TorznabCatType.Books, "         engineering");
+            AddCategoryMapping(824, TorznabCatType.Books, "         Automation / Robotics");
+            AddCategoryMapping(825, TorznabCatType.Books, "         Metallurgy / Materials");
+            AddCategoryMapping(826, TorznabCatType.Books, "         Mechanics, Strength of Materials");
+            AddCategoryMapping(827, TorznabCatType.Books, "         Energy / Electrical");
+            AddCategoryMapping(828, TorznabCatType.Books, "         Oil, gas and chemical industry");
+            AddCategoryMapping(829, TorznabCatType.Books, "         Agriculture and food industry");
+            AddCategoryMapping(836, TorznabCatType.Books, "         Railway deal");
+            AddCategoryMapping(837, TorznabCatType.Books, "         Normative documents");
+            AddCategoryMapping(838, TorznabCatType.Books, "         Journals: scientific, popular, radio and others.");
+            AddCategoryMapping(668, TorznabCatType.Books, "      Warfare");
+            AddCategoryMapping(669, TorznabCatType.Books, "         History of the Second World War");
+            AddCategoryMapping(830, TorznabCatType.Books, "         Militaria");
+            AddCategoryMapping(831, TorznabCatType.Books, "         Military history");
+            AddCategoryMapping(832, TorznabCatType.Books, "         Military equipment");
+            AddCategoryMapping(833, TorznabCatType.Books, "         Weapon");
+            AddCategoryMapping(834, TorznabCatType.Books, "         Educational literature");
+            AddCategoryMapping(835, TorznabCatType.Books, "         The special services of the world");
+            AddCategoryMapping(666, TorznabCatType.Books, "      Faith and Religion");
+            AddCategoryMapping(667, TorznabCatType.Books, "         Christianity");
+            AddCategoryMapping(881, TorznabCatType.Books, "         Islam");
+            AddCategoryMapping(882, TorznabCatType.Books, "         Religions of India, Tibet and East Asia / Judaism");
+            AddCategoryMapping(883, TorznabCatType.Books, "         Nontraditional religious, spiritual and mystical teachings");
+            AddCategoryMapping(884, TorznabCatType.Books, "         Religious Studies. History of Religions. Atheism");
+            AddCategoryMapping(1206, TorznabCatType.Books, "      Psychology");
+            AddCategoryMapping(1207, TorznabCatType.Books, "         General and Applied Psychology");
+            AddCategoryMapping(1208, TorznabCatType.Books, "         Psychotherapy and counseling");
+            AddCategoryMapping(1209, TorznabCatType.Books, "         Psychological diagnostics and therapy");
+            AddCategoryMapping(1210, TorznabCatType.Books, "         Social psychology and psychology of relationships");
+            AddCategoryMapping(1211, TorznabCatType.Books, "         Training and Coaching");
+            AddCategoryMapping(1212, TorznabCatType.Books, "         Self-development and self-improvement");
+            AddCategoryMapping(1213, TorznabCatType.Books, "         Popular psychology");
+            AddCategoryMapping(1214, TorznabCatType.Books, "         Sexology. Relations between the sexes");
+            AddCategoryMapping(254, TorznabCatType.Books, "      Collecting, hobby and hobbies");
+            AddCategoryMapping(633, TorznabCatType.Books, "         Collecting and auxiliary ist. discipline");
+            AddCategoryMapping(634, TorznabCatType.Books, "         Embroidery");
+            AddCategoryMapping(635, TorznabCatType.Books, "         Knitting");
+            AddCategoryMapping(636, TorznabCatType.Books, "         Sewing, patchwork");
+            AddCategoryMapping(637, TorznabCatType.Books, "         lace");
+            AddCategoryMapping(638, TorznabCatType.Books, "         Beading");
+            AddCategoryMapping(639, TorznabCatType.Books, "         Paper art");
+            AddCategoryMapping(640, TorznabCatType.Books, "         Other arts and crafts");
+            AddCategoryMapping(641, TorznabCatType.Books, "         Pets and aquariums");
+            AddCategoryMapping(642, TorznabCatType.Books, "         Hunting and fishing");
+            AddCategoryMapping(598, TorznabCatType.Books, "         Cooking (Book)");
+            AddCategoryMapping(312, TorznabCatType.Books, "         Cooking (newspapers and magazines)");
+            AddCategoryMapping(643, TorznabCatType.Books, "         Modelling");
+            AddCategoryMapping(644, TorznabCatType.Books, "         Farmland / Floriculture");
+            AddCategoryMapping(645, TorznabCatType.Books, "         Repair, private construction, design of interiors");
+            AddCategoryMapping(1866, TorznabCatType.Books, "         Woodworking");
+            AddCategoryMapping(646, TorznabCatType.Books, "         Board games");
+            AddCategoryMapping(647, TorznabCatType.Books, "         Other hobbies");
+            AddCategoryMapping(1786, TorznabCatType.Books, "      Nonfiction");
+            AddCategoryMapping(623, TorznabCatType.Books, "      Fiction");
+            AddCategoryMapping(624, TorznabCatType.Books, "         Russian Literature (books)");
+            AddCategoryMapping(627, TorznabCatType.Books, "         The detective, thriller (book)");
+            AddCategoryMapping(1624, TorznabCatType.Books, "            Militants (Books)");
+            AddCategoryMapping(1625, TorznabCatType.Books, "            Detectives (Books)");
+            AddCategoryMapping(628, TorznabCatType.Books, "         Female Novel (Book)");
+            AddCategoryMapping(631, TorznabCatType.Books, "         Adventure (book)");
+            AddCategoryMapping(632, TorznabCatType.Books, "         Literary magazines");
+            AddCategoryMapping(1611, TorznabCatType.Books, "         Fiction / Fantasy / Mystic (book)");
+            AddCategoryMapping(629, TorznabCatType.Books, "            Domestic science fiction / fantasy / mystic");
+            AddCategoryMapping(630, TorznabCatType.Books, "            International science fiction / fantasy / mystic");
+            AddCategoryMapping(1612, TorznabCatType.Books, "         Foreign literature (books)");
+            AddCategoryMapping(625, TorznabCatType.Books, "            Foreign literature (up to 1900)");
+            AddCategoryMapping(626, TorznabCatType.Books, "            Foreign literature (XX and XXI century)");
+            AddCategoryMapping(1618, TorznabCatType.Books, "         Historical books");
+            AddCategoryMapping(1789, TorznabCatType.Books, "         Satire, humor (the book)");
+            AddCategoryMapping(257, TorznabCatType.Books, "      Computer books");
+            AddCategoryMapping(678, TorznabCatType.Books, "         Programming (Literature)");
+            AddCategoryMapping(714, TorznabCatType.Books, "         Programs from Microsoft (literature)");
+            AddCategoryMapping(715, TorznabCatType.Books, "         Other programs (literature)");
+            AddCategoryMapping(716, TorznabCatType.Books, "         Mac OS; Linux, FreeBSD and other * NIX (literature)");
+            AddCategoryMapping(717, TorznabCatType.Books, "         DBMS (literature)");
+            AddCategoryMapping(718, TorznabCatType.Books, "         Web Design and Programming (Literature)");
+            AddCategoryMapping(719, TorznabCatType.Books, "         Graphics, video processing (literature)");
+            AddCategoryMapping(720, TorznabCatType.Books, "         Network / VoIP (literature)");
+            AddCategoryMapping(721, TorznabCatType.Books, "         Hacking and Security (literature)");
+            AddCategoryMapping(722, TorznabCatType.Books, "         Iron (book on a PC)");
+            AddCategoryMapping(1215, TorznabCatType.Books, "         Engineering and science programs (literature)");
+            AddCategoryMapping(1216, TorznabCatType.Books, "         Computer magazines and annexes");
+            AddCategoryMapping(1791, TorznabCatType.Books, "            gaming magazines");
+            AddCategoryMapping(1792, TorznabCatType.Books, "            Computer magazines");
+            AddCategoryMapping(1217, TorznabCatType.Books, "         Disc applications to gaming magazines");
+            AddCategoryMapping(311, TorznabCatType.Books, "      Comics");
+            AddCategoryMapping(1218, TorznabCatType.Books, "         Comics in Russian");
+            AddCategoryMapping(1219, TorznabCatType.Books, "         Marvel Comics publishing");
+            AddCategoryMapping(1220, TorznabCatType.Books, "         DC Comics publishing");
+            AddCategoryMapping(1221, TorznabCatType.Books, "         Comics from other publishers");
+            AddCategoryMapping(1222, TorznabCatType.Books, "         Comics in other languages");
+            AddCategoryMapping(1223, TorznabCatType.Books, "         Substandard distribution (Comics)");
+            AddCategoryMapping(259, TorznabCatType.Books, "      Collections of books and libraries");
+            AddCategoryMapping(983, TorznabCatType.Books, "         Libraries (mirror network libraries / collections)");
+            AddCategoryMapping(984, TorznabCatType.Books, "         Thematic collections (collections)");
+            AddCategoryMapping(1224, TorznabCatType.Books, "         Multidisciplinary collection (compilation)");
+            AddCategoryMapping(1788, TorznabCatType.Books, "         Mnogoavtorskie collections, book series");
+            AddCategoryMapping(1787, TorznabCatType.Books, "      Encyclopedias and dictionaries");
+            AddCategoryMapping(1225, TorznabCatType.Books, "   Multimedia and online publications");
+            AddCategoryMapping(1226, TorznabCatType.Books, "      Multimedia encyclopedia");
+            AddCategoryMapping(1227, TorznabCatType.Books, "      Interactive tutorials and educational materials");
+            AddCategoryMapping(1228, TorznabCatType.Books, "      Educational publications for children");
+            AddCategoryMapping(1229, TorznabCatType.Books, "      Cooking. Floriculture. housekeeping");
+            AddCategoryMapping(1230, TorznabCatType.Books, "      Culture. Art. History");
+            AddCategoryMapping(497, TorznabCatType.Books, "training materials");
+            AddCategoryMapping(1246, TorznabCatType.Books, "   Learning foreign languages");
+            AddCategoryMapping(1248, TorznabCatType.Books, "      Foreign languages ??for children");
+            AddCategoryMapping(1249, TorznabCatType.Books, "         English (for children)");
+            AddCategoryMapping(1250, TorznabCatType.Books, "         Other European languages ??(for children)");
+            AddCategoryMapping(1251, TorznabCatType.Books, "         Oriental languages ??(for children)");
+            AddCategoryMapping(1252, TorznabCatType.Books, "         School books, the exam (for children)");
+            AddCategoryMapping(1253, TorznabCatType.Books, "      Fiction in foreign languages");
+            AddCategoryMapping(1254, TorznabCatType.Books, "         Fiction in English");
+            AddCategoryMapping(1255, TorznabCatType.Books, "         Fiction French");
+            AddCategoryMapping(1256, TorznabCatType.Books, "         Fiction in other European languages");
+            AddCategoryMapping(1257, TorznabCatType.Books, "         Fiction in oriental languages");
+            AddCategoryMapping(1258, TorznabCatType.Books, "      Foreign Language for Adults");
+            AddCategoryMapping(1259, TorznabCatType.Books, "         English (for adults)");
+            AddCategoryMapping(1260, TorznabCatType.Books, "         German");
+            AddCategoryMapping(1261, TorznabCatType.Books, "         French");
+            AddCategoryMapping(1262, TorznabCatType.Books, "         Spanish");
+            AddCategoryMapping(1263, TorznabCatType.Books, "         Italian language");
+            AddCategoryMapping(1264, TorznabCatType.Books, "         Other European languages");
+            AddCategoryMapping(1265, TorznabCatType.Books, "         Arabic language");
+            AddCategoryMapping(1266, TorznabCatType.Books, "         Chinese");
+            AddCategoryMapping(1267, TorznabCatType.Books, "         Japanese");
+            AddCategoryMapping(1268, TorznabCatType.Books, "         Other oriental languages");
+            AddCategoryMapping(1269, TorznabCatType.Books, "         Russian as a foreign language");
+            AddCategoryMapping(1270, TorznabCatType.Books, "         Multilanguage collections");
+            AddCategoryMapping(1271, TorznabCatType.Books, "         Miscellaneous (foreign languages)");
+            AddCategoryMapping(1867, TorznabCatType.Books, "         LIM-courses");
+            AddCategoryMapping(1272, TorznabCatType.Books, "      Audio Books in foreign languages");
+            AddCategoryMapping(1273, TorznabCatType.Books, "         Audiobooks in English");
+            AddCategoryMapping(1274, TorznabCatType.Books, "         Audiobooks in German");
+            AddCategoryMapping(1275, TorznabCatType.Books, "         Audiobooks in other languages");
+            AddCategoryMapping(1623, TorznabCatType.Books, "      Educational audio materials");
+            AddCategoryMapping(1247, TorznabCatType.Books, "   video tutorials");
+            AddCategoryMapping(933, TorznabCatType.Books, "      Video tutorials and interactive training DVD");
+            AddCategoryMapping(936, TorznabCatType.Books, "         Cooking (video tutorial)");
+            AddCategoryMapping(1276, TorznabCatType.Books, "         Sport");
+            AddCategoryMapping(934, TorznabCatType.Books, "         Fitness - Cardio, Strength Training");
+            AddCategoryMapping(1277, TorznabCatType.Books, "         Fitness - Mind and Body");
+            AddCategoryMapping(1278, TorznabCatType.Books, "         Extreme sports (video tutorial)");
+            AddCategoryMapping(935, TorznabCatType.Books, "         Playing guitar");
+            AddCategoryMapping(1279, TorznabCatType.Books, "         Body-building");
+            AddCategoryMapping(1280, TorznabCatType.Books, "         Health practice");
+            AddCategoryMapping(1281, TorznabCatType.Books, "         Yoga");
+            AddCategoryMapping(1282, TorznabCatType.Books, "         Video and Snapshots");
+            AddCategoryMapping(1283, TorznabCatType.Books, "         Personal care");
+            AddCategoryMapping(1284, TorznabCatType.Books, "         Painting");
+            AddCategoryMapping(1286, TorznabCatType.Books, "         Percussion instruments");
+            AddCategoryMapping(1287, TorznabCatType.Books, "         Other musical instruments");
+            AddCategoryMapping(1288, TorznabCatType.Books, "         Playing bass guitar");
+            AddCategoryMapping(1289, TorznabCatType.Books, "         Ballroom dancing");
+            AddCategoryMapping(1290, TorznabCatType.Books, "         Belly dance");
+            AddCategoryMapping(1291, TorznabCatType.Books, "         Street and club dances");
+            AddCategoryMapping(1292, TorznabCatType.Books, "         Dancing, miscellaneous");
+            AddCategoryMapping(1295, TorznabCatType.Books, "         Tricks and stunts");
+            AddCategoryMapping(1296, TorznabCatType.Books, "         Education");
+            AddCategoryMapping(1297, TorznabCatType.Books, "         Business, Economics and Finance");
+            AddCategoryMapping(1299, TorznabCatType.Books, "         Pregnancy, childbirth, motherhood");
+            AddCategoryMapping(1300, TorznabCatType.Books, "         Educational video for children");
+            AddCategoryMapping(1301, TorznabCatType.Books, "         Psychology (video)");
+            AddCategoryMapping(1302, TorznabCatType.Books, "         Spirituality, self-development");
+            AddCategoryMapping(1303, TorznabCatType.Books, "         Pickup, love");
+            AddCategoryMapping(1304, TorznabCatType.Books, "         Construction, renovation and design");
+            AddCategoryMapping(1305, TorznabCatType.Books, "         Wood and metal");
+            AddCategoryMapping(1306, TorznabCatType.Books, "         Plants and Animals");
+            AddCategoryMapping(1676, TorznabCatType.Books, "         Fishing and hunting");
+            AddCategoryMapping(1293, TorznabCatType.Books, "            Hunting");
+            AddCategoryMapping(1294, TorznabCatType.Books, "            Fishing and spearfishing");
+            AddCategoryMapping(1307, TorznabCatType.Books, "         Miscellaneous (Video tutorials and educational interactive DVD)");
+            AddCategoryMapping(1309, TorznabCatType.Books, "      Martial Arts (Video Tutorials)");
+            AddCategoryMapping(1310, TorznabCatType.Books, "         Aikido and Aiki-jutsu");
+            AddCategoryMapping(1311, TorznabCatType.Books, "         Wing Chun");
+            AddCategoryMapping(1312, TorznabCatType.Books, "         Jujutsu");
+            AddCategoryMapping(1313, TorznabCatType.Books, "         Judo and Sambo");
+            AddCategoryMapping(1314, TorznabCatType.Books, "         Karate");
+            AddCategoryMapping(1315, TorznabCatType.Books, "         knife fight");
+            AddCategoryMapping(1316, TorznabCatType.Books, "         Work with weapon");
+            AddCategoryMapping(1317, TorznabCatType.Books, "         Russian style");
+            AddCategoryMapping(1318, TorznabCatType.Books, "         dogfight");
+            AddCategoryMapping(1319, TorznabCatType.Books, "         composite style");
+            AddCategoryMapping(1320, TorznabCatType.Books, "         shock styles");
+            AddCategoryMapping(1321, TorznabCatType.Books, "         Wushu");
+            AddCategoryMapping(1322, TorznabCatType.Books, "         Miscellaneous (Video Tutorials)");
+            AddCategoryMapping(1323, TorznabCatType.Books, "      Computer video tutorials and interactive training DVD");
+            AddCategoryMapping(1324, TorznabCatType.Books, "         Computer networks and security (video tutorial)");
+            AddCategoryMapping(1325, TorznabCatType.Books, "         OS and Microsoft server software (video tutorial)");
+            AddCategoryMapping(1326, TorznabCatType.Books, "         Microsoft Office software (video tutorial)");
+            AddCategoryMapping(1327, TorznabCatType.Books, "         OS and UNIX-program (video tutorial)");
+            AddCategoryMapping(1329, TorznabCatType.Books, "         Adobe Photoshop (video tutorial)");
+            AddCategoryMapping(1330, TorznabCatType.Books, "         Autodesk Maya (video tutorial)");
+            AddCategoryMapping(1331, TorznabCatType.Books, "         Autodesk 3ds Max (video tutorial)");
+            AddCategoryMapping(1332, TorznabCatType.Books, "         Autodesk Softimage (XSI) (video tutorial)");
+            AddCategoryMapping(1333, TorznabCatType.Books, "         ZBrush (video tutorial)");
+            AddCategoryMapping(1334, TorznabCatType.Books, "         Flash, Flex and ActionScript (video tutorial)");
+            AddCategoryMapping(1335, TorznabCatType.Books, "         2D-graphics (video tutorial)");
+            AddCategoryMapping(1336, TorznabCatType.Books, "         3D-graphics (video tutorial)");
+            AddCategoryMapping(1337, TorznabCatType.Books, "         Engineering and science programs (video tutorial)");
+            AddCategoryMapping(1338, TorznabCatType.Books, "         Web-design (video tutorial)");
+            AddCategoryMapping(1339, TorznabCatType.Books, "         Programming (video tutorial)");
+            AddCategoryMapping(1340, TorznabCatType.Books, "         Software for Mac OS (video tutorial)");
+            AddCategoryMapping(1341, TorznabCatType.Books, "         Working with video (video tutorial)");
+            AddCategoryMapping(1342, TorznabCatType.Books, "         Working with sound (video tutorial)");
+            AddCategoryMapping(1343, TorznabCatType.Books, "         Miscellaneous (Computer video tutorials)");
+            AddCategoryMapping(1530, TorznabCatType.Other, "Subject forums");
+            AddCategoryMapping(698, TorznabCatType.Other, "   Auto and Moto");
+            AddCategoryMapping(699, TorznabCatType.Other, "      Repair and maintenance of vehicles");
+            AddCategoryMapping(772, TorznabCatType.Other, "         The original selection of spare parts catalogs");
+            AddCategoryMapping(1344, TorznabCatType.Other, "         Non-original spare parts catalogs for selection");
+            AddCategoryMapping(1345, TorznabCatType.Other, "         diagnostic and repair programs");
+            AddCategoryMapping(1346, TorznabCatType.Other, "         Tuning, chip tuning, tuning");
+            AddCategoryMapping(700, TorznabCatType.Other, "         Books for repair / maintenance / operation of the vehicle");
+            AddCategoryMapping(1349, TorznabCatType.Other, "         Multimediyki repair / maintenance / operation of the vehicle");
+            AddCategoryMapping(1350, TorznabCatType.Other, "         Accounting, utilities, etc.");
+            AddCategoryMapping(1351, TorznabCatType.Other, "         Virtual Driving School");
+            AddCategoryMapping(1352, TorznabCatType.Other, "         Video lessons on driving vehicles");
+            AddCategoryMapping(1353, TorznabCatType.Other, "         Video lessons on repair of vehicles");
+            AddCategoryMapping(1354, TorznabCatType.Other, "         Magazines Auto / Moto");
+            AddCategoryMapping(1355, TorznabCatType.Other, "         Water transport");
+            AddCategoryMapping(1356, TorznabCatType.Other, "      Movies and television shows, car / moto");
+            AddCategoryMapping(1357, TorznabCatType.Other, "         Documentary / educational films");
+            AddCategoryMapping(1358, TorznabCatType.Other, "         entertainment shows");
+            AddCategoryMapping(1359, TorznabCatType.Other, "         Top Gear / Top Gear");
+            AddCategoryMapping(1360, TorznabCatType.Other, "         Test Drive / Reviews / Motor");
+            AddCategoryMapping(1361, TorznabCatType.Other, "         Tuning / Fast and the Furious");
+            AddCategoryMapping(600, TorznabCatType.Other, "   Medicine and Health");
+            AddCategoryMapping(601, TorznabCatType.Other, "      Books, magazines and on medicine and health program");
+            AddCategoryMapping(603, TorznabCatType.Other, "         Clinical medicine until 1980");
+            AddCategoryMapping(604, TorznabCatType.Other, "         Clinical Medicine from 1980 to 2000");
+            AddCategoryMapping(605, TorznabCatType.Other, "         Clinical Medicine since 2000");
+            AddCategoryMapping(606, TorznabCatType.Other, "         The popular medical periodicals (newspapers and magazines)");
+            AddCategoryMapping(607, TorznabCatType.Other, "         The scientific medical periodicals (newspapers and magazines)");
+            AddCategoryMapping(608, TorznabCatType.Other, "         Life Sciences");
+            AddCategoryMapping(609, TorznabCatType.Other, "         Pharmacy and Pharmacology");
+            AddCategoryMapping(610, TorznabCatType.Other, "         Non-traditional, traditional medicine and popular books on health");
+            AddCategoryMapping(611, TorznabCatType.Other, "         Veterinary, miscellaneous");
+            AddCategoryMapping(612, TorznabCatType.Other, "         Thematic collections of books");
+            AddCategoryMapping(613, TorznabCatType.Other, "         Audiobooks on medicine");
+            AddCategoryMapping(614, TorznabCatType.Other, "         Medical software");
+            AddCategoryMapping(602, TorznabCatType.Other, "      Tutorials, Doc. movies and TV shows on medicine");
+            AddCategoryMapping(615, TorznabCatType.Other, "         Medicine and Dentistry");
+            AddCategoryMapping(616, TorznabCatType.Other, "         Psychotherapy and clinical psychology");
+            AddCategoryMapping(617, TorznabCatType.Other, "         Massage");
+            AddCategoryMapping(618, TorznabCatType.Other, "         Health");
+            AddCategoryMapping(619, TorznabCatType.Other, "         Documentary movies and TV shows on medicine");
+            AddCategoryMapping(560, TorznabCatType.Other, "other");
+            AddCategoryMapping(578, TorznabCatType.Other, "   Economy and Life");
+            AddCategoryMapping(1558, TorznabCatType.Other, "   psychoactive audio programs");
+            AddCategoryMapping(1560, TorznabCatType.Other, "   Avatars, Icons, Smileys, painting, drawing, sculpture, pictures, wallpaper, Photography, Digital Art");
+            AddCategoryMapping(1651, TorznabCatType.Other, "      reproductions of paintings");
+            AddCategoryMapping(1652, TorznabCatType.Other, "      Art photography");
+            AddCategoryMapping(1653, TorznabCatType.Other, "      Contemporary photography");
+            AddCategoryMapping(1654, TorznabCatType.Other, "      Collections of works of modern art painters");
+            AddCategoryMapping(1655, TorznabCatType.Other, "      hand-drawn graphics");
+            AddCategoryMapping(1656, TorznabCatType.Other, "      Computer graphics");
+            AddCategoryMapping(1657, TorznabCatType.Other, "      Illustrations");
+            AddCategoryMapping(1659, TorznabCatType.Other, "      Graphics (Other)");
+            AddCategoryMapping(1562, TorznabCatType.Other, "      Amateur photos");
+            AddCategoryMapping(1561, TorznabCatType.Other, "      Pictures");
+            AddCategoryMapping(1563, TorznabCatType.Other, "      Photos of celebrities");
+            AddCategoryMapping(996, TorznabCatType.Other, "      Desktop Wallpaper \\ Wallpapers");
+            AddCategoryMapping(1578, TorznabCatType.Other, "      Wallpapers and themes for mobile devices");
+            AddCategoryMapping(1559, TorznabCatType.Other, "      Avatars, Icons, Smileys");
+            AddCategoryMapping(1564, TorznabCatType.Other, "   Audio");
+            AddCategoryMapping(1801, TorznabCatType.Other, "      Mobile Audio");
+            AddCategoryMapping(1565, TorznabCatType.Other, "   Video (Other)");
+            AddCategoryMapping(1566, TorznabCatType.Other, "   Publications and educational materials (texts)");
+            AddCategoryMapping(1567, TorznabCatType.Other, "   Sports (video)");
             AddCategoryMapping(1569, TorznabCatType.Other, "   Amateur videos");
         }
 
@@ -1598,10 +1598,10 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("ucp.php?mode=logout&"), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("ucp.php?mode=logout&"), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
@@ -1609,113 +1609,113 @@ namespace Jackett.Indexers
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            WebClientStringResult results = null;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("st", "0");
-            queryCollection.Add("sd", "d");
-            queryCollection.Add("sk", "t");
-            queryCollection.Add("tracker_search", "torrent");
-            queryCollection.Add("t", "0");
-            queryCollection.Add("submit", "Search");
-            queryCollection.Add("sr", "topics");
-            //queryCollection.Add("sr", "posts");
-            //queryCollection.Add("ch", "99999");
-
-            // if the search string is empty use the getnew view
-            if (string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search_id", "newposts");
+            var searchString = query.GetQueryString();
+
+            WebClientStringResult results = null;
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("st", "0");
+            queryCollection.Add("sd", "d");
+            queryCollection.Add("sk", "t");
+            queryCollection.Add("tracker_search", "torrent");
+            queryCollection.Add("t", "0");
+            queryCollection.Add("submit", "Search");
+            queryCollection.Add("sr", "topics");
+            //queryCollection.Add("sr", "posts");
+            //queryCollection.Add("ch", "99999");
+
+            // if the search string is empty use the getnew view
+            if (string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search_id", "newposts");
             }
-            else // use the normal search
-            {
-                searchString = searchString.Replace("-", " ");
-                queryCollection.Add("terms", "all");
-                queryCollection.Add("keywords", searchString);
-                queryCollection.Add("author", "");
-                queryCollection.Add("sc", "1");
-                queryCollection.Add("sf", "titleonly");
+            else // use the normal search
+            {
+                searchString = searchString.Replace("-", " ");
+                queryCollection.Add("terms", "all");
+                queryCollection.Add("keywords", searchString);
+                queryCollection.Add("author", "");
+                queryCollection.Add("sc", "1");
+                queryCollection.Add("sf", "titleonly");
             }
 
             var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
-            results = await RequestStringWithCookies(searchUrl);
+            results = await RequestStringWithCookies(searchUrl);
             try
             {
                 string RowsSelector = "ul.topics > li";
 
-                var SearchResultParser = new HtmlParser();
+                var SearchResultParser = new HtmlParser();
                 var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                foreach (var Row in Rows)
+                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                foreach (var Row in Rows)
                 {
-                    try
+                    try
                     {
                         var release = new ReleaseInfo();
 
-                        release.MinimumRatio = 1;
+                        release.MinimumRatio = 1;
                         release.MinimumSeedTime = 0;
-
-                        var qDetailsLink = Row.QuerySelector("a.topictitle");
-                        var qDownloadLink = Row.QuerySelector("a[href^=\"./download/file.php?id=\"]");
-                        
-                        release.Title = qDetailsLink.TextContent;
-                        release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
-                        release.Link = new Uri(SiteLink + qDownloadLink.GetAttribute("href"));
-                        release.Guid = release.Comments;
-
-                        release.Seeders = ParseUtil.CoerceInt(Row.QuerySelector("span.seed").TextContent);
-                        release.Peers = ParseUtil.CoerceInt(Row.QuerySelector("span.leech").TextContent) + release.Seeders;
-                        release.Grabs = ParseUtil.CoerceLong(Row.QuerySelector("span.complet").TextContent);
-
-                        var author = Row.QuerySelector("a[href^=\"./memberlist.php?mode=viewprofile&\"]");
-                        var timestr = author.NextSibling.NodeValue.Substring(3).Split('\n')[0].Trim();
-
-                        timestr = timestr.Replace("менее минуты назад", "now");
-                        timestr = timestr.Replace("назад", "ago");
-                        timestr = timestr.Replace("минуту", "minute");
-                        timestr = timestr.Replace("минуты", "minutes");
-                        timestr = timestr.Replace("минут", "minutes");
-
-                        timestr = timestr.Replace("Сегодня", "Today");
-                        timestr = timestr.Replace("Вчера", "Yesterday"); // untested
-
-                        timestr = timestr.Replace("янв", "Jan");
-                        timestr = timestr.Replace("фев", "Feb");
-                        timestr = timestr.Replace("мар", "Mar");
-                        timestr = timestr.Replace("апр", "Apr");
-                        timestr = timestr.Replace("май", "May");
-                        timestr = timestr.Replace("июн", "Jun");
-                        timestr = timestr.Replace("июл", "Jul");
-                        timestr = timestr.Replace("авг", "Aug");
-                        timestr = timestr.Replace("сен", "Sep");
-                        timestr = timestr.Replace("окт", "Oct");
-                        timestr = timestr.Replace("ноя", "Nov");
-                        timestr = timestr.Replace("дек", "Dec");
-                        release.PublishDate = DateTimeUtil.FromUnknown(timestr, "UK");
-
-                        var forum = Row.QuerySelector("a[href^=\"./viewforum.php?f=\"]");
-                        var forumid = forum.GetAttribute("href").Split('=')[1];
-                        release.Category = MapTrackerCatToNewznab(forumid);
-
-                        var size = forum.NextElementSibling;
-                        var sizestr = size.TextContent;
-                        sizestr = sizestr.Replace("ГБ", "GB");
-                        sizestr = sizestr.Replace("МБ", "MB");
-                        sizestr = sizestr.Replace("КБ", "KB"); // untested
-                        release.Size = ReleaseInfo.GetBytes(sizestr);
-
-                        release.DownloadVolumeFactor = 1;
-                        release.UploadVolumeFactor = 1;
 
-                        releases.Add(release);
-                    }
-                    catch (Exception ex)
-                    {
-                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
+                        var qDetailsLink = Row.QuerySelector("a.topictitle");
+                        var qDownloadLink = Row.QuerySelector("a[href^=\"./download/file.php?id=\"]");
+                        
+                        release.Title = qDetailsLink.TextContent;
+                        release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
+                        release.Link = new Uri(SiteLink + qDownloadLink.GetAttribute("href"));
+                        release.Guid = release.Comments;
+
+                        release.Seeders = ParseUtil.CoerceInt(Row.QuerySelector("span.seed").TextContent);
+                        release.Peers = ParseUtil.CoerceInt(Row.QuerySelector("span.leech").TextContent) + release.Seeders;
+                        release.Grabs = ParseUtil.CoerceLong(Row.QuerySelector("span.complet").TextContent);
+
+                        var author = Row.QuerySelector("a[href^=\"./memberlist.php?mode=viewprofile&\"]");
+                        var timestr = author.NextSibling.NodeValue.Substring(3).Split('\n')[0].Trim();
+
+                        timestr = timestr.Replace("менее минуты назад", "now");
+                        timestr = timestr.Replace("назад", "ago");
+                        timestr = timestr.Replace("минуту", "minute");
+                        timestr = timestr.Replace("минуты", "minutes");
+                        timestr = timestr.Replace("минут", "minutes");
+
+                        timestr = timestr.Replace("Сегодня", "Today");
+                        timestr = timestr.Replace("Вчера", "Yesterday"); // untested
+
+                        timestr = timestr.Replace("янв", "Jan");
+                        timestr = timestr.Replace("фев", "Feb");
+                        timestr = timestr.Replace("мар", "Mar");
+                        timestr = timestr.Replace("апр", "Apr");
+                        timestr = timestr.Replace("май", "May");
+                        timestr = timestr.Replace("июн", "Jun");
+                        timestr = timestr.Replace("июл", "Jul");
+                        timestr = timestr.Replace("авг", "Aug");
+                        timestr = timestr.Replace("сен", "Sep");
+                        timestr = timestr.Replace("окт", "Oct");
+                        timestr = timestr.Replace("ноя", "Nov");
+                        timestr = timestr.Replace("дек", "Dec");
+                        release.PublishDate = DateTimeUtil.FromUnknown(timestr, "UK");
+
+                        var forum = Row.QuerySelector("a[href^=\"./viewforum.php?f=\"]");
+                        var forumid = forum.GetAttribute("href").Split('=')[1];
+                        release.Category = MapTrackerCatToNewznab(forumid);
+
+                        var size = forum.NextElementSibling;
+                        var sizestr = size.TextContent;
+                        sizestr = sizestr.Replace("ГБ", "GB");
+                        sizestr = sizestr.Replace("МБ", "MB");
+                        sizestr = sizestr.Replace("КБ", "KB"); // untested
+                        release.Size = ReleaseInfo.GetBytes(sizestr);
+
+                        release.DownloadVolumeFactor = 1;
+                        release.UploadVolumeFactor = 1;
+
+                        releases.Add(release);
+                    }
+                    catch (Exception ex)
+                    {
+                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
                     }
-                }
+                }
             }
             catch (Exception ex)
             {
diff --git a/src/Jackett/Indexers/Abnormal.cs b/src/Jackett/Indexers/Abnormal.cs
index c9948062692cbf069d68d4653870c99f2263c612..56bd2ca96c97a111c666ae7ba1f0d7ed8bf17427 100644
--- a/src/Jackett/Indexers/Abnormal.cs
+++ b/src/Jackett/Indexers/Abnormal.cs
@@ -1,883 +1,883 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Web;
-using CsQuery;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig.Bespoke;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using NLog;
-
-namespace Jackett.Indexers
-{
-    /// <summary>
-    /// Provider for Abnormal Private French Tracker
-    /// </summary>
-    public class Abnormal : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "login.php"; } }
-        private string SearchUrl { get { return SiteLink + "torrents.php"; } }
-        private string TorrentCommentUrl { get { return TorrentDescriptionUrl; } }
-        private string TorrentDescriptionUrl { get { return SiteLink + "torrents.php?id="; } }
-        private string TorrentDownloadUrl { get { return SiteLink + "torrents.php?action=download&id={id}&authkey={auth_key}&torrent_pass={torrent_pass}"; } }
-        private bool Latency { get { return ConfigData.Latency.Value; } }
-        private bool DevMode { get { return ConfigData.DevMode.Value; } }
-        private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
-        private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
-
-        private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
-        private CQ fDom = null;
-
-        private ConfigurationDataAbnormal ConfigData
-        {
-            get { return (ConfigurationDataAbnormal)configData; }
-            set { base.configData = value; }
-        }
-
-        public Abnormal(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
-            : base(
-                name: "Abnormal",
-                description: "General French Private Tracker",
-                link: "https://abnormal.ws/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                downloadBase: "https://abnormal.ws/torrents.php?action=download&id=",
-                configData: new ConfigurationDataAbnormal())
-        {
-            Language = "fr-fr";
-            Encoding = Encoding.UTF8;
-            Type = "private";
-
-            // Clean capabilities
-            TorznabCaps.Categories.Clear();
-
-            // Movies
-            AddCategoryMapping("MOVIE|DVDR", TorznabCatType.MoviesDVD);             // DVDR
-            AddCategoryMapping("MOVIE|DVDRIP", TorznabCatType.MoviesSD);            // DVDRIP
-            AddCategoryMapping("MOVIE|BDRIP", TorznabCatType.MoviesSD);             // BDRIP
-            AddCategoryMapping("MOVIE|VOSTFR", TorznabCatType.MoviesOther);         // VOSTFR
-            AddCategoryMapping("MOVIE|HD|720p", TorznabCatType.MoviesHD);           // HD 720P
-            AddCategoryMapping("MOVIE|HD|1080p", TorznabCatType.MoviesHD);          // HD 1080P
-            AddCategoryMapping("MOVIE|REMUXBR", TorznabCatType.MoviesBluRay);       // REMUX BLURAY
-            AddCategoryMapping("MOVIE|FULLBR", TorznabCatType.MoviesBluRay);        // FULL BLURAY
-
-            // Series
-            AddCategoryMapping("TV|SD|VOSTFR", TorznabCatType.TV);                  // SD VOSTFR
-            AddCategoryMapping("TV|HD|VOSTFR", TorznabCatType.TVHD);                // HD VOSTFR
-            AddCategoryMapping("TV|SD|VF", TorznabCatType.TVSD);                    // SD VF
-            AddCategoryMapping("TV|HD|VF", TorznabCatType.TVHD);                    // HD VF
-            AddCategoryMapping("TV|PACK|FR", TorznabCatType.TVOTHER);               // PACK FR
-            AddCategoryMapping("TV|PACK|VOSTFR", TorznabCatType.TVOTHER);           // PACK VOSTFR
-            AddCategoryMapping("TV|EMISSIONS", TorznabCatType.TVOTHER);             // EMISSIONS
-
-            // Anime
-            AddCategoryMapping("ANIME", TorznabCatType.TVAnime);                    // ANIME
-
-            // Documentaries
-            AddCategoryMapping("DOCS", TorznabCatType.TVDocumentary);               // DOCS
-
-            // Music
-            AddCategoryMapping("MUSIC|FLAC", TorznabCatType.AudioLossless);         // FLAC
-            AddCategoryMapping("MUSIC|MP3", TorznabCatType.AudioMP3);               // MP3
-            AddCategoryMapping("MUSIC|CONCERT", TorznabCatType.AudioVideo);         // CONCERT
-
-            // Other
-            AddCategoryMapping("PC|APP", TorznabCatType.PC);                        // PC
-            AddCategoryMapping("PC|GAMES", TorznabCatType.PCGames);                 // GAMES
-            AddCategoryMapping("EBOOKS", TorznabCatType.BooksEbook);                // EBOOKS
-        }
-
-        /// <summary>
-        /// Configure our WiHD Provider
-        /// </summary>
-        /// <param name="configJson">Our params in Json</param>
-        /// <returns>Configuration state</returns>
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            // Retrieve config values set by Jackett's user
-            LoadValuesFromJson(configJson);
-
-            // Check & Validate Config
-            validateConfig();
-
-            // Setting our data for a better emulated browser (maximum security)
-            // TODO: Encoded Content not supported by Jackett at this time
-            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
-
-            // If we want to simulate a browser
-            if (ConfigData.Browser.Value) {
-
-                // Clean headers
-                emulatedBrowserHeaders.Clear();
-
-                // Inject headers
-                emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
-                emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
-                emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
-                emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
-                emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
-            }
-
-
-            // Getting login form to retrieve CSRF token
-            var myRequest = new Utils.Clients.WebRequest()
-            {
-                Url = LoginUrl
-            };
-
-            // Add our headers to request
-            myRequest.Headers = emulatedBrowserHeaders;
-
-            // Building login form data
-            var pairs = new Dictionary<string, string> {
-                { "username", ConfigData.Username.Value },
-                { "password", ConfigData.Password.Value },
-                { "keeplogged", "1" },
-                { "login", "Connexion" }
-            };
-
-            // Do the login
-            var request = new Utils.Clients.WebRequest(){
-                PostData = pairs,
-                Referer = LoginUrl,
-                Type = RequestType.POST,
-                Url = LoginUrl,
-                Headers = emulatedBrowserHeaders
-            };
-
-            // Perform loggin
-            latencyNow();
-            output("\nPerform loggin.. with " + LoginUrl);
-            var response = await webclient.GetString(request);
-
-            // Test if we are logged in
-            await ConfigureIfOK(response.Cookies, response.Cookies.Contains("session="), () =>
-            {
-                // Parse error page
-                CQ dom = response.Content;
-                string message = dom[".warning"].Text().Split('.').Reverse().Skip(1).First();
-
-                // Try left
-                string left = dom[".info"].Text().Trim();
-
-                // Oops, unable to login
-                output("-> Login failed: \"" + message + "\" and " + left + " tries left before being banned for 6 hours !", "error");
-                throw new ExceptionWithConfigData("Login failed: " + message, configData);
-            });
-
-            output("-> Login Success");
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        /// <summary>
-        /// Execute our search query
-        /// </summary>
-        /// <param name="query">Query</param>
-        /// <returns>Releases</returns>
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var torrentRowList = new List<CQ>();
-            var searchTerm = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            int nbResults = 0;
-            int pageLinkCount = 0;
-
-            // Check cache first so we don't query the server (if search term used or not in dev mode)
-            if(!DevMode && !string.IsNullOrEmpty(searchTerm))
-            {
-                lock (cache)
-                {
-                    // Remove old cache items
-                    CleanCache();
-
-                    // Search in cache
-                    var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
-                    if (cachedResult != null)
-                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
-                }
-            }
-
-            // Build our query
-            var request = buildQuery(searchTerm, query, searchUrl);
-
-            // Getting results & Store content
-            WebClientStringResult results = await queryExec(request);
-            fDom = results.Content;
-
-            try
-            {
-                // Find torrent rows
-                var firstPageRows = findTorrentRows();
-
-                // Add them to torrents list
-                torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
-
-                // Check if there are pagination links at bottom
-                Boolean pagination = (fDom[".linkbox > a"].Length != 0);
-
-                // If pagination available
-                if (pagination) {
-                    // Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
-                    pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom[".linkbox > a"].Last().Attr("href").ToString(), @"\d+").Value);
-
-                    // Calculate average number of results (based on torrents rows lenght on first page)
-                    nbResults = firstPageRows.Count() * pageLinkCount;
-                }
-                else {
-                    // Check if we have a minimum of one result
-                    if (firstPageRows.Length >= 1)
-                    {
-                        // Retrieve total count on our alone page
-                        nbResults = firstPageRows.Count();
-                        pageLinkCount = 1;
-                    }
-                    else
-                    {
-                        output("\nNo result found for your query, please try another search term ...\n", "info");
-                        // No result found for this query
-                        return releases;
-                    }
-                }
-                output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
-                output("\nThere are " + firstPageRows.Length + " results on the first page !");
-
-                // If we have a term used for search and pagination result superior to one
-                if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
-                {
-                    // Starting with page #2
-                    for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
-                    {
-                        output("\nProcessing page #" + i);
-
-                        // Request our page
-                        latencyNow();
-
-                        // Build our query
-                        var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
-
-                        // Getting results & Store content
-                        WebClientStringResult pageResults = await queryExec(pageRequest);
-
-                        // Assign response
-                        fDom = pageResults.Content;
-
-                        // Process page results
-                        var additionalPageRows = findTorrentRows();
-
-                        // Add them to torrents list
-                        torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
-                    }
-                }
-                else
-                {
-                    // No search term, maybe testing... so registring autkey and torrentpass for future uses
-                    string infosData = firstPageRows.First().Find("td:eq(3) > a").Attr("href");
-                    IList<string> infosList = infosData.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
-                    IList<string> infosTracker = infosList.Select(s => s.Split(new[] { '=' }, 2)[1].Trim()).ToList();
-
-                    output("\nStoring Authkey for future uses...");
-                    ConfigData.AuthKey.Value = infosTracker[2];
-
-                    output("\nStoring TorrentPass for future uses...");
-                    ConfigData.TorrentPass.Value = infosTracker[3];
-
-                }
-
-                // Loop on results
-                foreach (CQ tRow in torrentRowList)
-                {
-                    output("\n=>> Torrent #" + (releases.Count + 1));
-
-                    // ID
-                    int id = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1) > a").Attr("href").ToString(), @"\d+").Value);
-                    output("ID: " + id);
-
-                    // Release Name
-                    string name = tRow.Find("td:eq(1) > a").Text().ToString();
-                    output("Release: " + name);
-
-                    // Category
-                    string categoryID = tRow.Find("td:eq(0) > a").Attr("href").Replace("torrents.php?cat[]=", String.Empty);
-                    output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");
-
-                    // Seeders
-                    int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
-                    output("Seeders: " + seeders);
-
-                    // Leechers
-                    int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6)").Text(), @"\d+").Value);
-                    output("Leechers: " + leechers);
-
-                    // Completed
-                    int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
-                    output("Completed: " + completed);
-
-                    // Size
-                    string sizeStr = tRow.Find("td:eq(4)").Text().Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb");
-                    long size = ReleaseInfo.GetBytes(sizeStr);
-                    output("Size: " + sizeStr + " (" + size + " bytes)");
-
-                    // Publish DateToString
-                    IList<string> clockList = tRow.Find("td:eq(2) > span").Text().Replace("Il y a", "").Split(',').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
-                    var date = agoToDate(clockList);
-                    output("Released on: " + date.ToLocalTime());
-
-                    // Torrent Details URL
-                    Uri detailsLink = new Uri(TorrentDescriptionUrl + id);
-                    output("Details: " + detailsLink.AbsoluteUri);
-
-                    // Torrent Comments URL
-                    Uri commentsLink = new Uri(TorrentCommentUrl + id);
-                    output("Comments Link: " + commentsLink.AbsoluteUri);
-
-                    // Torrent Download URL
-                    Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{auth_key}", ConfigData.AuthKey.Value).Replace("{torrent_pass}", ConfigData.TorrentPass.Value));
-                    output("Download Link: " + downloadLink.AbsoluteUri);
-
-                    // Building release infos
-                    var release = new ReleaseInfo();
-                    release.Category = MapTrackerCatToNewznab(categoryID.ToString());
-                    release.Title = name;
-                    release.Seeders = seeders;
-                    release.Peers = seeders + leechers;
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-                    release.PublishDate = date;
-                    release.Size = size;
-                    release.Guid = detailsLink;
-                    release.Comments = commentsLink;
-                    release.Link = downloadLink;
-
-                    // freeleech
-                    if (tRow.Find("img[alt=\"Freeleech\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
-                    else
-                        release.DownloadVolumeFactor = 1;
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-
-            }
-            catch (Exception ex)
-            {
-                OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
-            }
-
-            // Return found releases
-            return releases;
-        }
-
-        /// <summary>
-        /// Build query to process
-        /// </summary>
-        /// <param name="term">Term to search</param>
-        /// <param name="query">Torznab Query for categories mapping</param>
-        /// <param name="url">Search url for provider</param>
-        /// <param name="page">Page number to request</param>
-        /// <returns>URL to query for parsing and processing results</returns>
-        private string buildQuery(string term, TorznabQuery query, string url, int page = 0)
-        {
-            var parameters = new NameValueCollection();
-            List<string> categoriesList = MapTorznabCapsToTrackers(query);
-            string categories = null;
-
-            // Check if we are processing a new page
-            if (page > 0)
-            {
-                // Adding page number to query
-                parameters.Add("page", page.ToString());
-            }
-
-            // Loop on Categories needed
-            foreach (string category in categoriesList)
-            {
-                // If last, build !
-                if (categoriesList.Last() == category)
-                {
-                    // Adding previous categories to URL with latest category
-                    parameters.Add(Uri.EscapeDataString("cat[]"), HttpUtility.UrlEncode(category) + categories);
-                }
-                else
-                {
-                    // Build categories parameter
-                    categories += "&" + Uri.EscapeDataString("cat[]") + "=" + HttpUtility.UrlEncode(category);
-                }
-            }
-
-            // If search term provided
-            if (!string.IsNullOrWhiteSpace(term))
-            {
-                // Add search term
-                parameters.Add("search", HttpUtility.UrlEncode(term));
-            }
-            else
-            {
-                parameters.Add("search", HttpUtility.UrlEncode("%"));
-                // Showing all torrents (just for output function)
-                term = "all";
-            }
-
-            // Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong cat[] param)
-            url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
-
-            output("\nBuilded query for \"" + term + "\"... " + url);
-
-            // Return our search url
-            return url;
-        }
-
-        /// <summary>
-        /// Switch Method for Querying
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> queryExec(string request)
-        {
-            WebClientStringResult results = null;
-
-            // Switch in we are in DEV mode with Hard Drive Cache or not
-            if (DevMode && CacheMode)
-            {
-                // Check Cache before querying and load previous results if available
-                results = await queryCache(request);
-            }
-            else
-            {
-                // Querying tracker directly
-                results = await queryTracker(request);
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Cache by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> queryCache(string request)
-        {
-            WebClientStringResult results = null;
-
-            // Create Directory if not exist
-            System.IO.Directory.CreateDirectory(directory);
-
-            // Clean Storage Provider Directory from outdated cached queries
-            cleanCacheStorage();
-
-            // Create fingerprint for request
-            string file = directory + request.GetHashCode() + ".json";
-
-            // Checking modes states
-            if (System.IO.File.Exists(file))
-            {
-                // File exist... loading it right now !
-                output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
-                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
-            }
-            else
-            {
-                // No cached file found, querying tracker directly
-                results = await queryTracker(request);
-
-                // Cached file didn't exist for our query, writing it right now !
-                output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
-                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Tracker by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> queryTracker(string request)
-        {
-            WebClientStringResult results = null;
-
-            // Cache mode not enabled or cached file didn't exist for our query
-            output("\nQuerying tracker for results....");
-
-            // Request our first page
-            latencyNow();
-            results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
-
-            // Return results from tracker
-            return results;
-        }
-
-        /// <summary>
-        /// Clean Hard Drive Cache Storage
-        /// </summary>
-        /// <param name="force">Force Provider Folder deletion</param>
-        private void cleanCacheStorage(Boolean force = false)
-        {
-            // Check cleaning method
-            if(force)
-            {
-                // Deleting Provider Storage folder and all files recursively
-                output("\nDeleting Provider Storage folder and all files recursively ...");
-                
-                // Check if directory exist
-                if(System.IO.Directory.Exists(directory))
-                {
-                    // Delete storage directory of provider
-                    System.IO.Directory.Delete(directory, true);
-                    output("-> Storage folder deleted successfully.");
-                }
-                else
-                {
-                    // No directory, so nothing to do
-                    output("-> No Storage folder found for this provider !");
-                }
-            }
-            else
-            {
-                int i = 0;
-                // Check if there is file older than ... and delete them
-                output("\nCleaning Provider Storage folder... in progress.");
-                System.IO.Directory.GetFiles(directory)
-                .Select(f => new System.IO.FileInfo(f))
-                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
-                .ToList()
-                .ForEach(f => {
-                    output("Deleting cached file << " + f.Name + " >> ... done.");
-                    f.Delete();
-                    i++;
-                    });
-
-                // Inform on what was cleaned during process
-                if(i > 0) {
-                    output("-> Deleted " + i + " cached files during cleaning.");
-                }
-                else {
-                    output("-> Nothing deleted during cleaning.");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Generate a random fake latency to avoid detection on tracker side
-        /// </summary>
-        private void latencyNow()
-        {
-            // Need latency ?
-            if(Latency)
-            {
-                // Generate a random value in our range
-                var random = new Random(DateTime.Now.Millisecond);
-                int waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value), Convert.ToInt32(ConfigData.LatencyEnd.Value));
-                output("\nLatency Faker => Sleeping for " + waiting + " ms...");
-
-                // Sleep now...
-                System.Threading.Thread.Sleep(waiting);
-            }
-        }
-
-        /// <summary>
-        /// Find torrent rows in search pages
-        /// </summary>
-        /// <returns>JQuery Object</returns>
-        private CQ findTorrentRows()
-        {
-            // Return all occurencis of torrents found
-            return fDom[".torrent_table > tbody > tr"].Not(".colhead");
-        }
-
-        /// <summary>
-        /// Convert Ago date to DateTime
-        /// </summary>
-        /// <param name="clockList"></param>
-        /// <returns>A DateTime</returns>
-        private DateTime agoToDate(IList<string> clockList)
-        {
-            DateTime release = DateTime.Now;
-            foreach (var ago in clockList)
-            {
-                // Check for years
-                if (ago.Contains("années") || ago.Contains("année"))
-                {
-                    // Number of years to remove
-                    int years = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddYears(-years);
-
-                    continue;
-                }
-                // Check for months
-                else if (ago.Contains("mois"))
-                {
-                    // Number of months to remove
-                    int months = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddMonths(-months);
-
-                    continue;
-                }
-                // Check for weeks
-                else if (ago.Contains("semaines") || ago.Contains("semaine"))
-                {
-                    // Number of weeks to remove
-                    int weeks = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddDays(-(7 * weeks));
-
-                    continue;
-                }
-                // Check for days
-                else if (ago.Contains("jours") || ago.Contains("jour"))
-                {
-                    // Number of days to remove
-                    int days = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddDays(-days);
-
-                    continue;
-                }
-                // Check for hours
-                else if (ago.Contains("heures") || ago.Contains("heure"))
-                {
-                    // Number of hours to remove
-                    int hours = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddHours(-hours);
-
-                    continue;
-                }
-                // Check for minutes
-                else if (ago.Contains("mins") || ago.Contains("min"))
-                {
-                    // Number of minutes to remove
-                    int minutes = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddMinutes(-minutes);
-
-                    continue;
-                }
-                // Check for seconds
-                else if (ago.Contains("secondes") || ago.Contains("seconde"))
-                {
-                    // Number of seconds to remove
-                    int seconds = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
-                    // Removing
-                    release = release.AddSeconds(-seconds);
-
-                    continue;
-                }
-                else
-                {
-                    output("Unable to detect release date of torrent", "error");
-                    //throw new Exception("Unable to detect release date of torrent");
-                }
-            }
-            return release;
-        }
-
-        /// <summary>
-        /// Output message for logging or developpment (console)
-        /// </summary>
-        /// <param name="message">Message to output</param>
-        /// <param name="level">Level for Logger</param>
-        private void output(string message, string level = "debug")
-        {
-            // Check if we are in dev mode
-            if(DevMode)
-            {
-                // Output message to console
-                Console.WriteLine(message);
-            }
-            else
-            {
-                // Send message to logger with level
-                switch (level)
-                {
-                    default:
-                        goto case "debug";
-                    case "debug":
-                        // Only if Debug Level Enabled on Jackett
-                        if (Engine.Logger.IsDebugEnabled)
-                        {
-                            logger.Debug(message);
-                        }
-                        break;
-                    case "info":
-                        logger.Info(message);
-                        break;
-                    case "error":
-                        logger.Error(message);
-                        break;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Validate Config entered by user on Jackett
-        /// </summary>
-        private void validateConfig()
-        {
-            output("\nValidating Settings ... \n");
-
-            // Check Username Setting
-            if (string.IsNullOrEmpty(ConfigData.Username.Value))
-            {
-                throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
-            }
-            else
-            {
-                output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value.ToString());
-            }
-
-            // Check Password Setting
-            if (string.IsNullOrEmpty(ConfigData.Password.Value))
-            {
-                throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
-            }
-            else
-            {
-                output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value.ToString());
-            }
-
-            // Check Max Page Setting
-            if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
-            {
-                try
-                {
-                    output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
-                }
-                catch (Exception)
-                {
-                    throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
-                }
-            }
-            else
-            {
-                throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
-            }
-
-            // Check Latency Setting
-            if (ConfigData.Latency.Value)
-            {
-                output("\nValidated Setting -- Latency Simulation enabled");
-
-                // Check Latency Start Setting
-                if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
-                {
-                    try
-                    {
-                        output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
-                }
-
-                // Check Latency End Setting
-                if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
-                {
-                    try
-                    {
-                        output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
-                }
-            }
-
-            // Check Browser Setting
-            if (ConfigData.Browser.Value)
-            {
-                output("\nValidated Setting -- Browser Simulation enabled");
-
-                // Check ACCEPT header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
-                }
-                else
-                {
-                    output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value.ToString());
-                }
-
-                // Check ACCEPT-LANG header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
-                }
-                else
-                {
-                    output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value.ToString());
-                }
-
-                // Check USER-AGENT header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
-                }
-                else
-                {
-                    output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value.ToString());
-                }
-            }
-
-            // Check Dev Cache Settings
-            if (ConfigData.HardDriveCache.Value == true)
-            {
-                output("\nValidated Setting -- DEV Hard Drive Cache enabled");
-
-                // Check if Dev Mode enabled !
-                if (!ConfigData.DevMode.Value)
-                {
-                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
-                }
-
-                // Check Cache Keep Time Setting
-                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
-                {
-                    try
-                    {
-                        output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
-                }
-            }
-            else
-            {
-                // Delete cache if previously existed
-                cleanCacheStorage(true);
-            }
-        }
-    }
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Web;
+using CsQuery;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig.Bespoke;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NLog;
+
+namespace Jackett.Indexers
+{
+    /// <summary>
+    /// Provider for Abnormal Private French Tracker
+    /// </summary>
+    public class Abnormal : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "login.php"; } }
+        private string SearchUrl { get { return SiteLink + "torrents.php"; } }
+        private string TorrentCommentUrl { get { return TorrentDescriptionUrl; } }
+        private string TorrentDescriptionUrl { get { return SiteLink + "torrents.php?id="; } }
+        private string TorrentDownloadUrl { get { return SiteLink + "torrents.php?action=download&id={id}&authkey={auth_key}&torrent_pass={torrent_pass}"; } }
+        private bool Latency { get { return ConfigData.Latency.Value; } }
+        private bool DevMode { get { return ConfigData.DevMode.Value; } }
+        private bool CacheMode { get { return ConfigData.HardDriveCache.Value; } }
+        private string directory { get { return System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType.Name + "\\"; } }
+
+        private Dictionary<string, string> emulatedBrowserHeaders = new Dictionary<string, string>();
+        private CQ fDom = null;
+
+        private ConfigurationDataAbnormal ConfigData
+        {
+            get { return (ConfigurationDataAbnormal)configData; }
+            set { base.configData = value; }
+        }
+
+        public Abnormal(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
+            : base(
+                name: "Abnormal",
+                description: "General French Private Tracker",
+                link: "https://abnormal.ws/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                downloadBase: "https://abnormal.ws/torrents.php?action=download&id=",
+                configData: new ConfigurationDataAbnormal())
+        {
+            Language = "fr-fr";
+            Encoding = Encoding.UTF8;
+            Type = "private";
+
+            // Clean capabilities
+            TorznabCaps.Categories.Clear();
+
+            // Movies
+            AddCategoryMapping("MOVIE|DVDR", TorznabCatType.MoviesDVD);             // DVDR
+            AddCategoryMapping("MOVIE|DVDRIP", TorznabCatType.MoviesSD);            // DVDRIP
+            AddCategoryMapping("MOVIE|BDRIP", TorznabCatType.MoviesSD);             // BDRIP
+            AddCategoryMapping("MOVIE|VOSTFR", TorznabCatType.MoviesOther);         // VOSTFR
+            AddCategoryMapping("MOVIE|HD|720p", TorznabCatType.MoviesHD);           // HD 720P
+            AddCategoryMapping("MOVIE|HD|1080p", TorznabCatType.MoviesHD);          // HD 1080P
+            AddCategoryMapping("MOVIE|REMUXBR", TorznabCatType.MoviesBluRay);       // REMUX BLURAY
+            AddCategoryMapping("MOVIE|FULLBR", TorznabCatType.MoviesBluRay);        // FULL BLURAY
+
+            // Series
+            AddCategoryMapping("TV|SD|VOSTFR", TorznabCatType.TV);                  // SD VOSTFR
+            AddCategoryMapping("TV|HD|VOSTFR", TorznabCatType.TVHD);                // HD VOSTFR
+            AddCategoryMapping("TV|SD|VF", TorznabCatType.TVSD);                    // SD VF
+            AddCategoryMapping("TV|HD|VF", TorznabCatType.TVHD);                    // HD VF
+            AddCategoryMapping("TV|PACK|FR", TorznabCatType.TVOTHER);               // PACK FR
+            AddCategoryMapping("TV|PACK|VOSTFR", TorznabCatType.TVOTHER);           // PACK VOSTFR
+            AddCategoryMapping("TV|EMISSIONS", TorznabCatType.TVOTHER);             // EMISSIONS
+
+            // Anime
+            AddCategoryMapping("ANIME", TorznabCatType.TVAnime);                    // ANIME
+
+            // Documentaries
+            AddCategoryMapping("DOCS", TorznabCatType.TVDocumentary);               // DOCS
+
+            // Music
+            AddCategoryMapping("MUSIC|FLAC", TorznabCatType.AudioLossless);         // FLAC
+            AddCategoryMapping("MUSIC|MP3", TorznabCatType.AudioMP3);               // MP3
+            AddCategoryMapping("MUSIC|CONCERT", TorznabCatType.AudioVideo);         // CONCERT
+
+            // Other
+            AddCategoryMapping("PC|APP", TorznabCatType.PC);                        // PC
+            AddCategoryMapping("PC|GAMES", TorznabCatType.PCGames);                 // GAMES
+            AddCategoryMapping("EBOOKS", TorznabCatType.BooksEbook);                // EBOOKS
+        }
+
+        /// <summary>
+        /// Configure our WiHD Provider
+        /// </summary>
+        /// <param name="configJson">Our params in Json</param>
+        /// <returns>Configuration state</returns>
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            // Retrieve config values set by Jackett's user
+            LoadValuesFromJson(configJson);
+
+            // Check & Validate Config
+            validateConfig();
+
+            // Setting our data for a better emulated browser (maximum security)
+            // TODO: Encoded Content not supported by Jackett at this time
+            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
+
+            // If we want to simulate a browser
+            if (ConfigData.Browser.Value) {
+
+                // Clean headers
+                emulatedBrowserHeaders.Clear();
+
+                // Inject headers
+                emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
+                emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
+                emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDNT.Value).ToString());
+                emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
+                emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
+            }
+
+
+            // Getting login form to retrieve CSRF token
+            var myRequest = new Utils.Clients.WebRequest()
+            {
+                Url = LoginUrl
+            };
+
+            // Add our headers to request
+            myRequest.Headers = emulatedBrowserHeaders;
+
+            // Building login form data
+            var pairs = new Dictionary<string, string> {
+                { "username", ConfigData.Username.Value },
+                { "password", ConfigData.Password.Value },
+                { "keeplogged", "1" },
+                { "login", "Connexion" }
+            };
+
+            // Do the login
+            var request = new Utils.Clients.WebRequest(){
+                PostData = pairs,
+                Referer = LoginUrl,
+                Type = RequestType.POST,
+                Url = LoginUrl,
+                Headers = emulatedBrowserHeaders
+            };
+
+            // Perform loggin
+            latencyNow();
+            output("\nPerform loggin.. with " + LoginUrl);
+            var response = await webclient.GetString(request);
+
+            // Test if we are logged in
+            await ConfigureIfOK(response.Cookies, response.Cookies.Contains("session="), () =>
+            {
+                // Parse error page
+                CQ dom = response.Content;
+                string message = dom[".warning"].Text().Split('.').Reverse().Skip(1).First();
+
+                // Try left
+                string left = dom[".info"].Text().Trim();
+
+                // Oops, unable to login
+                output("-> Login failed: \"" + message + "\" and " + left + " tries left before being banned for 6 hours !", "error");
+                throw new ExceptionWithConfigData("Login failed: " + message, configData);
+            });
+
+            output("-> Login Success");
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        /// <summary>
+        /// Execute our search query
+        /// </summary>
+        /// <param name="query">Query</param>
+        /// <returns>Releases</returns>
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var torrentRowList = new List<CQ>();
+            var searchTerm = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            int nbResults = 0;
+            int pageLinkCount = 0;
+
+            // Check cache first so we don't query the server (if search term used or not in dev mode)
+            if(!DevMode && !string.IsNullOrEmpty(searchTerm))
+            {
+                lock (cache)
+                {
+                    // Remove old cache items
+                    CleanCache();
+
+                    // Search in cache
+                    var cachedResult = cache.Where(i => i.Query == searchTerm).FirstOrDefault();
+                    if (cachedResult != null)
+                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
+                }
+            }
+
+            // Build our query
+            var request = buildQuery(searchTerm, query, searchUrl);
+
+            // Getting results & Store content
+            WebClientStringResult results = await queryExec(request);
+            fDom = results.Content;
+
+            try
+            {
+                // Find torrent rows
+                var firstPageRows = findTorrentRows();
+
+                // Add them to torrents list
+                torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
+
+                // Check if there are pagination links at bottom
+                Boolean pagination = (fDom[".linkbox > a"].Length != 0);
+
+                // If pagination available
+                if (pagination) {
+                    // Calculate numbers of pages available for this search query (Based on number results and number of torrents on first page)
+                    pageLinkCount = ParseUtil.CoerceInt(Regex.Match(fDom[".linkbox > a"].Last().Attr("href").ToString(), @"\d+").Value);
+
+                    // Calculate average number of results (based on torrents rows lenght on first page)
+                    nbResults = firstPageRows.Count() * pageLinkCount;
+                }
+                else {
+                    // Check if we have a minimum of one result
+                    if (firstPageRows.Length >= 1)
+                    {
+                        // Retrieve total count on our alone page
+                        nbResults = firstPageRows.Count();
+                        pageLinkCount = 1;
+                    }
+                    else
+                    {
+                        output("\nNo result found for your query, please try another search term ...\n", "info");
+                        // No result found for this query
+                        return releases;
+                    }
+                }
+                output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
+                output("\nThere are " + firstPageRows.Length + " results on the first page !");
+
+                // If we have a term used for search and pagination result superior to one
+                if (!string.IsNullOrWhiteSpace(query.GetQueryString()) && pageLinkCount > 1)
+                {
+                    // Starting with page #2
+                    for (int i = 2; i <= Math.Min(Int32.Parse(ConfigData.Pages.Value), pageLinkCount); i++)
+                    {
+                        output("\nProcessing page #" + i);
+
+                        // Request our page
+                        latencyNow();
+
+                        // Build our query
+                        var pageRequest = buildQuery(searchTerm, query, searchUrl, i);
+
+                        // Getting results & Store content
+                        WebClientStringResult pageResults = await queryExec(pageRequest);
+
+                        // Assign response
+                        fDom = pageResults.Content;
+
+                        // Process page results
+                        var additionalPageRows = findTorrentRows();
+
+                        // Add them to torrents list
+                        torrentRowList.AddRange(additionalPageRows.Select(fRow => fRow.Cq()));
+                    }
+                }
+                else
+                {
+                    // No search term, maybe testing... so registring autkey and torrentpass for future uses
+                    string infosData = firstPageRows.First().Find("td:eq(3) > a").Attr("href");
+                    IList<string> infosList = infosData.Split('&').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
+                    IList<string> infosTracker = infosList.Select(s => s.Split(new[] { '=' }, 2)[1].Trim()).ToList();
+
+                    output("\nStoring Authkey for future uses...");
+                    ConfigData.AuthKey.Value = infosTracker[2];
+
+                    output("\nStoring TorrentPass for future uses...");
+                    ConfigData.TorrentPass.Value = infosTracker[3];
+
+                }
+
+                // Loop on results
+                foreach (CQ tRow in torrentRowList)
+                {
+                    output("\n=>> Torrent #" + (releases.Count + 1));
+
+                    // ID
+                    int id = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(1) > a").Attr("href").ToString(), @"\d+").Value);
+                    output("ID: " + id);
+
+                    // Release Name
+                    string name = tRow.Find("td:eq(1) > a").Text().ToString();
+                    output("Release: " + name);
+
+                    // Category
+                    string categoryID = tRow.Find("td:eq(0) > a").Attr("href").Replace("torrents.php?cat[]=", String.Empty);
+                    output("Category: " + MapTrackerCatToNewznab(categoryID) + " (" + categoryID + ")");
+
+                    // Seeders
+                    int seeders = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
+                    output("Seeders: " + seeders);
+
+                    // Leechers
+                    int leechers = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(6)").Text(), @"\d+").Value);
+                    output("Leechers: " + leechers);
+
+                    // Completed
+                    int completed = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(5)").Text(), @"\d+").Value);
+                    output("Completed: " + completed);
+
+                    // Size
+                    string sizeStr = tRow.Find("td:eq(4)").Text().Replace("Go", "gb").Replace("Mo", "mb").Replace("Ko", "kb");
+                    long size = ReleaseInfo.GetBytes(sizeStr);
+                    output("Size: " + sizeStr + " (" + size + " bytes)");
+
+                    // Publish DateToString
+                    IList<string> clockList = tRow.Find("td:eq(2) > span").Text().Replace("Il y a", "").Split(',').Select(s => s.Trim()).Where(s => s != String.Empty).ToList();
+                    var date = agoToDate(clockList);
+                    output("Released on: " + date.ToLocalTime());
+
+                    // Torrent Details URL
+                    Uri detailsLink = new Uri(TorrentDescriptionUrl + id);
+                    output("Details: " + detailsLink.AbsoluteUri);
+
+                    // Torrent Comments URL
+                    Uri commentsLink = new Uri(TorrentCommentUrl + id);
+                    output("Comments Link: " + commentsLink.AbsoluteUri);
+
+                    // Torrent Download URL
+                    Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{auth_key}", ConfigData.AuthKey.Value).Replace("{torrent_pass}", ConfigData.TorrentPass.Value));
+                    output("Download Link: " + downloadLink.AbsoluteUri);
+
+                    // Building release infos
+                    var release = new ReleaseInfo();
+                    release.Category = MapTrackerCatToNewznab(categoryID.ToString());
+                    release.Title = name;
+                    release.Seeders = seeders;
+                    release.Peers = seeders + leechers;
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+                    release.PublishDate = date;
+                    release.Size = size;
+                    release.Guid = detailsLink;
+                    release.Comments = commentsLink;
+                    release.Link = downloadLink;
+
+                    // freeleech
+                    if (tRow.Find("img[alt=\"Freeleech\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
+                    else
+                        release.DownloadVolumeFactor = 1;
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+
+            }
+            catch (Exception ex)
+            {
+                OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
+            }
+
+            // Return found releases
+            return releases;
+        }
+
+        /// <summary>
+        /// Build query to process
+        /// </summary>
+        /// <param name="term">Term to search</param>
+        /// <param name="query">Torznab Query for categories mapping</param>
+        /// <param name="url">Search url for provider</param>
+        /// <param name="page">Page number to request</param>
+        /// <returns>URL to query for parsing and processing results</returns>
+        private string buildQuery(string term, TorznabQuery query, string url, int page = 0)
+        {
+            var parameters = new NameValueCollection();
+            List<string> categoriesList = MapTorznabCapsToTrackers(query);
+            string categories = null;
+
+            // Check if we are processing a new page
+            if (page > 0)
+            {
+                // Adding page number to query
+                parameters.Add("page", page.ToString());
+            }
+
+            // Loop on Categories needed
+            foreach (string category in categoriesList)
+            {
+                // If last, build !
+                if (categoriesList.Last() == category)
+                {
+                    // Adding previous categories to URL with latest category
+                    parameters.Add(Uri.EscapeDataString("cat[]"), HttpUtility.UrlEncode(category) + categories);
+                }
+                else
+                {
+                    // Build categories parameter
+                    categories += "&" + Uri.EscapeDataString("cat[]") + "=" + HttpUtility.UrlEncode(category);
+                }
+            }
+
+            // If search term provided
+            if (!string.IsNullOrWhiteSpace(term))
+            {
+                // Add search term
+                parameters.Add("search", HttpUtility.UrlEncode(term));
+            }
+            else
+            {
+                parameters.Add("search", HttpUtility.UrlEncode("%"));
+                // Showing all torrents (just for output function)
+                term = "all";
+            }
+
+            // Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong cat[] param)
+            url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
+
+            output("\nBuilded query for \"" + term + "\"... " + url);
+
+            // Return our search url
+            return url;
+        }
+
+        /// <summary>
+        /// Switch Method for Querying
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> queryExec(string request)
+        {
+            WebClientStringResult results = null;
+
+            // Switch in we are in DEV mode with Hard Drive Cache or not
+            if (DevMode && CacheMode)
+            {
+                // Check Cache before querying and load previous results if available
+                results = await queryCache(request);
+            }
+            else
+            {
+                // Querying tracker directly
+                results = await queryTracker(request);
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Cache by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> queryCache(string request)
+        {
+            WebClientStringResult results = null;
+
+            // Create Directory if not exist
+            System.IO.Directory.CreateDirectory(directory);
+
+            // Clean Storage Provider Directory from outdated cached queries
+            cleanCacheStorage();
+
+            // Create fingerprint for request
+            string file = directory + request.GetHashCode() + ".json";
+
+            // Checking modes states
+            if (System.IO.File.Exists(file))
+            {
+                // File exist... loading it right now !
+                output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
+                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
+            }
+            else
+            {
+                // No cached file found, querying tracker directly
+                results = await queryTracker(request);
+
+                // Cached file didn't exist for our query, writing it right now !
+                output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
+                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Tracker by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> queryTracker(string request)
+        {
+            WebClientStringResult results = null;
+
+            // Cache mode not enabled or cached file didn't exist for our query
+            output("\nQuerying tracker for results....");
+
+            // Request our first page
+            latencyNow();
+            results = await RequestStringWithCookiesAndRetry(request, null, null, emulatedBrowserHeaders);
+
+            // Return results from tracker
+            return results;
+        }
+
+        /// <summary>
+        /// Clean Hard Drive Cache Storage
+        /// </summary>
+        /// <param name="force">Force Provider Folder deletion</param>
+        private void cleanCacheStorage(Boolean force = false)
+        {
+            // Check cleaning method
+            if(force)
+            {
+                // Deleting Provider Storage folder and all files recursively
+                output("\nDeleting Provider Storage folder and all files recursively ...");
+                
+                // Check if directory exist
+                if(System.IO.Directory.Exists(directory))
+                {
+                    // Delete storage directory of provider
+                    System.IO.Directory.Delete(directory, true);
+                    output("-> Storage folder deleted successfully.");
+                }
+                else
+                {
+                    // No directory, so nothing to do
+                    output("-> No Storage folder found for this provider !");
+                }
+            }
+            else
+            {
+                int i = 0;
+                // Check if there is file older than ... and delete them
+                output("\nCleaning Provider Storage folder... in progress.");
+                System.IO.Directory.GetFiles(directory)
+                .Select(f => new System.IO.FileInfo(f))
+                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
+                .ToList()
+                .ForEach(f => {
+                    output("Deleting cached file << " + f.Name + " >> ... done.");
+                    f.Delete();
+                    i++;
+                    });
+
+                // Inform on what was cleaned during process
+                if(i > 0) {
+                    output("-> Deleted " + i + " cached files during cleaning.");
+                }
+                else {
+                    output("-> Nothing deleted during cleaning.");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Generate a random fake latency to avoid detection on tracker side
+        /// </summary>
+        private void latencyNow()
+        {
+            // Need latency ?
+            if(Latency)
+            {
+                // Generate a random value in our range
+                var random = new Random(DateTime.Now.Millisecond);
+                int waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value), Convert.ToInt32(ConfigData.LatencyEnd.Value));
+                output("\nLatency Faker => Sleeping for " + waiting + " ms...");
+
+                // Sleep now...
+                System.Threading.Thread.Sleep(waiting);
+            }
+        }
+
+        /// <summary>
+        /// Find torrent rows in search pages
+        /// </summary>
+        /// <returns>JQuery Object</returns>
+        private CQ findTorrentRows()
+        {
+            // Return all occurencis of torrents found
+            return fDom[".torrent_table > tbody > tr"].Not(".colhead");
+        }
+
+        /// <summary>
+        /// Convert Ago date to DateTime
+        /// </summary>
+        /// <param name="clockList"></param>
+        /// <returns>A DateTime</returns>
+        private DateTime agoToDate(IList<string> clockList)
+        {
+            DateTime release = DateTime.Now;
+            foreach (var ago in clockList)
+            {
+                // Check for years
+                if (ago.Contains("années") || ago.Contains("année"))
+                {
+                    // Number of years to remove
+                    int years = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddYears(-years);
+
+                    continue;
+                }
+                // Check for months
+                else if (ago.Contains("mois"))
+                {
+                    // Number of months to remove
+                    int months = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddMonths(-months);
+
+                    continue;
+                }
+                // Check for weeks
+                else if (ago.Contains("semaines") || ago.Contains("semaine"))
+                {
+                    // Number of weeks to remove
+                    int weeks = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddDays(-(7 * weeks));
+
+                    continue;
+                }
+                // Check for days
+                else if (ago.Contains("jours") || ago.Contains("jour"))
+                {
+                    // Number of days to remove
+                    int days = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddDays(-days);
+
+                    continue;
+                }
+                // Check for hours
+                else if (ago.Contains("heures") || ago.Contains("heure"))
+                {
+                    // Number of hours to remove
+                    int hours = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddHours(-hours);
+
+                    continue;
+                }
+                // Check for minutes
+                else if (ago.Contains("mins") || ago.Contains("min"))
+                {
+                    // Number of minutes to remove
+                    int minutes = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddMinutes(-minutes);
+
+                    continue;
+                }
+                // Check for seconds
+                else if (ago.Contains("secondes") || ago.Contains("seconde"))
+                {
+                    // Number of seconds to remove
+                    int seconds = ParseUtil.CoerceInt(Regex.Match(ago.ToString(), @"\d+").Value);
+                    // Removing
+                    release = release.AddSeconds(-seconds);
+
+                    continue;
+                }
+                else
+                {
+                    output("Unable to detect release date of torrent", "error");
+                    //throw new Exception("Unable to detect release date of torrent");
+                }
+            }
+            return release;
+        }
+
+        /// <summary>
+        /// Output message for logging or developpment (console)
+        /// </summary>
+        /// <param name="message">Message to output</param>
+        /// <param name="level">Level for Logger</param>
+        private void output(string message, string level = "debug")
+        {
+            // Check if we are in dev mode
+            if(DevMode)
+            {
+                // Output message to console
+                Console.WriteLine(message);
+            }
+            else
+            {
+                // Send message to logger with level
+                switch (level)
+                {
+                    default:
+                        goto case "debug";
+                    case "debug":
+                        // Only if Debug Level Enabled on Jackett
+                        if (Engine.Logger.IsDebugEnabled)
+                        {
+                            logger.Debug(message);
+                        }
+                        break;
+                    case "info":
+                        logger.Info(message);
+                        break;
+                    case "error":
+                        logger.Error(message);
+                        break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Validate Config entered by user on Jackett
+        /// </summary>
+        private void validateConfig()
+        {
+            output("\nValidating Settings ... \n");
+
+            // Check Username Setting
+            if (string.IsNullOrEmpty(ConfigData.Username.Value))
+            {
+                throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
+            }
+            else
+            {
+                output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value.ToString());
+            }
+
+            // Check Password Setting
+            if (string.IsNullOrEmpty(ConfigData.Password.Value))
+            {
+                throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
+            }
+            else
+            {
+                output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value.ToString());
+            }
+
+            // Check Max Page Setting
+            if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
+            {
+                try
+                {
+                    output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
+                }
+                catch (Exception)
+                {
+                    throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
+                }
+            }
+            else
+            {
+                throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
+            }
+
+            // Check Latency Setting
+            if (ConfigData.Latency.Value)
+            {
+                output("\nValidated Setting -- Latency Simulation enabled");
+
+                // Check Latency Start Setting
+                if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
+                {
+                    try
+                    {
+                        output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
+                }
+
+                // Check Latency End Setting
+                if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
+                {
+                    try
+                    {
+                        output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
+                }
+            }
+
+            // Check Browser Setting
+            if (ConfigData.Browser.Value)
+            {
+                output("\nValidated Setting -- Browser Simulation enabled");
+
+                // Check ACCEPT header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
+                }
+                else
+                {
+                    output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value.ToString());
+                }
+
+                // Check ACCEPT-LANG header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
+                }
+                else
+                {
+                    output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value.ToString());
+                }
+
+                // Check USER-AGENT header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
+                }
+                else
+                {
+                    output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value.ToString());
+                }
+            }
+
+            // Check Dev Cache Settings
+            if (ConfigData.HardDriveCache.Value == true)
+            {
+                output("\nValidated Setting -- DEV Hard Drive Cache enabled");
+
+                // Check if Dev Mode enabled !
+                if (!ConfigData.DevMode.Value)
+                {
+                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
+                }
+
+                // Check Cache Keep Time Setting
+                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
+                {
+                    try
+                    {
+                        output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
+                }
+            }
+            else
+            {
+                // Delete cache if previously existed
+                cleanCacheStorage(true);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/Abstract/AvistazTracker.cs b/src/Jackett/Indexers/Abstract/AvistazTracker.cs
index e82cdc34eef5c7cade1c98d20807cff85ad359b6..b3475e359ec7ba2e9aa58091a9e700a8f13e3459 100644
--- a/src/Jackett/Indexers/Abstract/AvistazTracker.cs
+++ b/src/Jackett/Indexers/Abstract/AvistazTracker.cs
@@ -61,7 +61,7 @@ namespace Jackett.Indexers
                 { "email_username", configData.Username.Value },
                 { "password", configData.Password.Value },
                 { "remember", "1" }
-            };
+            };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginUrl);
             await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("auth/logout"), () =>
@@ -90,11 +90,11 @@ namespace Jackett.Indexers
             var episodeSearchUrl = string.Format(SearchUrl, category, HttpUtility.UrlEncode(query.GetQueryString()));
 
             var response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
-            if (response.IsRedirect)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
+            if (response.IsRedirect)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
             }
 
             try
@@ -138,15 +138,15 @@ namespace Jackett.Indexers
                     var grabs = row.Cq().Find("td:nth-child(9)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (row.Cq().Find("i.fa-star").Any())
-                        release.DownloadVolumeFactor = 0;
-                    else if (row.Cq().Find("i.fa-star-half-o").Any())
-                        release.DownloadVolumeFactor = 0.5;
+                    if (row.Cq().Find("i.fa-star").Any())
+                        release.DownloadVolumeFactor = 0;
+                    else if (row.Cq().Find("i.fa-star-half-o").Any())
+                        release.DownloadVolumeFactor = 0.5;
                     else
                         release.DownloadVolumeFactor = 1;
 
-                    if (row.Cq().Find("i.fa-diamond").Any())
-                        release.UploadVolumeFactor = 2;
+                    if (row.Cq().Find("i.fa-diamond").Any())
+                        release.UploadVolumeFactor = 2;
                     else
                         release.UploadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/Abstract/GazelleTracker.cs b/src/Jackett/Indexers/Abstract/GazelleTracker.cs
index 6c7d21548279b03e12ad5f8c0f94e736a1a133e5..de53965073b8eea53e95f7e327ee78387f7f4335 100644
--- a/src/Jackett/Indexers/Abstract/GazelleTracker.cs
+++ b/src/Jackett/Indexers/Abstract/GazelleTracker.cs
@@ -1,27 +1,27 @@
-using AngleSharp.Parser.Html;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-
-namespace Jackett.Indexers.Abstract
-{
+using AngleSharp.Parser.Html;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace Jackett.Indexers.Abstract
+{
     public abstract class GazelleTracker : BaseIndexer
     {
         protected string LoginUrl { get { return SiteLink + "login.php"; } }
         protected string APIUrl { get { return SiteLink + "ajax.php"; } }
-        protected string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
+        protected string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
         protected string DetailsUrl { get { return SiteLink + "torrents.php?torrentid="; } }
 
         new ConfigurationDataBasicLogin configData
@@ -44,199 +44,199 @@ namespace Jackett.Indexers.Abstract
             Encoding = Encoding.GetEncoding("UTF-8");
         }
 
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-            };
-
-            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, string.Empty, true, SiteLink);
-            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php"), () =>
-            {
-                var loginResultParser = new HtmlParser();
-                var loginResultDocument = loginResultParser.Parse(response.Content);
-                var loginform = loginResultDocument.QuerySelector("#loginform");
-                if (loginform == null)
-                    throw new ExceptionWithConfigData(response.Content, configData);
-
-                loginform.QuerySelector("table").Remove();
-                var errorMessage = loginform.TextContent.Replace("\n\t", " ").Trim();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+            };
+
+            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, string.Empty, true, SiteLink);
+            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php"), () =>
+            {
+                var loginResultParser = new HtmlParser();
+                var loginResultDocument = loginResultParser.Parse(response.Content);
+                var loginform = loginResultDocument.QuerySelector("#loginform");
+                if (loginform == null)
+                    throw new ExceptionWithConfigData(response.Content, configData);
+
+                loginform.QuerySelector("table").Remove();
+                var errorMessage = loginform.TextContent.Replace("\n\t", " ").Trim();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            var searchUrl = APIUrl;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("action", "browse");
-            //queryCollection.Add("group_results", "0"); # results won't include all information
-            queryCollection.Add("order_by", "time");
-            queryCollection.Add("order_way", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("searchstr", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("filter_cat[" + cat + "]", "1");
-            }
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var response = await RequestStringWithCookiesAndRetry(searchUrl);
-
-            if (response.IsRedirect || query.IsTest)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(searchUrl);
-            }
-
-            try
-            {
-                var json = JObject.Parse(response.Content);
-                foreach (JObject r in json["response"]["results"])
-                {
-                    var groupTime = DateTimeUtil.UnixTimestampToDateTime(long.Parse((string)r["groupTime"]));
-                    var groupName = HttpUtility.HtmlDecode((string)r["groupName"]);
-                    var artist = HttpUtility.HtmlDecode((string)r["artist"]);
-                    var cover = (string)r["cover"];
-                    var tags = r["tags"].ToList();
-                    var groupYear = (string)r["groupYear"];
-                    var releaseType = (string)r["releaseType"];
-
-                    var release = new ReleaseInfo();
-
-                    release.PublishDate = groupTime;
-
-                    if (!string.IsNullOrEmpty(cover))
-                        release.BannerUrl = new Uri(cover);
-
-                    release.Title = "";
-                    if (!string.IsNullOrEmpty(artist))
-                        release.Title += artist + " - ";
-                    release.Title += groupName;
-                    if (!string.IsNullOrEmpty(groupYear))
-                        release.Title += " [" + groupYear + "]";
-                    if (!string.IsNullOrEmpty(releaseType))
-                        release.Title += " [" + releaseType + "]";
-
-                    release.Description = "";
-                    if (tags != null && tags.Count > 0 && (string)tags[0] != "")
-                        release.Description += "Tags: " + string.Join(", ", tags) + "\n";
-
-                    if (r["torrents"] is JArray)
-                    {
-                        foreach (JObject torrent in r["torrents"])
-                        {
-                            ReleaseInfo release2 = (ReleaseInfo)release.Clone();
-                            FillReleaseInfoFromJson(release2, torrent);
-                            if (ReleaseInfoPostParse(release2, torrent, r))
-                                releases.Add(release2);
-                        }
-                    }
-                    else
-                    {
-                        FillReleaseInfoFromJson(release, r);
-                        if (ReleaseInfoPostParse(release, r, r))
-                            releases.Add(release);
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(response.Content, ex);
-            }
-
-            return releases;
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+
+            var searchUrl = APIUrl;
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("action", "browse");
+            //queryCollection.Add("group_results", "0"); # results won't include all information
+            queryCollection.Add("order_by", "time");
+            queryCollection.Add("order_way", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("searchstr", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("filter_cat[" + cat + "]", "1");
+            }
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var response = await RequestStringWithCookiesAndRetry(searchUrl);
+
+            if (response.IsRedirect || query.IsTest)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(searchUrl);
+            }
+
+            try
+            {
+                var json = JObject.Parse(response.Content);
+                foreach (JObject r in json["response"]["results"])
+                {
+                    var groupTime = DateTimeUtil.UnixTimestampToDateTime(long.Parse((string)r["groupTime"]));
+                    var groupName = HttpUtility.HtmlDecode((string)r["groupName"]);
+                    var artist = HttpUtility.HtmlDecode((string)r["artist"]);
+                    var cover = (string)r["cover"];
+                    var tags = r["tags"].ToList();
+                    var groupYear = (string)r["groupYear"];
+                    var releaseType = (string)r["releaseType"];
+
+                    var release = new ReleaseInfo();
+
+                    release.PublishDate = groupTime;
+
+                    if (!string.IsNullOrEmpty(cover))
+                        release.BannerUrl = new Uri(cover);
+
+                    release.Title = "";
+                    if (!string.IsNullOrEmpty(artist))
+                        release.Title += artist + " - ";
+                    release.Title += groupName;
+                    if (!string.IsNullOrEmpty(groupYear))
+                        release.Title += " [" + groupYear + "]";
+                    if (!string.IsNullOrEmpty(releaseType))
+                        release.Title += " [" + releaseType + "]";
+
+                    release.Description = "";
+                    if (tags != null && tags.Count > 0 && (string)tags[0] != "")
+                        release.Description += "Tags: " + string.Join(", ", tags) + "\n";
+
+                    if (r["torrents"] is JArray)
+                    {
+                        foreach (JObject torrent in r["torrents"])
+                        {
+                            ReleaseInfo release2 = (ReleaseInfo)release.Clone();
+                            FillReleaseInfoFromJson(release2, torrent);
+                            if (ReleaseInfoPostParse(release2, torrent, r))
+                                releases.Add(release2);
+                        }
+                    }
+                    else
+                    {
+                        FillReleaseInfoFromJson(release, r);
+                        if (ReleaseInfoPostParse(release, r, r))
+                            releases.Add(release);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(response.Content, ex);
+            }
+
+            return releases;
         }
 
         // hook to add/modify the parsed information, return false to exclude the torrent from the results
-        protected virtual bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result)
-        {
-            return true;
+        protected virtual bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result)
+        {
+            return true;
         }
 
-        void FillReleaseInfoFromJson(ReleaseInfo release, JObject torrent)
-        {
-            var torrentId = torrent["torrentId"];
-
-            var time = (string)torrent["time"];
-            if (!string.IsNullOrEmpty(time)) {
-                release.PublishDate = DateTime.ParseExact(time+" +0000", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
-            }
-
-            var flags = new List<string>();
-
-            var format = (string)torrent["format"];
-            if (!string.IsNullOrEmpty(format))
-                flags.Add(format);
-
-            var encoding = (string)torrent["encoding"];
-            if (!string.IsNullOrEmpty(encoding))
-                flags.Add(encoding);
-
-            if(torrent["hasLog"] != null && (bool)torrent["hasLog"])
-            {
-                var logScore = (string)torrent["logScore"];
-                flags.Add("Log (" + logScore + "%)");
-            }
-
-            if (torrent["hasCue"] != null && (bool)torrent["hasCue"])
-                flags.Add("Cue");
-
-            var media = (string)torrent["media"];
-            if (!string.IsNullOrEmpty(media))
-                flags.Add(media);
-
-            if (torrent["remastered"] != null && (bool)torrent["remastered"])
-            {
-                var remasterYear = (string)torrent["remasterYear"];
-                var remasterTitle = HttpUtility.HtmlDecode((string)torrent["remasterTitle"]);
-                flags.Add(remasterYear + (!string.IsNullOrEmpty(remasterTitle) ? " " + remasterTitle : ""));
-            }
-
-            if (flags.Count > 0)
-                release.Title += " " + string.Join(" / ", flags);
-
-            release.Size = (long)torrent["size"];
-            release.Seeders = (int)torrent["seeders"];
-            release.Peers = (int)torrent["leechers"] + release.Seeders;
-            release.Comments = new Uri(DetailsUrl + torrentId);
-            release.Guid = release.Comments;
-            release.Link = new Uri(DownloadUrl + torrentId);
-            var category = (string)torrent["category"];
-            if (category == null || category.Contains("Select Category"))
-                release.Category = MapTrackerCatToNewznab("1");
-            else
-                release.Category = MapTrackerCatDescToNewznab(category);
-            release.Files = (int)torrent["fileCount"];
-            release.Grabs = (int)torrent["snatches"];
-            release.DownloadVolumeFactor = 1;
-            release.UploadVolumeFactor = 1;
-            if ((bool)torrent["isFreeleech"])
-            {
-                release.DownloadVolumeFactor = 0;
-            }
-            if ((bool)torrent["isPersonalFreeleech"])
-            {
-                release.DownloadVolumeFactor = 0;
-            }
-            if ((bool)torrent["isNeutralLeech"])
-            {
-                release.DownloadVolumeFactor = 0;
-                release.UploadVolumeFactor = 0;
-            }
+        void FillReleaseInfoFromJson(ReleaseInfo release, JObject torrent)
+        {
+            var torrentId = torrent["torrentId"];
+
+            var time = (string)torrent["time"];
+            if (!string.IsNullOrEmpty(time)) {
+                release.PublishDate = DateTime.ParseExact(time+" +0000", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
+            }
+
+            var flags = new List<string>();
+
+            var format = (string)torrent["format"];
+            if (!string.IsNullOrEmpty(format))
+                flags.Add(format);
+
+            var encoding = (string)torrent["encoding"];
+            if (!string.IsNullOrEmpty(encoding))
+                flags.Add(encoding);
+
+            if(torrent["hasLog"] != null && (bool)torrent["hasLog"])
+            {
+                var logScore = (string)torrent["logScore"];
+                flags.Add("Log (" + logScore + "%)");
+            }
+
+            if (torrent["hasCue"] != null && (bool)torrent["hasCue"])
+                flags.Add("Cue");
+
+            var media = (string)torrent["media"];
+            if (!string.IsNullOrEmpty(media))
+                flags.Add(media);
+
+            if (torrent["remastered"] != null && (bool)torrent["remastered"])
+            {
+                var remasterYear = (string)torrent["remasterYear"];
+                var remasterTitle = HttpUtility.HtmlDecode((string)torrent["remasterTitle"]);
+                flags.Add(remasterYear + (!string.IsNullOrEmpty(remasterTitle) ? " " + remasterTitle : ""));
+            }
+
+            if (flags.Count > 0)
+                release.Title += " " + string.Join(" / ", flags);
+
+            release.Size = (long)torrent["size"];
+            release.Seeders = (int)torrent["seeders"];
+            release.Peers = (int)torrent["leechers"] + release.Seeders;
+            release.Comments = new Uri(DetailsUrl + torrentId);
+            release.Guid = release.Comments;
+            release.Link = new Uri(DownloadUrl + torrentId);
+            var category = (string)torrent["category"];
+            if (category == null || category.Contains("Select Category"))
+                release.Category = MapTrackerCatToNewznab("1");
+            else
+                release.Category = MapTrackerCatDescToNewznab(category);
+            release.Files = (int)torrent["fileCount"];
+            release.Grabs = (int)torrent["snatches"];
+            release.DownloadVolumeFactor = 1;
+            release.UploadVolumeFactor = 1;
+            if ((bool)torrent["isFreeleech"])
+            {
+                release.DownloadVolumeFactor = 0;
+            }
+            if ((bool)torrent["isPersonalFreeleech"])
+            {
+                release.DownloadVolumeFactor = 0;
+            }
+            if ((bool)torrent["isNeutralLeech"])
+            {
+                release.DownloadVolumeFactor = 0;
+                release.UploadVolumeFactor = 0;
+            }
         }
-    }
-}
+    }
+}
diff --git a/src/Jackett/Indexers/AlphaRatio.cs b/src/Jackett/Indexers/AlphaRatio.cs
index b00215b781f236e90707683347b5cdb468460b68..d79da44d1b7c74239e43f5f77a38bea4093f16aa 100644
--- a/src/Jackett/Indexers/AlphaRatio.cs
+++ b/src/Jackett/Indexers/AlphaRatio.cs
@@ -1,219 +1,219 @@
-using CsQuery;
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using System.Net.Http.Headers;
-using Jackett.Models;
-using Jackett.Utils;
-using NLog;
-using Jackett.Services;
-using Jackett.Utils.Clients;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
-namespace Jackett.Indexers
-{
-    public class AlphaRatio : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "login.php"; } }
-        private string SearchUrl { get { return SiteLink + "ajax.php?action=browse&order_by=time&order_way=desc&"; } }
-        private string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
-        private string GuidUrl { get { return SiteLink + "torrents.php?torrentid="; } }
-
-        public AlphaRatio(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
-            : base(name: "AlphaRatio",
-                description: "Legendary",
-                link: "https://alpharatio.cc/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                downloadBase: "https://alpharatio.cc/torrents.php?action=download&id=",
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(1, TorznabCatType.TVSD);
-            AddCategoryMapping(2, TorznabCatType.TVHD);
-            AddCategoryMapping(3, TorznabCatType.TVSD);
-            AddCategoryMapping(4, TorznabCatType.TVSD);
-            AddCategoryMapping(5, TorznabCatType.TVHD);
-            AddCategoryMapping(6, TorznabCatType.MoviesSD);
-            AddCategoryMapping(7, TorznabCatType.MoviesHD);
-            AddCategoryMapping(8, TorznabCatType.MoviesSD);
-            AddCategoryMapping(9, TorznabCatType.MoviesHD);
-            AddCategoryMapping(10, TorznabCatType.XXX);
-            AddCategoryMapping(20, TorznabCatType.XXX);
-            AddCategoryMapping(12, TorznabCatType.PCGames);
-            AddCategoryMapping(13, TorznabCatType.ConsoleXbox);
-            AddCategoryMapping(14, TorznabCatType.ConsolePS3);
-            AddCategoryMapping(15, TorznabCatType.ConsoleWii);
-            AddCategoryMapping(16, TorznabCatType.PC);
-            AddCategoryMapping(17, TorznabCatType.PCMac);
-            AddCategoryMapping(19, TorznabCatType.PCPhoneOther);
-            AddCategoryMapping(21, TorznabCatType.BooksEbook);
-            AddCategoryMapping(22, TorznabCatType.AudioAudiobook);
-            AddCategoryMapping(23, TorznabCatType.Audio);
-        }
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "login", "Login" },
-                { "keeplogged", "1" }
-            };
-
-            // Do the login
-            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, string.Empty, true, SiteLink);
-            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php?"), () =>
-               {
-                   CQ dom = response.Content;
-                   dom["#loginform > table"].Remove();
-                   var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
-                   throw new ExceptionWithConfigData(errorMessage, configData);
-               });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        void FillReleaseInfoFromJson(ReleaseInfo release, JObject r)
-        {
-            var id = r["torrentId"];
-            release.Size = (long)r["size"];
-            release.Seeders = (int)r["seeders"];
-            release.Peers = (int)r["leechers"] + release.Seeders;
-            release.Guid = new Uri(GuidUrl + id);
-            release.Comments = release.Guid;
-            release.Link = new Uri(DownloadUrl + id);
-            release.Category = MapTrackerCatToNewznab(CategoryReverseMapper((string)r["category"]));
-            release.Files = (int)r["fileCount"];
-            release.Grabs = (int)r["snatches"];
-            release.DownloadVolumeFactor = 1;
-            release.UploadVolumeFactor = 1;
-            if ((bool)r["isFreeleech"])
-            {
-                release.DownloadVolumeFactor = 0;
-            }
-            if ((bool)r["isPersonalFreeleech"])
-            {
-                release.DownloadVolumeFactor = 0;
-            }
-            if ((bool)r["isNeutralLeech"])
-            {
-                release.DownloadVolumeFactor = 0;
-                release.UploadVolumeFactor = 0;
-            }
-
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("searchstr", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("filter_cat[" + cat + "]", "1");
-            }
-
-            searchUrl += queryCollection.GetQueryString();
-            var response = await RequestStringWithCookiesAndRetry(searchUrl);
-            if (response.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(searchUrl);
-            }
-
-            try
-            {
-                var json = JObject.Parse(response.Content);
-                foreach (JObject r in json["response"]["results"])
-                {
-                    DateTime pubDate = DateTime.MinValue;
-                    double dateNum;
-                    if (double.TryParse((string)r["groupTime"], out dateNum))
-                        pubDate = UnixTimestampToDateTime(dateNum);
-
-                    var groupName = (string)r["groupName"];
-
-                    if (r["torrents"] is JArray)
-                    {
-                        foreach (JObject t in r["torrents"])
-                        {
-                            var release = new ReleaseInfo();
-                            release.PublishDate = pubDate;
-                            release.Title = groupName;
-                            release.Description = groupName;
-                            FillReleaseInfoFromJson(release, t);
-                            releases.Add(release);
-                        }
-                    }
-                    else
-                    {
-                        var release = new ReleaseInfo();
-                        release.PublishDate = pubDate;
-                        release.Title = groupName;
-                        release.Description = groupName;
-                        FillReleaseInfoFromJson(release, r);
-                        releases.Add(release);
-                    }
-
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(response.Content, ex);
-            }
-
-            return releases;
-        }
-
-        static DateTime UnixTimestampToDateTime(double unixTime)
-        {
-            DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
-            long unixTimeStampInTicks = (long)(unixTime * TimeSpan.TicksPerSecond);
-            return new DateTime(unixStart.Ticks + unixTimeStampInTicks, DateTimeKind.Utc).ToLocalTime();
-        }
-
-        static string CategoryReverseMapper(string categoryName)
-        {
-            Dictionary<string, string> dictionary = new Dictionary<string, string>();
-
-            dictionary.Add("TvSD", "1");
-            dictionary.Add("TvHD", "2");
-            dictionary.Add("MovieSD", "6");
-            dictionary.Add("MovieHD", "7");
-
-            if (dictionary.ContainsKey(categoryName))
-            {
-                return dictionary[categoryName];
-            }
-            return string.Empty;
-        }
-    }
-}
+using CsQuery;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using System.Net.Http.Headers;
+using Jackett.Models;
+using Jackett.Utils;
+using NLog;
+using Jackett.Services;
+using Jackett.Utils.Clients;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+
+namespace Jackett.Indexers
+{
+    public class AlphaRatio : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "login.php"; } }
+        private string SearchUrl { get { return SiteLink + "ajax.php?action=browse&order_by=time&order_way=desc&"; } }
+        private string DownloadUrl { get { return SiteLink + "torrents.php?action=download&id="; } }
+        private string GuidUrl { get { return SiteLink + "torrents.php?torrentid="; } }
+
+        public AlphaRatio(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
+            : base(name: "AlphaRatio",
+                description: "Legendary",
+                link: "https://alpharatio.cc/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                downloadBase: "https://alpharatio.cc/torrents.php?action=download&id=",
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(1, TorznabCatType.TVSD);
+            AddCategoryMapping(2, TorznabCatType.TVHD);
+            AddCategoryMapping(3, TorznabCatType.TVSD);
+            AddCategoryMapping(4, TorznabCatType.TVSD);
+            AddCategoryMapping(5, TorznabCatType.TVHD);
+            AddCategoryMapping(6, TorznabCatType.MoviesSD);
+            AddCategoryMapping(7, TorznabCatType.MoviesHD);
+            AddCategoryMapping(8, TorznabCatType.MoviesSD);
+            AddCategoryMapping(9, TorznabCatType.MoviesHD);
+            AddCategoryMapping(10, TorznabCatType.XXX);
+            AddCategoryMapping(20, TorznabCatType.XXX);
+            AddCategoryMapping(12, TorznabCatType.PCGames);
+            AddCategoryMapping(13, TorznabCatType.ConsoleXbox);
+            AddCategoryMapping(14, TorznabCatType.ConsolePS3);
+            AddCategoryMapping(15, TorznabCatType.ConsoleWii);
+            AddCategoryMapping(16, TorznabCatType.PC);
+            AddCategoryMapping(17, TorznabCatType.PCMac);
+            AddCategoryMapping(19, TorznabCatType.PCPhoneOther);
+            AddCategoryMapping(21, TorznabCatType.BooksEbook);
+            AddCategoryMapping(22, TorznabCatType.AudioAudiobook);
+            AddCategoryMapping(23, TorznabCatType.Audio);
+        }
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "login", "Login" },
+                { "keeplogged", "1" }
+            };
+
+            // Do the login
+            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, string.Empty, true, SiteLink);
+            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("logout.php?"), () =>
+               {
+                   CQ dom = response.Content;
+                   dom["#loginform > table"].Remove();
+                   var errorMessage = dom["#loginform"].Text().Trim().Replace("\n\t", " ");
+                   throw new ExceptionWithConfigData(errorMessage, configData);
+               });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        void FillReleaseInfoFromJson(ReleaseInfo release, JObject r)
+        {
+            var id = r["torrentId"];
+            release.Size = (long)r["size"];
+            release.Seeders = (int)r["seeders"];
+            release.Peers = (int)r["leechers"] + release.Seeders;
+            release.Guid = new Uri(GuidUrl + id);
+            release.Comments = release.Guid;
+            release.Link = new Uri(DownloadUrl + id);
+            release.Category = MapTrackerCatToNewznab(CategoryReverseMapper((string)r["category"]));
+            release.Files = (int)r["fileCount"];
+            release.Grabs = (int)r["snatches"];
+            release.DownloadVolumeFactor = 1;
+            release.UploadVolumeFactor = 1;
+            if ((bool)r["isFreeleech"])
+            {
+                release.DownloadVolumeFactor = 0;
+            }
+            if ((bool)r["isPersonalFreeleech"])
+            {
+                release.DownloadVolumeFactor = 0;
+            }
+            if ((bool)r["isNeutralLeech"])
+            {
+                release.DownloadVolumeFactor = 0;
+                release.UploadVolumeFactor = 0;
+            }
+
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("searchstr", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("filter_cat[" + cat + "]", "1");
+            }
+
+            searchUrl += queryCollection.GetQueryString();
+            var response = await RequestStringWithCookiesAndRetry(searchUrl);
+            if (response.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(searchUrl);
+            }
+
+            try
+            {
+                var json = JObject.Parse(response.Content);
+                foreach (JObject r in json["response"]["results"])
+                {
+                    DateTime pubDate = DateTime.MinValue;
+                    double dateNum;
+                    if (double.TryParse((string)r["groupTime"], out dateNum))
+                        pubDate = UnixTimestampToDateTime(dateNum);
+
+                    var groupName = (string)r["groupName"];
+
+                    if (r["torrents"] is JArray)
+                    {
+                        foreach (JObject t in r["torrents"])
+                        {
+                            var release = new ReleaseInfo();
+                            release.PublishDate = pubDate;
+                            release.Title = groupName;
+                            release.Description = groupName;
+                            FillReleaseInfoFromJson(release, t);
+                            releases.Add(release);
+                        }
+                    }
+                    else
+                    {
+                        var release = new ReleaseInfo();
+                        release.PublishDate = pubDate;
+                        release.Title = groupName;
+                        release.Description = groupName;
+                        FillReleaseInfoFromJson(release, r);
+                        releases.Add(release);
+                    }
+
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(response.Content, ex);
+            }
+
+            return releases;
+        }
+
+        static DateTime UnixTimestampToDateTime(double unixTime)
+        {
+            DateTime unixStart = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
+            long unixTimeStampInTicks = (long)(unixTime * TimeSpan.TicksPerSecond);
+            return new DateTime(unixStart.Ticks + unixTimeStampInTicks, DateTimeKind.Utc).ToLocalTime();
+        }
+
+        static string CategoryReverseMapper(string categoryName)
+        {
+            Dictionary<string, string> dictionary = new Dictionary<string, string>();
+
+            dictionary.Add("TvSD", "1");
+            dictionary.Add("TvHD", "2");
+            dictionary.Add("MovieSD", "6");
+            dictionary.Add("MovieHD", "7");
+
+            if (dictionary.ContainsKey(categoryName))
+            {
+                return dictionary[categoryName];
+            }
+            return string.Empty;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Andraste.cs b/src/Jackett/Indexers/Andraste.cs
index 03cd3f830fb717634980be946fe3b0d4565782f9..790b49a2318da3b52ad2587f4dbb06904b88ec22 100644
--- a/src/Jackett/Indexers/Andraste.cs
+++ b/src/Jackett/Indexers/Andraste.cs
@@ -10,10 +10,10 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-using System.Linq;
-
+using System.Collections.Specialized;
+using System.Text;
+using System.Linq;
+
 namespace Jackett.Indexers
 {
     public class Andraste : BaseIndexer, IIndexer
@@ -42,35 +42,35 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(9,  TorznabCatType.Other); // Anderes
-            AddCategoryMapping(23, TorznabCatType.TVAnime); // Animation - Film &; Serie
-            AddCategoryMapping(1,  TorznabCatType.PC); // Appz
-            AddCategoryMapping(52, TorznabCatType.Other); // Botuploads
-            AddCategoryMapping(25, TorznabCatType.TVDocumentary); // Doku - Alle Formate
-            AddCategoryMapping(27, TorznabCatType.Books); // E-Books
-            AddCategoryMapping(51, TorznabCatType.Movies3D); // Film/3D
-            AddCategoryMapping(20, TorznabCatType.MoviesDVD); // Film/DVDr
-            AddCategoryMapping(37, TorznabCatType.MoviesHD); // Film/HD 1080p++
-            AddCategoryMapping(38, TorznabCatType.MoviesSD); // Film/HD 720p
-            AddCategoryMapping(36, TorznabCatType.Movies); // Film/im Kino
-            AddCategoryMapping(19, TorznabCatType.Movies); // Film/XviD,DivX,x264
-            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games/PC
-            AddCategoryMapping(12, TorznabCatType.ConsolePS4); // Games/Playstation
-            AddCategoryMapping(22, TorznabCatType.ConsoleWii); // Games/Wii & DS
-            AddCategoryMapping(21, TorznabCatType.ConsoleXbox); // Games/Xbox & 360
-            AddCategoryMapping(48, TorznabCatType.PCPhoneAndroid); // Handy & PDA/Android
-            AddCategoryMapping(47, TorznabCatType.PCPhoneIOS); // Handy & PDA/iOS
-            AddCategoryMapping(44, TorznabCatType.PCMac); // Macintosh
-            AddCategoryMapping(41, TorznabCatType.Other); // MegaPack
-            AddCategoryMapping(24, TorznabCatType.AudioAudiobook); // Musik/Hörbuch & Hörspiel
-            AddCategoryMapping(46, TorznabCatType.Audio); // Musik/HQ 320++
-            AddCategoryMapping(6,  TorznabCatType.Audio); // Musik/Musik
-            AddCategoryMapping(26, TorznabCatType.AudioVideo); // Musik/Musikvideos
-            AddCategoryMapping(29, TorznabCatType.TVSD); // Serien/DVDr
-            AddCategoryMapping(35, TorznabCatType.TVHD); // Serien/HD 720p++
-            AddCategoryMapping(7,  TorznabCatType.TV); // Serien/XviD,DivX,x264
-            AddCategoryMapping(45, TorznabCatType.TV); // Shows
-            AddCategoryMapping(40, TorznabCatType.TVSport); // Sport
+            AddCategoryMapping(9,  TorznabCatType.Other); // Anderes
+            AddCategoryMapping(23, TorznabCatType.TVAnime); // Animation - Film &; Serie
+            AddCategoryMapping(1,  TorznabCatType.PC); // Appz
+            AddCategoryMapping(52, TorznabCatType.Other); // Botuploads
+            AddCategoryMapping(25, TorznabCatType.TVDocumentary); // Doku - Alle Formate
+            AddCategoryMapping(27, TorznabCatType.Books); // E-Books
+            AddCategoryMapping(51, TorznabCatType.Movies3D); // Film/3D
+            AddCategoryMapping(20, TorznabCatType.MoviesDVD); // Film/DVDr
+            AddCategoryMapping(37, TorznabCatType.MoviesHD); // Film/HD 1080p++
+            AddCategoryMapping(38, TorznabCatType.MoviesSD); // Film/HD 720p
+            AddCategoryMapping(36, TorznabCatType.Movies); // Film/im Kino
+            AddCategoryMapping(19, TorznabCatType.Movies); // Film/XviD,DivX,x264
+            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games/PC
+            AddCategoryMapping(12, TorznabCatType.ConsolePS4); // Games/Playstation
+            AddCategoryMapping(22, TorznabCatType.ConsoleWii); // Games/Wii & DS
+            AddCategoryMapping(21, TorznabCatType.ConsoleXbox); // Games/Xbox & 360
+            AddCategoryMapping(48, TorznabCatType.PCPhoneAndroid); // Handy & PDA/Android
+            AddCategoryMapping(47, TorznabCatType.PCPhoneIOS); // Handy & PDA/iOS
+            AddCategoryMapping(44, TorznabCatType.PCMac); // Macintosh
+            AddCategoryMapping(41, TorznabCatType.Other); // MegaPack
+            AddCategoryMapping(24, TorznabCatType.AudioAudiobook); // Musik/Hörbuch & Hörspiel
+            AddCategoryMapping(46, TorznabCatType.Audio); // Musik/HQ 320++
+            AddCategoryMapping(6,  TorznabCatType.Audio); // Musik/Musik
+            AddCategoryMapping(26, TorznabCatType.AudioVideo); // Musik/Musikvideos
+            AddCategoryMapping(29, TorznabCatType.TVSD); // Serien/DVDr
+            AddCategoryMapping(35, TorznabCatType.TVHD); // Serien/HD 720p++
+            AddCategoryMapping(7,  TorznabCatType.TV); // Serien/XviD,DivX,x264
+            AddCategoryMapping(45, TorznabCatType.TV); // Shows
+            AddCategoryMapping(40, TorznabCatType.TVSport); // Sport
             AddCategoryMapping(32, TorznabCatType.XXX); // XXX
         }
 
@@ -85,44 +85,44 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom["table.tableinborder"].Html();
-                errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom["table.tableinborder"].Html();
+                errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("showsearch", "1");
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("orderby", "added");
-            queryCollection.Add("sort", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("showsearch", "1");
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("orderby", "added");
+            queryCollection.Add("sort", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookies(searchUrl);
@@ -136,50 +136,50 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    release.Title = qDetailsLink.Attr("title");
-
-                    if (!query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-                    var qDLLink = qRow.Find("a[href^=download.php?torrent=]").First();
-                    var qSeeders = qRow.Find("span:contains(Seeder) > b:eq(0)");
-                    var qLeechers = qRow.Find("span:contains(Seeder) > b:eq(1)");
-                    var qDateStr = qRow.Find("td > table > tbody > tr > td:eq(7)").First();
-                    var qSize = qRow.Find("span:contains(Volumen) > b:eq(0)").First();
-                    var qOnlyUpload = qRow.Find("img[title=OnlyUpload]");
-
-                    if(qOnlyUpload.Any())
-                    {
-                        release.MinimumRatio = 2;
-                        release.MinimumSeedTime = 144 * 60 * 60;
-                    }
-                    else
-                    {
-                        release.MinimumRatio = 1;
-                        release.MinimumSeedTime = 72 * 60 * 60;
-                    }
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    release.Title = qDetailsLink.Attr("title");
+
+                    if (!query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+                    var qDLLink = qRow.Find("a[href^=download.php?torrent=]").First();
+                    var qSeeders = qRow.Find("span:contains(Seeder) > b:eq(0)");
+                    var qLeechers = qRow.Find("span:contains(Seeder) > b:eq(1)");
+                    var qDateStr = qRow.Find("td > table > tbody > tr > td:eq(7)").First();
+                    var qSize = qRow.Find("span:contains(Volumen) > b:eq(0)").First();
+                    var qOnlyUpload = qRow.Find("img[title=OnlyUpload]");
+
+                    if(qOnlyUpload.Any())
+                    {
+                        release.MinimumRatio = 2;
+                        release.MinimumSeedTime = 144 * 60 * 60;
+                    }
+                    else
+                    {
+                        release.MinimumRatio = 1;
+                        release.MinimumSeedTime = 72 * 60 * 60;
+                    }
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text().Trim().Replace('\xA0', ' ');
-                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc.ToLocalTime();
 
                     var files = qRow.Find("a[href*=\"&filelist=1\"] ~ font ~ b").Text();
@@ -190,8 +190,8 @@ namespace Jackett.Indexers
 
                     if (globalFreeleech)
                         release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[alt=\"OU\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("img[alt=\"OU\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/AnimeBytes.cs b/src/Jackett/Indexers/AnimeBytes.cs
index 99739e648a31b7fe811a5ae8c372ee86f535c806..f3495cfa91f2976cb2248525443dd575a07f6fe6 100644
--- a/src/Jackett/Indexers/AnimeBytes.cs
+++ b/src/Jackett/Indexers/AnimeBytes.cs
@@ -1,474 +1,474 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Models.IndexerConfig.Bespoke;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Security.Cryptography;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using System.Web;
-
-namespace Jackett.Indexers
-{
-    public class AnimeBytes : BaseIndexer, IIndexer
-    {
-        enum SearchType
-        {
-            Video,
-            Audio
-        }
-
-        private string LoginUrl { get { return SiteLink + "user/login"; } }
-        private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
-        private string MusicSearchUrl { get { return SiteLink + "torrents2.php?"; } }
-        public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
-        public bool InsertSeason { get { return configData.InsertSeason!=null && configData.InsertSeason.Value; } }
-
-        new ConfigurationDataAnimeBytes configData
-        {
-            get { return (ConfigurationDataAnimeBytes)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l, IProtectionService ps)
-            : base(name: "AnimeBytes",
-                link: "https://animebytes.tv/",
-                description: "Powered by Tentacles",
-                manager: i,
-                client: client,
-                caps: new TorznabCapabilities(TorznabCatType.TVAnime,
-                                              TorznabCatType.Movies,
-                                              TorznabCatType.BooksComics,
-                                              TorznabCatType.ConsolePSP,
-                                              TorznabCatType.ConsoleOther,
-                                              TorznabCatType.PCGames,
-                                              TorznabCatType.AudioMP3,
-                                              TorznabCatType.AudioLossless,
-                                              TorznabCatType.AudioOther),
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataAnimeBytes())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-        }
-
-
-        public override IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input)
-        {
-            // Prevent filtering
-            return input;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            lock (cache)
-            {
-                cache.Clear();
-            }
-
-            // Get the login form as we need the CSRF Token
-            var loginPage = await webclient.GetString(new Utils.Clients.WebRequest()
-            {
-                Url = LoginUrl,
-                Encoding = Encoding
-            });
-
-            CQ loginPageDom = loginPage.Content;
-            var csrfIndex = loginPageDom["input[name=\"_CSRF_INDEX\"]"].Last();
-            var csrfToken = loginPageDom["input[name=\"_CSRF_TOKEN\"]"].Last();
-
-            // Build login form
-            var pairs = new Dictionary<string, string> {
-                    { "_CSRF_INDEX", csrfIndex.Attr("value") },
-                    { "_CSRF_TOKEN", csrfToken.Attr("value") },
-                    { "username", configData.Username.Value },
-                    { "password", configData.Password.Value },
-                    { "keeplogged_sent", "true" },
-                    { "keeplogged", "on" },
-                    { "login", "Log In!" }
-            };
-
-            // Do the login
-            var request = new Utils.Clients.WebRequest()
-            {
-                Cookies = loginPage.Cookies,
-                PostData = pairs,
-                Referer = LoginUrl,
-                Type = RequestType.POST,
-                Encoding = Encoding,
-                Url = LoginUrl
-            };
-            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null);
-
-            // Follow the redirect
-            await FollowIfRedirect(response, request.Url, SearchUrl);
-
-            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/user/logout"), () =>
-            {
-                // Their login page appears to be broken and just gives a 500 error.
-                throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", configData);
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        // Override to load legacy config format
-        public override void LoadFromSavedConfiguration(JToken jsonConfig)
-        {
-            if (jsonConfig is JObject)
-            {
-                configData.CookieHeader.Value = jsonConfig.Value<string>("cookies");
-                configData.IncludeRaw.Value = jsonConfig.Value<bool>("raws");
-                SaveConfig();
-                IsConfigured = true;
-                return;
-            }
-
-            base.LoadFromSavedConfiguration(jsonConfig);
-        }
-
-        private string StripEpisodeNumber(string term)
-        {
-            // Tracer does not support searching with episode number so strip it if we have one
-            term = Regex.Replace(term, @"\W(\dx)?\d?\d$", string.Empty);
-            term = Regex.Replace(term, @"\W(S\d\d?E)?\d?\d$", string.Empty);
-            return term;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            // The result list
-            var releases = new List<ReleaseInfo>();
-            
-            if (ContainsMusicCategories(query.Categories))
-            {
-                foreach (var result in await GetResults(SearchType.Audio, query.SanitizedSearchTerm))
-                {
-                    releases.Add(result);
-                }
-            }
-
-            foreach (var result in await GetResults(SearchType.Video, StripEpisodeNumber(query.SanitizedSearchTerm)))
-            {
-                releases.Add(result);
-            }
-
-            return releases.ToArray();
-        }
-
-        private bool ContainsMusicCategories(int[] categories)
-        {
-            var music = new[]
-            {
-                TorznabCatType.Audio.ID,
-                TorznabCatType.AudioMP3.ID,
-                TorznabCatType.AudioLossless.ID,
-                TorznabCatType.AudioOther.ID,
-                TorznabCatType.AudioForeign.ID
-            };
-
-            return categories.Length == 0 || music.Any(categories.Contains);
-        }
-
-        private async Task<IEnumerable<ReleaseInfo>> GetResults(SearchType searchType, string searchTerm)
-        {
-            var cleanSearchTerm = HttpUtility.UrlEncode(searchTerm);
-
-            // The result list
-            var releases = new List<ReleaseInfo>();
-
-            var queryUrl = searchType == SearchType.Video ? SearchUrl : MusicSearchUrl;
-            // Only include the query bit if its required as hopefully the site caches the non query page
-            if (!string.IsNullOrWhiteSpace(searchTerm))
-            {
-                queryUrl += string.Format("searchstr={0}&action=advanced&search_type=title&year=&year2=&tags=&tags_type=0&sort=time_added&way=desc&hentai=2&releasegroup=&epcount=&epcount2=&artbooktitle=", cleanSearchTerm);
-            }
-
-            // Check cache first so we don't query the server for each episode when searching for each episode in a series.
-            lock (cache)
-            {
-                // Remove old cache items
-                CleanCache();
-
-                var cachedResult = cache.Where(i => i.Query == queryUrl).FirstOrDefault();
-                if (cachedResult != null)
-                    return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
-            }
-            
-            // Get the content from the tracker
-            var response = await RequestStringWithCookiesAndRetry(queryUrl);
-            if (response.IsRedirect)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(queryUrl);
-            }
-
-            CQ dom = response.Content;
-
-            // Parse
-            try
-            {
-                var releaseInfo = "S01";
-                var root = dom.Find(".group_cont");
-                // We may have got redirected to the series page if we have none of these
-                if (root.Count() == 0)
-                    root = dom.Find(".torrent_table");
-
-                foreach (var series in root)
-                {
-                    var seriesCq = series.Cq();
-
-                    var synonyms = new List<string>();
-                    string mainTitle;
-                    if (searchType == SearchType.Video)
-                        mainTitle = seriesCq.Find(".group_title strong a").First().Text().Trim();
-                    else
-                        mainTitle = seriesCq.Find(".group_title strong").Text().Trim();
-
-                    var yearStr = seriesCq.Find(".group_title strong").First().Text().Trim().Replace("]", "").Trim();
-                    int yearIndex = yearStr.LastIndexOf("[");
-                    if (yearIndex > -1)
-                        yearStr = yearStr.Substring(yearIndex + 1);
-
-                    int year = 0;
-                    if (!int.TryParse(yearStr, out year))
-                        year = DateTime.Now.Year;
-
-                    synonyms.Add(mainTitle);
-
-                    // If the title contains a comma then we can't use the synonyms as they are comma seperated
-                    if (!mainTitle.Contains(","))
-                    {
-                        var symnomnNames = string.Empty;
-                        foreach (var e in seriesCq.Find(".group_statbox li"))
-                        {
-                            if (e.FirstChild.InnerText == "Synonyms:")
-                            {
-                                symnomnNames = e.InnerText;
-                            }
-                        }
-
-                        if (!string.IsNullOrWhiteSpace(symnomnNames))
-                        {
-                            foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
-                            {
-                                var theName = name.Trim();
-                                if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
-                                {
-                                    synonyms.Add(theName);
-                                }
-                            }
-                        }
-                    }
-
-                    foreach (var title in synonyms)
-                    {
-                        var releaseRows = seriesCq.Find(".torrent_group tr");
-
-                        // Skip the first two info rows
-                        for (int r = 1; r < releaseRows.Count(); r++)
-                        {
-                            var row = releaseRows.Get(r);
-                            var rowCq = row.Cq();
-                            if (rowCq.HasClass("edition_info"))
-                            {
-                                releaseInfo = rowCq.Find("td").Text();
-
-                                if (string.IsNullOrWhiteSpace(releaseInfo))
-                                {
-                                    // Single episodes alpha - Reported that this info is missing.
-                                    // It should self correct when availible
-                                    break;
-                                }
-
-                                releaseInfo = releaseInfo.Replace("Episode ", "");
-                                releaseInfo = releaseInfo.Replace("Season ", "S");
-                                releaseInfo = releaseInfo.Trim();
-                                int test = 0;
-                                if (InsertSeason && int.TryParse(releaseInfo, out test) && releaseInfo.Length==1)
-                                {
-                                    releaseInfo = "S01E0" + releaseInfo;
-                                }
-
-                            }
-                            else if (rowCq.HasClass("torrent"))
-                            {
-                                var links = rowCq.Find("a");
-                                // Protect against format changes
-                                if (links.Count() != 2)
-                                {
-                                    continue;
-                                }
-
-                                var release = new ReleaseInfo();
-                                release.MinimumRatio = 1;
-                                release.MinimumSeedTime = 259200;
-                                var downloadLink = links.Get(0);
-
-                                // We dont know this so try to fake based on the release year
-                                release.PublishDate = new DateTime(year, 1, 1);
-                                release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);
-
-                                var infoLink = links.Get(1);
-                                release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
-                                release.Guid = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
-                                release.Link = new Uri(downloadLink.Attributes.GetAttribute("href"));
-
-                                string category = null;
-                                if (searchType == SearchType.Video)
-                                {
-                                    category = seriesCq.Find("a[title=\"View Torrent\"]").Text().Trim();
-                                    if (category == "TV Series")
-                                        release.Category = new List<int> { TorznabCatType.TVAnime.ID };
-
-                                    // Ignore these categories as they'll cause hell with the matcher
-                                    // TV Special, OVA, ONA, DVD Special, BD Special
-
-                                    if (category == "Movie")
-                                        release.Category = new List<int> { TorznabCatType.Movies.ID };
-
-                                    if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel")
-                                        release.Category = new List<int> { TorznabCatType.BooksComics.ID };
-
-                                    if (category == "Novel" || category == "Artbook")
-                                        release.Category = new List<int> { TorznabCatType.BooksComics.ID };
-
-                                    if (category == "Game" || category == "Visual Novel")
-                                    {
-                                        var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
-                                        if (description.Contains(" PSP "))
-                                            release.Category = new List<int> { TorznabCatType.ConsolePSP.ID };
-                                        if (description.Contains("PSX"))
-                                            release.Category = new List<int> { TorznabCatType.ConsoleOther.ID };
-                                        if (description.Contains(" NES "))
-                                            release.Category = new List<int> { TorznabCatType.ConsoleOther.ID };
-                                        if (description.Contains(" PC "))
-                                            release.Category = new List<int> { TorznabCatType.PCGames.ID };
-                                    }
-                                }
-
-                                if (searchType == SearchType.Audio)
-                                {
-                                    category = seriesCq.Find(".group_img .cat a").Text();
-                                    if (category == "Single" || category == "Album" || category == "Compilation" || category == "Soundtrack" || category == "Remix CD")
-                                    {
-                                        var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
-                                        if (description.Contains(" Lossless "))
-                                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
-                                        else if (description.Contains("MP3"))
-                                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
-                                        else
-                                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
-                                    }
-                                }
-
-
-
-                                // We dont actually have a release name >.> so try to create one
-                                var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
-                                for (int i = releaseTags.Count - 1; i >= 0; i--)
-                                {
-                                    releaseTags[i] = releaseTags[i].Trim();
-                                    if (string.IsNullOrWhiteSpace(releaseTags[i]))
-                                        releaseTags.RemoveAt(i);
-                                }
-
-                                var group = releaseTags.Last();
-                                if (group.Contains("(") && group.Contains(")"))
-                                {
-                                    // Skip raws if set
-                                    if (group.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
-                                    {
-                                        continue;
-                                    }
-
-                                    var start = group.IndexOf("(");
-                                    group = "[" + group.Substring(start + 1, (group.IndexOf(")") - 1) - start) + "] ";
-                                }
-                                else
-                                {
-                                    group = string.Empty;
-                                }
-
-                                var infoString = "";
-
-                                for (int i = 0; i + 1 < releaseTags.Count(); i++)
-                                {
-                                    if (releaseTags[i] == "Raw" && !AllowRaws)
-                                        continue;
-                                    infoString += "[" + releaseTags[i] + "]";
-                                }
-
-                                if (category == "Movie")
-                                {
-                                    release.Title = string.Format("{0} {1} {2}{3}", title, year, group, infoString);
-                                }
-                                else
-                                {
-                                    release.Title = string.Format("{0}{1} {2} {3}", group, title, releaseInfo, infoString);
-                                }
-                                release.Description = title;
-
-                                var size = rowCq.Find(".torrent_size");
-                                if (size.Count() > 0)
-                                {
-                                    release.Size = ReleaseInfo.GetBytes(size.First().Text());
-                                }
-
-                                //  Additional 5 hours per GB 
-                                release.MinimumSeedTime += (release.Size / 1000000000) * 18000;
-
-                                // Peer info
-                                release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
-                                release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
-
-                                // grabs
-                                var grabs = rowCq.Find("td.torrent_snatched").Text();
-                                release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                                // freeleech
-                                if (rowCq.Find("img[alt=\"Freeleech!\"]").Length >= 1)
-                                    release.DownloadVolumeFactor = 0;
-                                else
-                                    release.DownloadVolumeFactor = 1;
-                                release.UploadVolumeFactor = 1;
-
-                                if (release.Category != null)
-                                    releases.Add(release);
-                            }
-                        }
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(response.Content, ex);
-            }
-
-            // Add to the cache
-            lock (cache)
-            {
-                cache.Add(new CachedQueryResult(queryUrl, releases));
-            }
-
-            return releases.Select(s => (ReleaseInfo)s.Clone());
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Models.IndexerConfig.Bespoke;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Concurrent;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Security.Cryptography;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace Jackett.Indexers
+{
+    public class AnimeBytes : BaseIndexer, IIndexer
+    {
+        enum SearchType
+        {
+            Video,
+            Audio
+        }
+
+        private string LoginUrl { get { return SiteLink + "user/login"; } }
+        private string SearchUrl { get { return SiteLink + "torrents.php?"; } }
+        private string MusicSearchUrl { get { return SiteLink + "torrents2.php?"; } }
+        public bool AllowRaws { get { return configData.IncludeRaw.Value; } }
+        public bool InsertSeason { get { return configData.InsertSeason!=null && configData.InsertSeason.Value; } }
+
+        new ConfigurationDataAnimeBytes configData
+        {
+            get { return (ConfigurationDataAnimeBytes)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public AnimeBytes(IIndexerManagerService i, IWebClient client, Logger l, IProtectionService ps)
+            : base(name: "AnimeBytes",
+                link: "https://animebytes.tv/",
+                description: "Powered by Tentacles",
+                manager: i,
+                client: client,
+                caps: new TorznabCapabilities(TorznabCatType.TVAnime,
+                                              TorznabCatType.Movies,
+                                              TorznabCatType.BooksComics,
+                                              TorznabCatType.ConsolePSP,
+                                              TorznabCatType.ConsoleOther,
+                                              TorznabCatType.PCGames,
+                                              TorznabCatType.AudioMP3,
+                                              TorznabCatType.AudioLossless,
+                                              TorznabCatType.AudioOther),
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataAnimeBytes())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+        }
+
+
+        public override IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> input)
+        {
+            // Prevent filtering
+            return input;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            lock (cache)
+            {
+                cache.Clear();
+            }
+
+            // Get the login form as we need the CSRF Token
+            var loginPage = await webclient.GetString(new Utils.Clients.WebRequest()
+            {
+                Url = LoginUrl,
+                Encoding = Encoding
+            });
+
+            CQ loginPageDom = loginPage.Content;
+            var csrfIndex = loginPageDom["input[name=\"_CSRF_INDEX\"]"].Last();
+            var csrfToken = loginPageDom["input[name=\"_CSRF_TOKEN\"]"].Last();
+
+            // Build login form
+            var pairs = new Dictionary<string, string> {
+                    { "_CSRF_INDEX", csrfIndex.Attr("value") },
+                    { "_CSRF_TOKEN", csrfToken.Attr("value") },
+                    { "username", configData.Username.Value },
+                    { "password", configData.Password.Value },
+                    { "keeplogged_sent", "true" },
+                    { "keeplogged", "on" },
+                    { "login", "Log In!" }
+            };
+
+            // Do the login
+            var request = new Utils.Clients.WebRequest()
+            {
+                Cookies = loginPage.Cookies,
+                PostData = pairs,
+                Referer = LoginUrl,
+                Type = RequestType.POST,
+                Encoding = Encoding,
+                Url = LoginUrl
+            };
+            var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null);
+
+            // Follow the redirect
+            await FollowIfRedirect(response, request.Url, SearchUrl);
+
+            await ConfigureIfOK(response.Cookies, response.Content != null && response.Content.Contains("/user/logout"), () =>
+            {
+                // Their login page appears to be broken and just gives a 500 error.
+                throw new ExceptionWithConfigData("Failed to login, 6 failed attempts will get you banned for 6 hours.", configData);
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        // Override to load legacy config format
+        public override void LoadFromSavedConfiguration(JToken jsonConfig)
+        {
+            if (jsonConfig is JObject)
+            {
+                configData.CookieHeader.Value = jsonConfig.Value<string>("cookies");
+                configData.IncludeRaw.Value = jsonConfig.Value<bool>("raws");
+                SaveConfig();
+                IsConfigured = true;
+                return;
+            }
+
+            base.LoadFromSavedConfiguration(jsonConfig);
+        }
+
+        private string StripEpisodeNumber(string term)
+        {
+            // Tracer does not support searching with episode number so strip it if we have one
+            term = Regex.Replace(term, @"\W(\dx)?\d?\d$", string.Empty);
+            term = Regex.Replace(term, @"\W(S\d\d?E)?\d?\d$", string.Empty);
+            return term;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            // The result list
+            var releases = new List<ReleaseInfo>();
+            
+            if (ContainsMusicCategories(query.Categories))
+            {
+                foreach (var result in await GetResults(SearchType.Audio, query.SanitizedSearchTerm))
+                {
+                    releases.Add(result);
+                }
+            }
+
+            foreach (var result in await GetResults(SearchType.Video, StripEpisodeNumber(query.SanitizedSearchTerm)))
+            {
+                releases.Add(result);
+            }
+
+            return releases.ToArray();
+        }
+
+        private bool ContainsMusicCategories(int[] categories)
+        {
+            var music = new[]
+            {
+                TorznabCatType.Audio.ID,
+                TorznabCatType.AudioMP3.ID,
+                TorznabCatType.AudioLossless.ID,
+                TorznabCatType.AudioOther.ID,
+                TorznabCatType.AudioForeign.ID
+            };
+
+            return categories.Length == 0 || music.Any(categories.Contains);
+        }
+
+        private async Task<IEnumerable<ReleaseInfo>> GetResults(SearchType searchType, string searchTerm)
+        {
+            var cleanSearchTerm = HttpUtility.UrlEncode(searchTerm);
+
+            // The result list
+            var releases = new List<ReleaseInfo>();
+
+            var queryUrl = searchType == SearchType.Video ? SearchUrl : MusicSearchUrl;
+            // Only include the query bit if its required as hopefully the site caches the non query page
+            if (!string.IsNullOrWhiteSpace(searchTerm))
+            {
+                queryUrl += string.Format("searchstr={0}&action=advanced&search_type=title&year=&year2=&tags=&tags_type=0&sort=time_added&way=desc&hentai=2&releasegroup=&epcount=&epcount2=&artbooktitle=", cleanSearchTerm);
+            }
+
+            // Check cache first so we don't query the server for each episode when searching for each episode in a series.
+            lock (cache)
+            {
+                // Remove old cache items
+                CleanCache();
+
+                var cachedResult = cache.Where(i => i.Query == queryUrl).FirstOrDefault();
+                if (cachedResult != null)
+                    return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
+            }
+            
+            // Get the content from the tracker
+            var response = await RequestStringWithCookiesAndRetry(queryUrl);
+            if (response.IsRedirect)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(queryUrl);
+            }
+
+            CQ dom = response.Content;
+
+            // Parse
+            try
+            {
+                var releaseInfo = "S01";
+                var root = dom.Find(".group_cont");
+                // We may have got redirected to the series page if we have none of these
+                if (root.Count() == 0)
+                    root = dom.Find(".torrent_table");
+
+                foreach (var series in root)
+                {
+                    var seriesCq = series.Cq();
+
+                    var synonyms = new List<string>();
+                    string mainTitle;
+                    if (searchType == SearchType.Video)
+                        mainTitle = seriesCq.Find(".group_title strong a").First().Text().Trim();
+                    else
+                        mainTitle = seriesCq.Find(".group_title strong").Text().Trim();
+
+                    var yearStr = seriesCq.Find(".group_title strong").First().Text().Trim().Replace("]", "").Trim();
+                    int yearIndex = yearStr.LastIndexOf("[");
+                    if (yearIndex > -1)
+                        yearStr = yearStr.Substring(yearIndex + 1);
+
+                    int year = 0;
+                    if (!int.TryParse(yearStr, out year))
+                        year = DateTime.Now.Year;
+
+                    synonyms.Add(mainTitle);
+
+                    // If the title contains a comma then we can't use the synonyms as they are comma seperated
+                    if (!mainTitle.Contains(","))
+                    {
+                        var symnomnNames = string.Empty;
+                        foreach (var e in seriesCq.Find(".group_statbox li"))
+                        {
+                            if (e.FirstChild.InnerText == "Synonyms:")
+                            {
+                                symnomnNames = e.InnerText;
+                            }
+                        }
+
+                        if (!string.IsNullOrWhiteSpace(symnomnNames))
+                        {
+                            foreach (var name in symnomnNames.Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries))
+                            {
+                                var theName = name.Trim();
+                                if (!theName.Contains("&#") && !string.IsNullOrWhiteSpace(theName))
+                                {
+                                    synonyms.Add(theName);
+                                }
+                            }
+                        }
+                    }
+
+                    foreach (var title in synonyms)
+                    {
+                        var releaseRows = seriesCq.Find(".torrent_group tr");
+
+                        // Skip the first two info rows
+                        for (int r = 1; r < releaseRows.Count(); r++)
+                        {
+                            var row = releaseRows.Get(r);
+                            var rowCq = row.Cq();
+                            if (rowCq.HasClass("edition_info"))
+                            {
+                                releaseInfo = rowCq.Find("td").Text();
+
+                                if (string.IsNullOrWhiteSpace(releaseInfo))
+                                {
+                                    // Single episodes alpha - Reported that this info is missing.
+                                    // It should self correct when availible
+                                    break;
+                                }
+
+                                releaseInfo = releaseInfo.Replace("Episode ", "");
+                                releaseInfo = releaseInfo.Replace("Season ", "S");
+                                releaseInfo = releaseInfo.Trim();
+                                int test = 0;
+                                if (InsertSeason && int.TryParse(releaseInfo, out test) && releaseInfo.Length==1)
+                                {
+                                    releaseInfo = "S01E0" + releaseInfo;
+                                }
+
+                            }
+                            else if (rowCq.HasClass("torrent"))
+                            {
+                                var links = rowCq.Find("a");
+                                // Protect against format changes
+                                if (links.Count() != 2)
+                                {
+                                    continue;
+                                }
+
+                                var release = new ReleaseInfo();
+                                release.MinimumRatio = 1;
+                                release.MinimumSeedTime = 259200;
+                                var downloadLink = links.Get(0);
+
+                                // We dont know this so try to fake based on the release year
+                                release.PublishDate = new DateTime(year, 1, 1);
+                                release.PublishDate = release.PublishDate.AddDays(Math.Min(DateTime.Now.DayOfYear, 365) - 1);
+
+                                var infoLink = links.Get(1);
+                                release.Comments = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href"));
+                                release.Guid = new Uri(SiteLink + infoLink.Attributes.GetAttribute("href") + "&nh=" + StringUtil.Hash(title)); // Sonarr should dedupe on this url - allow a url per name.
+                                release.Link = new Uri(downloadLink.Attributes.GetAttribute("href"));
+
+                                string category = null;
+                                if (searchType == SearchType.Video)
+                                {
+                                    category = seriesCq.Find("a[title=\"View Torrent\"]").Text().Trim();
+                                    if (category == "TV Series")
+                                        release.Category = new List<int> { TorznabCatType.TVAnime.ID };
+
+                                    // Ignore these categories as they'll cause hell with the matcher
+                                    // TV Special, OVA, ONA, DVD Special, BD Special
+
+                                    if (category == "Movie")
+                                        release.Category = new List<int> { TorznabCatType.Movies.ID };
+
+                                    if (category == "Manga" || category == "Oneshot" || category == "Anthology" || category == "Manhwa" || category == "Manhua" || category == "Light Novel")
+                                        release.Category = new List<int> { TorznabCatType.BooksComics.ID };
+
+                                    if (category == "Novel" || category == "Artbook")
+                                        release.Category = new List<int> { TorznabCatType.BooksComics.ID };
+
+                                    if (category == "Game" || category == "Visual Novel")
+                                    {
+                                        var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
+                                        if (description.Contains(" PSP "))
+                                            release.Category = new List<int> { TorznabCatType.ConsolePSP.ID };
+                                        if (description.Contains("PSX"))
+                                            release.Category = new List<int> { TorznabCatType.ConsoleOther.ID };
+                                        if (description.Contains(" NES "))
+                                            release.Category = new List<int> { TorznabCatType.ConsoleOther.ID };
+                                        if (description.Contains(" PC "))
+                                            release.Category = new List<int> { TorznabCatType.PCGames.ID };
+                                    }
+                                }
+
+                                if (searchType == SearchType.Audio)
+                                {
+                                    category = seriesCq.Find(".group_img .cat a").Text();
+                                    if (category == "Single" || category == "Album" || category == "Compilation" || category == "Soundtrack" || category == "Remix CD")
+                                    {
+                                        var description = rowCq.Find(".torrent_properties a:eq(1)").Text();
+                                        if (description.Contains(" Lossless "))
+                                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
+                                        else if (description.Contains("MP3"))
+                                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
+                                        else
+                                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
+                                    }
+                                }
+
+
+
+                                // We dont actually have a release name >.> so try to create one
+                                var releaseTags = infoLink.InnerText.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).ToList();
+                                for (int i = releaseTags.Count - 1; i >= 0; i--)
+                                {
+                                    releaseTags[i] = releaseTags[i].Trim();
+                                    if (string.IsNullOrWhiteSpace(releaseTags[i]))
+                                        releaseTags.RemoveAt(i);
+                                }
+
+                                var group = releaseTags.Last();
+                                if (group.Contains("(") && group.Contains(")"))
+                                {
+                                    // Skip raws if set
+                                    if (group.ToLowerInvariant().StartsWith("raw") && !AllowRaws)
+                                    {
+                                        continue;
+                                    }
+
+                                    var start = group.IndexOf("(");
+                                    group = "[" + group.Substring(start + 1, (group.IndexOf(")") - 1) - start) + "] ";
+                                }
+                                else
+                                {
+                                    group = string.Empty;
+                                }
+
+                                var infoString = "";
+
+                                for (int i = 0; i + 1 < releaseTags.Count(); i++)
+                                {
+                                    if (releaseTags[i] == "Raw" && !AllowRaws)
+                                        continue;
+                                    infoString += "[" + releaseTags[i] + "]";
+                                }
+
+                                if (category == "Movie")
+                                {
+                                    release.Title = string.Format("{0} {1} {2}{3}", title, year, group, infoString);
+                                }
+                                else
+                                {
+                                    release.Title = string.Format("{0}{1} {2} {3}", group, title, releaseInfo, infoString);
+                                }
+                                release.Description = title;
+
+                                var size = rowCq.Find(".torrent_size");
+                                if (size.Count() > 0)
+                                {
+                                    release.Size = ReleaseInfo.GetBytes(size.First().Text());
+                                }
+
+                                //  Additional 5 hours per GB 
+                                release.MinimumSeedTime += (release.Size / 1000000000) * 18000;
+
+                                // Peer info
+                                release.Seeders = ParseUtil.CoerceInt(rowCq.Find(".torrent_seeders").Text());
+                                release.Peers = release.Seeders + ParseUtil.CoerceInt(rowCq.Find(".torrent_leechers").Text());
+
+                                // grabs
+                                var grabs = rowCq.Find("td.torrent_snatched").Text();
+                                release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                                // freeleech
+                                if (rowCq.Find("img[alt=\"Freeleech!\"]").Length >= 1)
+                                    release.DownloadVolumeFactor = 0;
+                                else
+                                    release.DownloadVolumeFactor = 1;
+                                release.UploadVolumeFactor = 1;
+
+                                if (release.Category != null)
+                                    releases.Add(release);
+                            }
+                        }
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(response.Content, ex);
+            }
+
+            // Add to the cache
+            lock (cache)
+            {
+                cache.Add(new CachedQueryResult(queryUrl, releases));
+            }
+
+            return releases.Select(s => (ReleaseInfo)s.Clone());
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/AnimeTorrents.cs b/src/Jackett/Indexers/AnimeTorrents.cs
index 42f4a5bb0ce975302393bad1d29283723cf7faeb..b2e16664fb1c5c4508e3dccbf6d0d96c2825292c 100644
--- a/src/Jackett/Indexers/AnimeTorrents.cs
+++ b/src/Jackett/Indexers/AnimeTorrents.cs
@@ -146,16 +146,16 @@ namespace Jackett.Indexers
                     release.PublishDate = DateTime.ParseExact(dateString, "dd MMM yy", CultureInfo.InvariantCulture);
 
                     var qLink = qRow.Find("td:eq(2) a");
-                    if (qLink.Length != 0) // newbie users don't see DL links
-                    {
-                        release.Link = new Uri(qLink.Attr("href"));
+                    if (qLink.Length != 0) // newbie users don't see DL links
+                    {
+                        release.Link = new Uri(qLink.Attr("href"));
                     }
-                    else
-                    {
-                        // use comments link as placeholder
-                        // null causes errors during export to torznab
-                        // skipping the release prevents newbie users from adding the tracker (empty result)
-                        release.Link = release.Comments;
+                    else
+                    {
+                        // use comments link as placeholder
+                        // null causes errors during export to torznab
+                        // skipping the release prevents newbie users from adding the tracker (empty result)
+                        release.Link = release.Comments;
                     }
 
                     var sizeStr = qRow.Find("td:eq(5)").Text();
@@ -176,26 +176,26 @@ namespace Jackett.Indexers
 
                     release.Category = MapTrackerCatToNewznab(rCat);
 
-                    if (qRow.Find("img[alt=\"Gold Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
+                    if (qRow.Find("img[alt=\"Gold Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
                     else
                         release.DownloadVolumeFactor = 1;
 
                     var ULFactorImg = qRow.Find("img[alt*=\"x Multiplier Torrent\"]");
-                    if (ULFactorImg.Length >= 1)
-                    {
-                        release.UploadVolumeFactor = ParseUtil.CoerceDouble(ULFactorImg.Attr("alt").Split('x')[0]);
-                    }
-                    else
-                    {
-                        release.UploadVolumeFactor = 1;
-                    }
-
-                    qTitleLink.Remove();
-                    release.Description = qRow.Find("td:eq(1)").Text();
-
+                    if (ULFactorImg.Length >= 1)
+                    {
+                        release.UploadVolumeFactor = ParseUtil.CoerceDouble(ULFactorImg.Attr("alt").Split('x')[0]);
+                    }
+                    else
+                    {
+                        release.UploadVolumeFactor = 1;
+                    }
+
+                    qTitleLink.Remove();
+                    release.Description = qRow.Find("td:eq(1)").Text();
+
                     releases.Add(release);
                 }
             }
diff --git a/src/Jackett/Indexers/BB.cs b/src/Jackett/Indexers/BB.cs
index 2f93a46dfeb8a173489445cddf2ce5e182207931..f115acaa1b264240ded63bb569d512bb2f1846c1 100644
--- a/src/Jackett/Indexers/BB.cs
+++ b/src/Jackett/Indexers/BB.cs
@@ -15,7 +15,7 @@ using System.Threading.Tasks;
 using System.Web;
 using Jackett.Models.IndexerConfig;
 using System.Collections.Specialized;
-
+
 namespace Jackett.Indexers
 {
     // To comply with the rules for this tracker, only the acronym is used and no publicly displayed URLs to the site. 
@@ -95,10 +95,10 @@ namespace Jackett.Indexers
 
             var searchString = query.GetQueryString();
             var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("action", "basic");
-
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("action", "basic");
+
             if (!string.IsNullOrWhiteSpace(searchString))
             {
                 queryCollection.Add("searchstr", searchString);
@@ -114,10 +114,10 @@ namespace Jackett.Indexers
             var results = await RequestStringWithCookiesAndRetry(searchUrl);
 
             // Occasionally the cookies become invalid, login again if that happens
-            if (results.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookiesAndRetry(searchUrl);
+            if (results.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookiesAndRetry(searchUrl);
             }
 
             try
@@ -155,10 +155,10 @@ namespace Jackett.Indexers
                     release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text().Trim()) + release.Seeders;
 
                     var grabs = qRow.Find("td:nth-child(6)").Text();
-                    release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                    if (qRow.Find("strong:contains(\"Freeleech!\")").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                    if (qRow.Find("strong:contains(\"Freeleech!\")").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/BJShare.cs b/src/Jackett/Indexers/BJShare.cs
index c742bf267dd208ac417ee73f47482b5daf9a85b5..958244770de1f342587118999f033c9e784339ae 100644
--- a/src/Jackett/Indexers/BJShare.cs
+++ b/src/Jackett/Indexers/BJShare.cs
@@ -10,11 +10,11 @@ using System;
 using System.Text;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using AngleSharp.Parser.Html;
-using AngleSharp.Dom;
-using System.Text.RegularExpressions;
-
+using System.Collections.Specialized;
+using AngleSharp.Parser.Html;
+using AngleSharp.Dom;
+using System.Text.RegularExpressions;
+
 namespace Jackett.Indexers
 {
     public class BJShare : BaseIndexer, IIndexer
@@ -39,7 +39,7 @@ namespace Jackett.Indexers
                    logger: l,
                    p: ps,
                    configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
+        {
             Encoding = Encoding.GetEncoding("UTF-8");
             Language = "pt-br";
             Type = "private";
@@ -63,8 +63,8 @@ namespace Jackett.Indexers
             AddCategoryMapping(11, TorznabCatType.Other); // Video-Aula
             AddCategoryMapping(6, TorznabCatType.TV); // Vídeos de TV
             AddCategoryMapping(4, TorznabCatType.Other); // Jogos
-            AddCategoryMapping(199, TorznabCatType.XXX); // Filmes Adultos
-            AddCategoryMapping(200, TorznabCatType.XXX); // Jogos Adultos
+            AddCategoryMapping(199, TorznabCatType.XXX); // Filmes Adultos
+            AddCategoryMapping(200, TorznabCatType.XXX); // Jogos Adultos
             AddCategoryMapping(201, TorznabCatType.XXXImageset); // Fotos Adultas
         }
 
@@ -80,241 +80,241 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
 
-        private string StripSearchString(string term)
-        {
-            // Search does not support searching with episode numbers so strip it if we have one
-            // Ww AND filter the result later to archive the proper result
-            term = Regex.Replace(term, @"[S|E]\d\d", string.Empty);
-            return term.Trim();
+        private string StripSearchString(string term)
+        {
+            // Search does not support searching with episode numbers so strip it if we have one
+            // Ww AND filter the result later to archive the proper result
+            term = Regex.Replace(term, @"[S|E]\d\d", string.Empty);
+            return term.Trim();
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            
-            // if the search string is empty use the "last 24h torrents" view
-            if (string.IsNullOrWhiteSpace(searchString))
-            {
+            var searchString = query.GetQueryString();
+            
+            // if the search string is empty use the "last 24h torrents" view
+            if (string.IsNullOrWhiteSpace(searchString))
+            {
                 var results = await RequestStringWithCookies(TodayUrl);
                 try
                 {
                     string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
 
-                    var SearchResultParser = new HtmlParser();
+                    var SearchResultParser = new HtmlParser();
                     var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                    foreach (var Row in Rows)
+                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                    foreach (var Row in Rows)
                     {
-                        try
+                        try
                         {
                             var release = new ReleaseInfo();
 
-                            release.MinimumRatio = 1;
+                            release.MinimumRatio = 1;
                             release.MinimumSeedTime = 0;
-
-                            var qDetailsLink = Row.QuerySelector("a.BJinfoBox");
-                            var qTitle = qDetailsLink.QuerySelector("font");
-                            release.Title = qTitle.TextContent;
-
-                            var qBJinfoBox = qDetailsLink.QuerySelector("span");
-                            var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
-                            var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
-                            var qSeeders = Row.QuerySelector("td:nth-child(4)");
-                            var qLeechers = Row.QuerySelector("td:nth-child(5)");
-                            var qFreeLeech = Row.QuerySelector("font[color=\"green\"]:contains(Free)");
-
-                            release.Description = "";
-                            foreach (var Child in qBJinfoBox.ChildNodes)
-                            {
-                                var type = Child.NodeType;
-                                if (type != NodeType.Text)
-                                    continue;
-
-                                var line = Child.TextContent;
-                                if (line.StartsWith("Tamanho:"))
-                                {
-                                    string Size = line.Substring("Tamanho: ".Length); ;
-                                    release.Size = ReleaseInfo.GetBytes(Size);
-                                }
-                                else if (line.StartsWith("Lançado em: "))
-                                {
-                                    string PublishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
-                                    PublishDateStr += " +0";
-                                    var PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(PublishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-                                    release.PublishDate = PublishDate.ToLocalTime();
-                                }
-                                else
-                                {
-                                    release.Description += line + "\n";
-                                }
-                            }
-
-
-                            var catStr = qCatLink.GetAttribute("href").Split('=')[1];
-                            release.Category = MapTrackerCatToNewznab(catStr);
-
-                            release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
-                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
-                            release.Guid = release.Link;
-
-                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
-                            release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
-
-
-                            if (qFreeLeech != null)
-                                release.DownloadVolumeFactor = 0;
+
+                            var qDetailsLink = Row.QuerySelector("a.BJinfoBox");
+                            var qTitle = qDetailsLink.QuerySelector("font");
+                            release.Title = qTitle.TextContent;
+
+                            var qBJinfoBox = qDetailsLink.QuerySelector("span");
+                            var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
+                            var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
+                            var qSeeders = Row.QuerySelector("td:nth-child(4)");
+                            var qLeechers = Row.QuerySelector("td:nth-child(5)");
+                            var qFreeLeech = Row.QuerySelector("font[color=\"green\"]:contains(Free)");
+
+                            release.Description = "";
+                            foreach (var Child in qBJinfoBox.ChildNodes)
+                            {
+                                var type = Child.NodeType;
+                                if (type != NodeType.Text)
+                                    continue;
+
+                                var line = Child.TextContent;
+                                if (line.StartsWith("Tamanho:"))
+                                {
+                                    string Size = line.Substring("Tamanho: ".Length); ;
+                                    release.Size = ReleaseInfo.GetBytes(Size);
+                                }
+                                else if (line.StartsWith("Lançado em: "))
+                                {
+                                    string PublishDateStr = line.Substring("Lançado em: ".Length).Replace("às ", "");
+                                    PublishDateStr += " +0";
+                                    var PublishDate = DateTime.SpecifyKind(DateTime.ParseExact(PublishDateStr, "dd/MM/yyyy HH:mm z", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+                                    release.PublishDate = PublishDate.ToLocalTime();
+                                }
+                                else
+                                {
+                                    release.Description += line + "\n";
+                                }
+                            }
+
+
+                            var catStr = qCatLink.GetAttribute("href").Split('=')[1];
+                            release.Category = MapTrackerCatToNewznab(catStr);
+
+                            release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
+                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
+                            release.Guid = release.Link;
+
+                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
+                            release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
+
+
+                            if (qFreeLeech != null)
+                                release.DownloadVolumeFactor = 0;
                             else
-                                release.DownloadVolumeFactor = 1;
-
+                                release.DownloadVolumeFactor = 1;
+
                             release.UploadVolumeFactor = 1;
 
-                            releases.Add(release);
-                        }
-                        catch (Exception ex)
-                        {
-                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
+                            releases.Add(release);
                         }
-                    }
+                        catch (Exception ex)
+                        {
+                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
+                        }
+                    }
                 }
                 catch (Exception ex)
                 {
                     OnParseError(results.Content, ex);
-                }
+                }
             }
-            else // use search
+            else // use search
             {
-                var searchUrl = BrowseUrl;
-
-                var queryCollection = new NameValueCollection();
-                queryCollection.Add("searchstr", StripSearchString(searchString));
-                queryCollection.Add("order_by", "time");
-                queryCollection.Add("order_way", "desc");
-                queryCollection.Add("group_results", "1");
-                queryCollection.Add("action", "basic");
-                queryCollection.Add("searchsubmit", "1");
-
-                foreach (var cat in MapTorznabCapsToTrackers(query))
-                {
-                    queryCollection.Add("filter_cat["+cat+"]", "1");
-                }
-
-                searchUrl += "?" + queryCollection.GetQueryString();
-
+                var searchUrl = BrowseUrl;
+
+                var queryCollection = new NameValueCollection();
+                queryCollection.Add("searchstr", StripSearchString(searchString));
+                queryCollection.Add("order_by", "time");
+                queryCollection.Add("order_way", "desc");
+                queryCollection.Add("group_results", "1");
+                queryCollection.Add("action", "basic");
+                queryCollection.Add("searchsubmit", "1");
+
+                foreach (var cat in MapTorznabCapsToTrackers(query))
+                {
+                    queryCollection.Add("filter_cat["+cat+"]", "1");
+                }
+
+                searchUrl += "?" + queryCollection.GetQueryString();
+
                 var results = await RequestStringWithCookies(searchUrl);
                 try
                 {
                     string RowsSelector = "table.torrent_table > tbody > tr:not(tr.colhead)";
 
-                    var SearchResultParser = new HtmlParser();
+                    var SearchResultParser = new HtmlParser();
                     var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-
-                    ICollection<int> GroupCategory = null;
-                    string GroupTitle = null;
-                    string GroupYearStr = null;
-                    Nullable<DateTime> GroupPublishDate = null;
-
-                    foreach (var Row in Rows)
+                    var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+
+                    ICollection<int> GroupCategory = null;
+                    string GroupTitle = null;
+                    string GroupYearStr = null;
+                    Nullable<DateTime> GroupPublishDate = null;
+
+                    foreach (var Row in Rows)
                     {
-                        try
-                        {
-                            var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
-                            string Title = qDetailsLink.TextContent;
-                            ICollection<int> Category = null;
-                            string YearStr = null;
-                            Nullable<DateTime> YearPublishDate = null;
-
-                            if (Row.ClassList.Contains("group") || Row.ClassList.Contains("torrent")) // group/ungrouped headers
-                            {
-                                var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
-                                string CategoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
-                                Category = MapTrackerCatToNewznab(CategoryStr);
-                                YearStr = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
-                                YearPublishDate = DateTime.SpecifyKind(DateTime.ParseExact(YearStr, "yyyy", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                                if (Row.ClassList.Contains("group")) // group headers
-                                {
-                                    GroupCategory = Category;
-                                    GroupTitle = Title;
-                                    GroupYearStr = YearStr;
-                                    GroupPublishDate = YearPublishDate;
-                                    continue;
-                                }
-                            }
-
+                        try
+                        {
+                            var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
+                            string Title = qDetailsLink.TextContent;
+                            ICollection<int> Category = null;
+                            string YearStr = null;
+                            Nullable<DateTime> YearPublishDate = null;
+
+                            if (Row.ClassList.Contains("group") || Row.ClassList.Contains("torrent")) // group/ungrouped headers
+                            {
+                                var qCatLink = Row.QuerySelector("a[href^=\"/torrents.php?filter_cat\"]");
+                                string CategoryStr = qCatLink.GetAttribute("href").Split('=')[1].Split('&')[0];
+                                Category = MapTrackerCatToNewznab(CategoryStr);
+                                YearStr = qDetailsLink.NextSibling.TextContent.Trim().TrimStart('[').TrimEnd(']');
+                                YearPublishDate = DateTime.SpecifyKind(DateTime.ParseExact(YearStr, "yyyy", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                                if (Row.ClassList.Contains("group")) // group headers
+                                {
+                                    GroupCategory = Category;
+                                    GroupTitle = Title;
+                                    GroupYearStr = YearStr;
+                                    GroupPublishDate = YearPublishDate;
+                                    continue;
+                                }
+                            }
+
                             var release = new ReleaseInfo();
 
-                            release.MinimumRatio = 1;
-                            release.MinimumSeedTime = 0;
-
-                            var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
-                            var qSize = Row.QuerySelector("td:nth-last-child(4)");
-                            var qSeeders = Row.QuerySelector("td:nth-last-child(3)");
-                            var qLeechers = Row.QuerySelector("td:nth-last-child(2)");
-                            var qFreeLeech = Row.QuerySelector("strong[title=\"Free\"]");
-
-                            if (Row.ClassList.Contains("group_torrent")) // torrents belonging to a group
-                            {
-                                release.Description = qDetailsLink.TextContent;
-                                release.Title = GroupTitle + " " + GroupYearStr;
-                                release.PublishDate = GroupPublishDate.Value;
-                                release.Category = GroupCategory;
-                            }
-                            else if (Row.ClassList.Contains("torrent")) // standalone/un grouped torrents
-                            {
-                                var qDescription = Row.QuerySelector("div.torrent_info");
-                                release.Description = qDescription.TextContent;
-                                release.Title = Title + " " + YearStr;
-                                release.PublishDate = YearPublishDate.Value;
-                                release.Category = Category;
-                            }
-
-                            release.Description = release.Description.Replace(" / Free", ""); // Remove Free Tag
-                            release.Title += " " + release.Description; // add year and Description to the release Title to add some meaning to it
-
-                            // check for previously stripped search terms
-                            if (!query.MatchQueryStringAND(release.Title))
-                                continue;
-
-                            var Size = qSize.TextContent;
-                            release.Size = ReleaseInfo.GetBytes(Size);
-
-                            release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
-                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
-                            release.Guid = release.Link;
-
-                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
-                            release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
-
-                            if (qFreeLeech != null)
-                                release.DownloadVolumeFactor = 0;
+                            release.MinimumRatio = 1;
+                            release.MinimumSeedTime = 0;
+
+                            var qDLLink = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
+                            var qSize = Row.QuerySelector("td:nth-last-child(4)");
+                            var qSeeders = Row.QuerySelector("td:nth-last-child(3)");
+                            var qLeechers = Row.QuerySelector("td:nth-last-child(2)");
+                            var qFreeLeech = Row.QuerySelector("strong[title=\"Free\"]");
+
+                            if (Row.ClassList.Contains("group_torrent")) // torrents belonging to a group
+                            {
+                                release.Description = qDetailsLink.TextContent;
+                                release.Title = GroupTitle + " " + GroupYearStr;
+                                release.PublishDate = GroupPublishDate.Value;
+                                release.Category = GroupCategory;
+                            }
+                            else if (Row.ClassList.Contains("torrent")) // standalone/un grouped torrents
+                            {
+                                var qDescription = Row.QuerySelector("div.torrent_info");
+                                release.Description = qDescription.TextContent;
+                                release.Title = Title + " " + YearStr;
+                                release.PublishDate = YearPublishDate.Value;
+                                release.Category = Category;
+                            }
+
+                            release.Description = release.Description.Replace(" / Free", ""); // Remove Free Tag
+                            release.Title += " " + release.Description; // add year and Description to the release Title to add some meaning to it
+
+                            // check for previously stripped search terms
+                            if (!query.MatchQueryStringAND(release.Title))
+                                continue;
+
+                            var Size = qSize.TextContent;
+                            release.Size = ReleaseInfo.GetBytes(Size);
+
+                            release.Link = new Uri(SiteLink + qDLLink.GetAttribute("href"));
+                            release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
+                            release.Guid = release.Link;
+
+                            release.Seeders = ParseUtil.CoerceInt(qSeeders.TextContent);
+                            release.Peers = ParseUtil.CoerceInt(qLeechers.TextContent) + release.Seeders;
+
+                            if (qFreeLeech != null)
+                                release.DownloadVolumeFactor = 0;
                             else
-                                release.DownloadVolumeFactor = 1;
-
+                                release.DownloadVolumeFactor = 1;
+
                             release.UploadVolumeFactor = 1;
 
-                            releases.Add(release);
-                        }
-                        catch (Exception ex)
-                        {
-                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
+                            releases.Add(release);
                         }
-                    }
+                        catch (Exception ex)
+                        {
+                            logger.Error(string.Format("{0}: Error while parsing row '{1}': {2}", ID, Row.OuterHtml, ex.Message));
+                        }
+                    }
                 }
                 catch (Exception ex)
                 {
                     OnParseError(results.Content, ex);
-                }
+                }
             }
 
             return releases;
diff --git a/src/Jackett/Indexers/BaseIndexer.cs b/src/Jackett/Indexers/BaseIndexer.cs
index d35f10ce377397ce85bdfed3adfa857bebd58799..3faca56d4ac3bdca6720dacea6b487b7bcf21772 100644
--- a/src/Jackett/Indexers/BaseIndexer.cs
+++ b/src/Jackett/Indexers/BaseIndexer.cs
@@ -1,645 +1,645 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models;
-using Newtonsoft.Json.Linq;
-using NLog;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using AutoMapper;
-using System.Threading;
-using Jackett.Models.IndexerConfig;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public abstract class BaseIndexer
-    {
-        public string SiteLink { get; protected set; }
-        public string DefaultSiteLink { get; protected set; }
-        public string[] AlternativeSiteLinks { get; protected set; } = new string[] { };
-        public string DisplayDescription { get; protected set; }
-        public string DisplayName { get; protected set; }
-        public string Language { get; protected set; }
-        public Encoding Encoding { get; protected set; }
-        public string Type { get; protected set; }
-        public string ID { get { return GetIndexerID(GetType()); } }
-
-        public bool IsConfigured { get; protected set; }
-        public TorznabCapabilities TorznabCaps { get; protected set; }
-        protected Logger logger;
-        protected IIndexerManagerService indexerService;
-        protected static List<CachedQueryResult> cache = new List<CachedQueryResult>();
-        protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
-        protected IWebClient webclient;
-        protected IProtectionService protectionService;
-        protected readonly string downloadUrlBase = "";
-
-        protected string CookieHeader
-        {
-            get { return configData.CookieHeader.Value; }
-            set { configData.CookieHeader.Value = value; }
-        }
-
-        public string LastError
-        {
-            get { return configData.LastError.Value; }
-            set
-            {
-                bool SaveNeeded = configData.LastError.Value != value && IsConfigured;
-                configData.LastError.Value = value;
-                if (SaveNeeded)
-                    SaveConfig();
-            }
-        }
-
-        protected ConfigurationData configData;
-
-        private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
-
-        // standard constructor used by most indexers
-        public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, string downloadBase = null)
-            : this(manager, client, logger, p)
-        {
-            if (!link.EndsWith("/"))
-                throw new Exception("Site link must end with a slash.");
-
-            DisplayName = name;
-            DisplayDescription = description;
-            SiteLink = link;
-            DefaultSiteLink = link;
-            this.downloadUrlBase = downloadBase;
-            this.configData = configData;
-            LoadValuesFromJson(null);
-
-            if (caps == null)
-                caps = TorznabUtil.CreateDefaultTorznabTVCaps();
-            TorznabCaps = caps;
-
-        }
-
-        // minimal constructor used by e.g. cardigann generic indexer
-        public BaseIndexer(IIndexerManagerService manager, IWebClient client, Logger logger, IProtectionService p)
-        {
-            this.logger = logger;
-            indexerService = manager;
-            webclient = client;
-            protectionService = p;
-        }
-
-        public IEnumerable<ReleaseInfo> CleanLinks(IEnumerable<ReleaseInfo> releases)
-        {
-            if (string.IsNullOrEmpty(downloadUrlBase))
-                return releases;
-            foreach (var release in releases)
-            {
-                if (release.Link.ToString().StartsWith(downloadUrlBase))
-                {
-                    release.Link = new Uri(release.Link.ToString().Substring(downloadUrlBase.Length), UriKind.Relative);
-                }
-            }
-
-            return releases;
-        }
-
-        public Uri UncleanLink(Uri link)
-        {
-            if (string.IsNullOrWhiteSpace(downloadUrlBase))
-            {
-                return link;
-            }
-
-            if (link.ToString().StartsWith(downloadUrlBase))
-            {
-                return link;
-            }
-
-            return new Uri(downloadUrlBase + link.ToString(), UriKind.RelativeOrAbsolute);
-        }
-
-        protected ICollection<int> MapTrackerCatToNewznab(string input)
-        {
-            var cats = new List<int>();
-            if (null != input)
-            {
-                var mapping = categoryMapping.Where(m => m.TrackerCategory != null && m.TrackerCategory.ToLowerInvariant() == input.ToLowerInvariant()).FirstOrDefault();
-                if (mapping != null)
-                {
-                    cats.Add(mapping.NewzNabCategory);
-                }
-
-                // 1:1 category mapping
-                try
-                {
-                    var trackerCategoryInt = int.Parse(input);
-                    cats.Add(trackerCategoryInt + 100000);
-                }
-                catch (FormatException)
-                {
-                    // input is not an integer, continue
-                }
-            }
-            return cats;
-        }
-
-        protected ICollection<int> MapTrackerCatDescToNewznab(string input)
-        {
-            var cats = new List<int>();
-            if (null != input)
-            {
-                var mapping = categoryMapping.Where(m => m.TrackerCategoryDesc != null && m.TrackerCategoryDesc.ToLowerInvariant() == input.ToLowerInvariant()).FirstOrDefault();
-                if (mapping != null)
-                {
-                    cats.Add(mapping.NewzNabCategory);
-
-                    if (mapping.TrackerCategory != null)
-                    {
-                        // 1:1 category mapping
-                        try
-                        {
-                            var trackerCategoryInt = int.Parse(mapping.TrackerCategory);
-                            cats.Add(trackerCategoryInt + 100000);
-                        }
-                        catch (FormatException)
-                        {
-                            // mapping.TrackerCategory is not an integer, continue
-                        }
-                    }
-                }
-            }
-            return cats;
-        }
-
-        public static string GetIndexerID(Type type)
-        {
-            return StringUtil.StripNonAlphaNumeric(type.Name.ToLowerInvariant());
-        }
-
-        public virtual Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            return Task.FromResult<ConfigurationData>(configData);
-        }
-
-        public virtual void ResetBaseConfig()
-        {
-            CookieHeader = string.Empty;
-            IsConfigured = false;
-        }
-
-        public virtual void SaveConfig()
-        {
-            indexerService.SaveConfig(this as IIndexer, configData.ToJson(protectionService, forDisplay: false));
-        }
-
-        protected void OnParseError(string results, Exception ex)
-        {
-            var fileName = string.Format("Error on {0} for {1}.txt", DateTime.Now.ToString("yyyyMMddHHmmss"), DisplayName);
-            var spacing = string.Join("", Enumerable.Repeat(Environment.NewLine, 5));
-            var fileContents = string.Format("{0}{1}{2}", ex, spacing, results);
-            logger.Error(fileName + fileContents);
-            throw ex;
-        }
-
-        protected void CleanCache()
-        {
-            foreach (var expired in cache.Where(i => DateTime.Now - i.Created > cacheTime).ToList())
-            {
-                cache.Remove(expired);
-            }
-        }
-
-        protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
-        {
-            var byteResult = new WebClientByteResult();
-            // Map to byte
-            Mapper.Map(response, byteResult);
-            await FollowIfRedirect(byteResult, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
-            // Map to string
-            Mapper.Map(byteResult, response);
-        }
-
-        protected async Task FollowIfRedirect(WebClientByteResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
-        {
-            // Follow up  to 5 redirects
-            for (int i = 0; i < 5; i++)
-            {
-                if (!response.IsRedirect)
-                    break;
-                await DoFollowIfRedirect(response, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
-                if (accumulateCookies)
-                {
-                    CookieHeader = ResolveCookies((CookieHeader != null && CookieHeader != ""? CookieHeader + " " : "") + (overrideCookies != null && overrideCookies != "" ? overrideCookies + " " : "") + response.Cookies);
-                    overrideCookies = response.Cookies = CookieHeader;
-                }
-                if (overrideCookies != null && response.Cookies == null)
-                {
-                    response.Cookies = overrideCookies;
-                }
-            }
-        }
-
-        private String ResolveCookies(String incomingCookies = "")
-        {
-            var redirRequestCookies = (CookieHeader != null && CookieHeader != "" ? CookieHeader + " " : "") + incomingCookies;
-            System.Text.RegularExpressions.Regex expression = new System.Text.RegularExpressions.Regex(@"([^\\,;\s]+)=([^=\\,;\s]*)");
-            Dictionary<string, string> cookieDIctionary = new Dictionary<string, string>();
-            var matches = expression.Match(redirRequestCookies);
-            while (matches.Success)
-            {
-                if (matches.Groups.Count > 2) cookieDIctionary[matches.Groups[1].Value] = matches.Groups[2].Value;
-                matches = matches.NextMatch();
-            }
-            return string.Join("; ", cookieDIctionary.Select(kv => kv.Key.ToString() + "=" + kv.Value.ToString()).ToArray());
-            
-        }
-
-        // Update CookieHeader with new cookies and save the config if something changed (e.g. a new CloudFlare clearance cookie was issued)
-        protected void UpdateCookieHeader(string newCookies, string cookieOverride = null)
-        {
-            string newCookieHeader = ResolveCookies((cookieOverride != null && cookieOverride != "" ? cookieOverride + " " : "") + newCookies);
-            if (CookieHeader != newCookieHeader)
-            {
-                logger.Debug(string.Format("updating Cookies {0} => {1}", CookieHeader, newCookieHeader));
-                CookieHeader = newCookieHeader;
-                if (IsConfigured)
-                    SaveConfig();
-            }
-        }
-
-        private async Task DoFollowIfRedirect(WebClientByteResult incomingResponse, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
-        {
-            if (incomingResponse.IsRedirect)
-            {
-                var redirRequestCookies = "";
-                if (accumulateCookies)
-                {
-                    redirRequestCookies = ResolveCookies((CookieHeader != "" ? CookieHeader + " " : "") + (overrideCookies != null ? overrideCookies : ""));
-                } else
-                {
-                    redirRequestCookies = (overrideCookies != null ? overrideCookies : "");
-                }
-                // Do redirect
-                var redirectedResponse = await webclient.GetBytes(new WebRequest()
-                {
-                    Url = overrideRedirectUrl ?? incomingResponse.RedirectingTo,
-                    Referer = referrer,
-                    Cookies = redirRequestCookies,
-                    Encoding = Encoding
-                });
-                Mapper.Map(redirectedResponse, incomingResponse);
-            }
-        }
-
-
-        protected void LoadLegacyCookieConfig(JToken jsonConfig)
-        {
-            string legacyCookieHeader = (string)jsonConfig["cookie_header"];
-            if (!string.IsNullOrEmpty(legacyCookieHeader))
-            {
-                CookieHeader = legacyCookieHeader;
-            }
-            else
-            {
-                // Legacy cookie key
-                var jcookies = jsonConfig["cookies"];
-                if (jcookies is JArray)
-                {
-                    var array = (JArray)jcookies;
-                    legacyCookieHeader = string.Empty;
-                    for (int i = 0; i < array.Count; i++)
-                    {
-                        if (i != 0)
-                            legacyCookieHeader += "; ";
-                        legacyCookieHeader += array[i];
-                    }
-                    CookieHeader = legacyCookieHeader;
-                }
-                else if (jcookies != null)
-                {
-                    CookieHeader = (string)jcookies;
-                }
-            }
-        }
-
-        virtual public void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
-        {
-            IProtectionService ps = null;
-            if (useProtectionService)
-                ps = protectionService;
-            configData.LoadValuesFromJson(jsonConfig, ps);
-            if (string.IsNullOrWhiteSpace(configData.SiteLink.Value))
-            {
-                configData.SiteLink.Value = DefaultSiteLink;
-            }
-            if (!configData.SiteLink.Value.EndsWith("/"))
-                configData.SiteLink.Value += "/";
-
-            var match = Regex.Match(configData.SiteLink.Value, "^https?:\\/\\/[\\w\\-\\/\\.]+$");
-            if (!match.Success)
-            {
-                throw new Exception(string.Format("\"{0}\" is not a valid URL.", configData.SiteLink.Value));
-            }
-
-            SiteLink = configData.SiteLink.Value;
-        }
-
-        public virtual void LoadFromSavedConfiguration(JToken jsonConfig)
-        {
-            if (jsonConfig is JArray)
-            {
-                LoadValuesFromJson(jsonConfig, true);
-                IsConfigured = true;
-            }
-            // read and upgrade old settings file format
-            else if (jsonConfig is Object)
-            {
-                LoadLegacyCookieConfig(jsonConfig);
-                SaveConfig();
-                IsConfigured = true;
-            }
-        }
-
-        public async virtual Task<byte[]> Download(Uri link)
-        {
-            return await Download(link, RequestType.GET);
-        }
-
-        public async virtual Task<byte[]> Download(Uri link, RequestType method = RequestType.GET)
-        {
-            // do some extra escaping, needed for HD-Torrents
-            var requestLink = link.ToString()
-                .Replace("(", "%28")
-                .Replace(")", "%29")
-                .Replace("'", "%27");
-            var response = await RequestBytesWithCookiesAndRetry(requestLink, null, method, requestLink);
-            if (response.Status != System.Net.HttpStatusCode.OK && response.Status != System.Net.HttpStatusCode.Continue && response.Status != System.Net.HttpStatusCode.PartialContent)
-            {
-                logger.Error("Failed download cookies: " + this.CookieHeader);
-                if (response.Content != null)
-                    logger.Error("Failed download response:\n" + Encoding.UTF8.GetString(response.Content));
-                throw new Exception($"Remote server returned {response.Status.ToString()}" + (response.IsRedirect ? " => "+response.RedirectingTo : ""));
-            }
-
-            return response.Content;
-        }
-
-        protected async Task<WebClientByteResult> RequestBytesWithCookiesAndRetry(string url, string cookieOverride = null, RequestType method = RequestType.GET, string referer = null, IEnumerable<KeyValuePair<string, string>> data = null)
-        {
-            Exception lastException = null;
-            for (int i = 0; i < 3; i++)
-            {
-                try
-                {
-                    return await RequestBytesWithCookies(url, cookieOverride, method, referer, data);
-                }
-                catch (Exception e)
-                {
-                    logger.Error(e, string.Format("On attempt {0} downloading from {1}: {2}", (i + 1), DisplayName, e.Message));
-                    lastException = e;
-                }
-                await Task.Delay(500);
-            }
-
-            throw lastException;
-        }
-
-        protected async Task<WebClientStringResult> RequestStringWithCookies(string url, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null)
-        {
-            var request = new Utils.Clients.WebRequest()
-            {
-                Url = url,
-                Type = RequestType.GET,
-                Cookies = CookieHeader,
-                Referer = referer,
-                Headers = headers,
-                Encoding = Encoding
-            };
-
-            if (cookieOverride != null)
-                request.Cookies = cookieOverride;
-            WebClientStringResult result = await webclient.GetString(request);
-            UpdateCookieHeader(result.Cookies, cookieOverride);
-            return result;
-        }
-
-        protected async Task<WebClientStringResult> RequestStringWithCookiesAndRetry(string url, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null)
-        {
-            Exception lastException = null;
-            for (int i = 0; i < 3; i++)
-            {
-                try
-                {
-                    return await RequestStringWithCookies(url, cookieOverride, referer, headers);
-                }
-                catch (Exception e)
-                {
-                    logger.Error(string.Format("On attempt {0} checking for results from {1}: {2}", (i + 1), DisplayName, e.Message));
-                    lastException = e;
-                }
-                await Task.Delay(500);
-            }
-
-            throw lastException;
-        }
-
-        protected async Task<WebClientByteResult> RequestBytesWithCookies(string url, string cookieOverride = null, RequestType method = RequestType.GET, string referer = null, IEnumerable<KeyValuePair<string, string>> data = null, Dictionary<string, string> headers = null)
-        {
-            var request = new Utils.Clients.WebRequest()
-            {
-                Url = url,
-                Type = method,
-                Cookies = cookieOverride ?? CookieHeader,
-                PostData = data,
-                Referer = referer,
-                Headers = headers,
-                Encoding = Encoding
-            };
-
-            if (cookieOverride != null)
-                request.Cookies = cookieOverride;
-            return await webclient.GetBytes(request);
-        }
-
-        protected async Task<WebClientStringResult> PostDataWithCookies(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null, bool? emulateBrowser = null)
-        {
-            var request = new Utils.Clients.WebRequest()
-            {
-                Url = url,
-                Type = RequestType.POST,
-                Cookies = cookieOverride ?? CookieHeader,
-                PostData = data,
-                Referer = referer,
-                Headers = headers,
-                RawBody = rawbody,
-                Encoding = Encoding
-            };
-
-            if (emulateBrowser.HasValue)
-                request.EmulateBrowser = emulateBrowser.Value;
-            WebClientStringResult result = await webclient.GetString(request);
-            UpdateCookieHeader(result.Cookies, cookieOverride);
-            return result;
-        }
-
-        protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null, bool? emulateBrowser = null)
-        {
-            Exception lastException = null;
-            for (int i = 0; i < 3; i++)
-            {
-                try
-                {
-                    return await PostDataWithCookies(url, data, cookieOverride, referer, headers, rawbody, emulateBrowser);
-                }
-                catch (Exception e)
-                {
-                    logger.Error(string.Format("On attempt {0} checking for results from {1}: {2}", (i + 1), DisplayName, e.Message));
-                    lastException = e;
-                }
-                await Task.Delay(500);
-            }
-
-            throw lastException;
-        }
-
-        protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, IEnumerable<KeyValuePair<string, string>> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer = null, bool accumulateCookies = false)
-        {
-            var request = new Utils.Clients.WebRequest()
-            {
-                Url = url,
-                Type = RequestType.POST,
-                Cookies = cookies,
-                Referer = referer,
-                PostData = data,
-                Encoding = Encoding
-            };
-            var response = await webclient.GetString(request);
-            if (accumulateCookies)
-            {
-                response.Cookies = ResolveCookies((request.Cookies == null ? "" : request.Cookies + " ") + response.Cookies);
-            }
-            var firstCallCookies = response.Cookies;
-
-            if (response.IsRedirect)
-            {
-                await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies, accumulateCookies);
-            }
-
-            if (returnCookiesFromFirstCall)
-            {
-                response.Cookies = ResolveCookies(firstCallCookies + (accumulateCookies ? " " + response.Cookies : ""));
-            }
-            
-            return response;
-        }
-
-        protected async Task ConfigureIfOK(string cookies, bool isLoggedin, Func<Task> onError)
-        {
-            if (isLoggedin)
-            {
-                CookieHeader = cookies;
-                SaveConfig();
-                IsConfigured = true;
-            }
-            else
-            {
-                await onError();
-            }
-        }
-
-        public virtual IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> results)
-        {
-            foreach (var result in results)
-            {
-                if (query.Categories.Length == 0 || result.Category == null || result.Category.Count() == 0 || query.Categories.Intersect(result.Category).Any() || TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category))
-                {
-                    yield return result;
-                }
-            }
-        }
-
-        protected List<string> GetAllTrackerCategories()
-        {
-            return categoryMapping.Select(x => x.TrackerCategory).ToList();
-        }
-
-        protected void AddCategoryMapping(string trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
-        {
-            categoryMapping.Add(new CategoryMapping(trackerCategory, trackerCategoryDesc, newznabCategory.ID));
-            if (!TorznabCaps.Categories.Contains(newznabCategory))
-            {
-                TorznabCaps.Categories.Add(newznabCategory);
-                if (TorznabCatType.Movies.Contains(newznabCategory))
-                    TorznabCaps.MovieSearchAvailable = true;
-            }
-
-            // add 1:1 categories
-            if (trackerCategoryDesc != null && trackerCategory != null)
-            {
-                try
-                {
-                    var trackerCategoryInt = int.Parse(trackerCategory);
-                    var CustomCat = new TorznabCategory(trackerCategoryInt + 100000, trackerCategoryDesc);
-                    if (!TorznabCaps.Categories.Contains(CustomCat))
-                        TorznabCaps.Categories.Add(CustomCat);
-                }
-                catch (FormatException)
-                {
-                    // trackerCategory is not an integer, continue
-                }
-            }
-        }
-
-        protected void AddCategoryMapping(int trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
-        {
-            AddCategoryMapping(trackerCategory.ToString(), newznabCategory, trackerCategoryDesc);
-        }
-
-        protected void AddMultiCategoryMapping(TorznabCategory newznabCategory, params int[] trackerCategories)
-        {
-            foreach (var trackerCat in trackerCategories)
-            {
-                AddCategoryMapping(trackerCat, newznabCategory);
-            }
-        }
-
-        protected virtual List<string> MapTorznabCapsToTrackers(TorznabQuery query, bool mapChildrenCatsToParent = false)
-        {
-            var result = new List<string>();
-            foreach (var cat in query.Categories)
-            {
-                // use 1:1 mapping to tracker categories for newznab categories >= 100000
-                if (cat >= 100000)
-                {
-                    result.Add((cat - 100000).ToString());
-                    continue;
-                }
-
-                var queryCats = new List<int> { cat };
-                var newznabCat = TorznabCatType.AllCats.FirstOrDefault(c => c.ID == cat);
-                if (newznabCat != null)
-                {
-                    queryCats.AddRange(newznabCat.SubCategories.Select(c => c.ID));
-                }
-
-                if (mapChildrenCatsToParent)
-                {
-                    var parentNewznabCat = TorznabCatType.AllCats.FirstOrDefault(c => c.SubCategories.Contains(newznabCat));
-                    if (parentNewznabCat != null)
-                    {
-                        queryCats.Add(parentNewznabCat.ID);
-                    }
-                }
-
-                foreach (var mapping in categoryMapping.Where(c => queryCats.Contains(c.NewzNabCategory)))
-                {
-                    result.Add(mapping.TrackerCategory);
-                }
-            }
-
-            return result.Distinct().ToList();
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models;
+using Newtonsoft.Json.Linq;
+using NLog;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using AutoMapper;
+using System.Threading;
+using Jackett.Models.IndexerConfig;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public abstract class BaseIndexer
+    {
+        public string SiteLink { get; protected set; }
+        public string DefaultSiteLink { get; protected set; }
+        public string[] AlternativeSiteLinks { get; protected set; } = new string[] { };
+        public string DisplayDescription { get; protected set; }
+        public string DisplayName { get; protected set; }
+        public string Language { get; protected set; }
+        public Encoding Encoding { get; protected set; }
+        public string Type { get; protected set; }
+        public string ID { get { return GetIndexerID(GetType()); } }
+
+        public bool IsConfigured { get; protected set; }
+        public TorznabCapabilities TorznabCaps { get; protected set; }
+        protected Logger logger;
+        protected IIndexerManagerService indexerService;
+        protected static List<CachedQueryResult> cache = new List<CachedQueryResult>();
+        protected static readonly TimeSpan cacheTime = new TimeSpan(0, 9, 0);
+        protected IWebClient webclient;
+        protected IProtectionService protectionService;
+        protected readonly string downloadUrlBase = "";
+
+        protected string CookieHeader
+        {
+            get { return configData.CookieHeader.Value; }
+            set { configData.CookieHeader.Value = value; }
+        }
+
+        public string LastError
+        {
+            get { return configData.LastError.Value; }
+            set
+            {
+                bool SaveNeeded = configData.LastError.Value != value && IsConfigured;
+                configData.LastError.Value = value;
+                if (SaveNeeded)
+                    SaveConfig();
+            }
+        }
+
+        protected ConfigurationData configData;
+
+        private List<CategoryMapping> categoryMapping = new List<CategoryMapping>();
+
+        // standard constructor used by most indexers
+        public BaseIndexer(string name, string link, string description, IIndexerManagerService manager, IWebClient client, Logger logger, ConfigurationData configData, IProtectionService p, TorznabCapabilities caps = null, string downloadBase = null)
+            : this(manager, client, logger, p)
+        {
+            if (!link.EndsWith("/"))
+                throw new Exception("Site link must end with a slash.");
+
+            DisplayName = name;
+            DisplayDescription = description;
+            SiteLink = link;
+            DefaultSiteLink = link;
+            this.downloadUrlBase = downloadBase;
+            this.configData = configData;
+            LoadValuesFromJson(null);
+
+            if (caps == null)
+                caps = TorznabUtil.CreateDefaultTorznabTVCaps();
+            TorznabCaps = caps;
+
+        }
+
+        // minimal constructor used by e.g. cardigann generic indexer
+        public BaseIndexer(IIndexerManagerService manager, IWebClient client, Logger logger, IProtectionService p)
+        {
+            this.logger = logger;
+            indexerService = manager;
+            webclient = client;
+            protectionService = p;
+        }
+
+        public IEnumerable<ReleaseInfo> CleanLinks(IEnumerable<ReleaseInfo> releases)
+        {
+            if (string.IsNullOrEmpty(downloadUrlBase))
+                return releases;
+            foreach (var release in releases)
+            {
+                if (release.Link.ToString().StartsWith(downloadUrlBase))
+                {
+                    release.Link = new Uri(release.Link.ToString().Substring(downloadUrlBase.Length), UriKind.Relative);
+                }
+            }
+
+            return releases;
+        }
+
+        public Uri UncleanLink(Uri link)
+        {
+            if (string.IsNullOrWhiteSpace(downloadUrlBase))
+            {
+                return link;
+            }
+
+            if (link.ToString().StartsWith(downloadUrlBase))
+            {
+                return link;
+            }
+
+            return new Uri(downloadUrlBase + link.ToString(), UriKind.RelativeOrAbsolute);
+        }
+
+        protected ICollection<int> MapTrackerCatToNewznab(string input)
+        {
+            var cats = new List<int>();
+            if (null != input)
+            {
+                var mapping = categoryMapping.Where(m => m.TrackerCategory != null && m.TrackerCategory.ToLowerInvariant() == input.ToLowerInvariant()).FirstOrDefault();
+                if (mapping != null)
+                {
+                    cats.Add(mapping.NewzNabCategory);
+                }
+
+                // 1:1 category mapping
+                try
+                {
+                    var trackerCategoryInt = int.Parse(input);
+                    cats.Add(trackerCategoryInt + 100000);
+                }
+                catch (FormatException)
+                {
+                    // input is not an integer, continue
+                }
+            }
+            return cats;
+        }
+
+        protected ICollection<int> MapTrackerCatDescToNewznab(string input)
+        {
+            var cats = new List<int>();
+            if (null != input)
+            {
+                var mapping = categoryMapping.Where(m => m.TrackerCategoryDesc != null && m.TrackerCategoryDesc.ToLowerInvariant() == input.ToLowerInvariant()).FirstOrDefault();
+                if (mapping != null)
+                {
+                    cats.Add(mapping.NewzNabCategory);
+
+                    if (mapping.TrackerCategory != null)
+                    {
+                        // 1:1 category mapping
+                        try
+                        {
+                            var trackerCategoryInt = int.Parse(mapping.TrackerCategory);
+                            cats.Add(trackerCategoryInt + 100000);
+                        }
+                        catch (FormatException)
+                        {
+                            // mapping.TrackerCategory is not an integer, continue
+                        }
+                    }
+                }
+            }
+            return cats;
+        }
+
+        public static string GetIndexerID(Type type)
+        {
+            return StringUtil.StripNonAlphaNumeric(type.Name.ToLowerInvariant());
+        }
+
+        public virtual Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            return Task.FromResult<ConfigurationData>(configData);
+        }
+
+        public virtual void ResetBaseConfig()
+        {
+            CookieHeader = string.Empty;
+            IsConfigured = false;
+        }
+
+        public virtual void SaveConfig()
+        {
+            indexerService.SaveConfig(this as IIndexer, configData.ToJson(protectionService, forDisplay: false));
+        }
+
+        protected void OnParseError(string results, Exception ex)
+        {
+            var fileName = string.Format("Error on {0} for {1}.txt", DateTime.Now.ToString("yyyyMMddHHmmss"), DisplayName);
+            var spacing = string.Join("", Enumerable.Repeat(Environment.NewLine, 5));
+            var fileContents = string.Format("{0}{1}{2}", ex, spacing, results);
+            logger.Error(fileName + fileContents);
+            throw ex;
+        }
+
+        protected void CleanCache()
+        {
+            foreach (var expired in cache.Where(i => DateTime.Now - i.Created > cacheTime).ToList())
+            {
+                cache.Remove(expired);
+            }
+        }
+
+        protected async Task FollowIfRedirect(WebClientStringResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
+        {
+            var byteResult = new WebClientByteResult();
+            // Map to byte
+            Mapper.Map(response, byteResult);
+            await FollowIfRedirect(byteResult, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
+            // Map to string
+            Mapper.Map(byteResult, response);
+        }
+
+        protected async Task FollowIfRedirect(WebClientByteResult response, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
+        {
+            // Follow up  to 5 redirects
+            for (int i = 0; i < 5; i++)
+            {
+                if (!response.IsRedirect)
+                    break;
+                await DoFollowIfRedirect(response, referrer, overrideRedirectUrl, overrideCookies, accumulateCookies);
+                if (accumulateCookies)
+                {
+                    CookieHeader = ResolveCookies((CookieHeader != null && CookieHeader != ""? CookieHeader + " " : "") + (overrideCookies != null && overrideCookies != "" ? overrideCookies + " " : "") + response.Cookies);
+                    overrideCookies = response.Cookies = CookieHeader;
+                }
+                if (overrideCookies != null && response.Cookies == null)
+                {
+                    response.Cookies = overrideCookies;
+                }
+            }
+        }
+
+        private String ResolveCookies(String incomingCookies = "")
+        {
+            var redirRequestCookies = (CookieHeader != null && CookieHeader != "" ? CookieHeader + " " : "") + incomingCookies;
+            System.Text.RegularExpressions.Regex expression = new System.Text.RegularExpressions.Regex(@"([^\\,;\s]+)=([^=\\,;\s]*)");
+            Dictionary<string, string> cookieDIctionary = new Dictionary<string, string>();
+            var matches = expression.Match(redirRequestCookies);
+            while (matches.Success)
+            {
+                if (matches.Groups.Count > 2) cookieDIctionary[matches.Groups[1].Value] = matches.Groups[2].Value;
+                matches = matches.NextMatch();
+            }
+            return string.Join("; ", cookieDIctionary.Select(kv => kv.Key.ToString() + "=" + kv.Value.ToString()).ToArray());
+            
+        }
+
+        // Update CookieHeader with new cookies and save the config if something changed (e.g. a new CloudFlare clearance cookie was issued)
+        protected void UpdateCookieHeader(string newCookies, string cookieOverride = null)
+        {
+            string newCookieHeader = ResolveCookies((cookieOverride != null && cookieOverride != "" ? cookieOverride + " " : "") + newCookies);
+            if (CookieHeader != newCookieHeader)
+            {
+                logger.Debug(string.Format("updating Cookies {0} => {1}", CookieHeader, newCookieHeader));
+                CookieHeader = newCookieHeader;
+                if (IsConfigured)
+                    SaveConfig();
+            }
+        }
+
+        private async Task DoFollowIfRedirect(WebClientByteResult incomingResponse, string referrer = null, string overrideRedirectUrl = null, string overrideCookies = null, bool accumulateCookies = false)
+        {
+            if (incomingResponse.IsRedirect)
+            {
+                var redirRequestCookies = "";
+                if (accumulateCookies)
+                {
+                    redirRequestCookies = ResolveCookies((CookieHeader != "" ? CookieHeader + " " : "") + (overrideCookies != null ? overrideCookies : ""));
+                } else
+                {
+                    redirRequestCookies = (overrideCookies != null ? overrideCookies : "");
+                }
+                // Do redirect
+                var redirectedResponse = await webclient.GetBytes(new WebRequest()
+                {
+                    Url = overrideRedirectUrl ?? incomingResponse.RedirectingTo,
+                    Referer = referrer,
+                    Cookies = redirRequestCookies,
+                    Encoding = Encoding
+                });
+                Mapper.Map(redirectedResponse, incomingResponse);
+            }
+        }
+
+
+        protected void LoadLegacyCookieConfig(JToken jsonConfig)
+        {
+            string legacyCookieHeader = (string)jsonConfig["cookie_header"];
+            if (!string.IsNullOrEmpty(legacyCookieHeader))
+            {
+                CookieHeader = legacyCookieHeader;
+            }
+            else
+            {
+                // Legacy cookie key
+                var jcookies = jsonConfig["cookies"];
+                if (jcookies is JArray)
+                {
+                    var array = (JArray)jcookies;
+                    legacyCookieHeader = string.Empty;
+                    for (int i = 0; i < array.Count; i++)
+                    {
+                        if (i != 0)
+                            legacyCookieHeader += "; ";
+                        legacyCookieHeader += array[i];
+                    }
+                    CookieHeader = legacyCookieHeader;
+                }
+                else if (jcookies != null)
+                {
+                    CookieHeader = (string)jcookies;
+                }
+            }
+        }
+
+        virtual public void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
+        {
+            IProtectionService ps = null;
+            if (useProtectionService)
+                ps = protectionService;
+            configData.LoadValuesFromJson(jsonConfig, ps);
+            if (string.IsNullOrWhiteSpace(configData.SiteLink.Value))
+            {
+                configData.SiteLink.Value = DefaultSiteLink;
+            }
+            if (!configData.SiteLink.Value.EndsWith("/"))
+                configData.SiteLink.Value += "/";
+
+            var match = Regex.Match(configData.SiteLink.Value, "^https?:\\/\\/[\\w\\-\\/\\.]+$");
+            if (!match.Success)
+            {
+                throw new Exception(string.Format("\"{0}\" is not a valid URL.", configData.SiteLink.Value));
+            }
+
+            SiteLink = configData.SiteLink.Value;
+        }
+
+        public virtual void LoadFromSavedConfiguration(JToken jsonConfig)
+        {
+            if (jsonConfig is JArray)
+            {
+                LoadValuesFromJson(jsonConfig, true);
+                IsConfigured = true;
+            }
+            // read and upgrade old settings file format
+            else if (jsonConfig is Object)
+            {
+                LoadLegacyCookieConfig(jsonConfig);
+                SaveConfig();
+                IsConfigured = true;
+            }
+        }
+
+        public async virtual Task<byte[]> Download(Uri link)
+        {
+            return await Download(link, RequestType.GET);
+        }
+
+        public async virtual Task<byte[]> Download(Uri link, RequestType method = RequestType.GET)
+        {
+            // do some extra escaping, needed for HD-Torrents
+            var requestLink = link.ToString()
+                .Replace("(", "%28")
+                .Replace(")", "%29")
+                .Replace("'", "%27");
+            var response = await RequestBytesWithCookiesAndRetry(requestLink, null, method, requestLink);
+            if (response.Status != System.Net.HttpStatusCode.OK && response.Status != System.Net.HttpStatusCode.Continue && response.Status != System.Net.HttpStatusCode.PartialContent)
+            {
+                logger.Error("Failed download cookies: " + this.CookieHeader);
+                if (response.Content != null)
+                    logger.Error("Failed download response:\n" + Encoding.UTF8.GetString(response.Content));
+                throw new Exception($"Remote server returned {response.Status.ToString()}" + (response.IsRedirect ? " => "+response.RedirectingTo : ""));
+            }
+
+            return response.Content;
+        }
+
+        protected async Task<WebClientByteResult> RequestBytesWithCookiesAndRetry(string url, string cookieOverride = null, RequestType method = RequestType.GET, string referer = null, IEnumerable<KeyValuePair<string, string>> data = null)
+        {
+            Exception lastException = null;
+            for (int i = 0; i < 3; i++)
+            {
+                try
+                {
+                    return await RequestBytesWithCookies(url, cookieOverride, method, referer, data);
+                }
+                catch (Exception e)
+                {
+                    logger.Error(e, string.Format("On attempt {0} downloading from {1}: {2}", (i + 1), DisplayName, e.Message));
+                    lastException = e;
+                }
+                await Task.Delay(500);
+            }
+
+            throw lastException;
+        }
+
+        protected async Task<WebClientStringResult> RequestStringWithCookies(string url, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null)
+        {
+            var request = new Utils.Clients.WebRequest()
+            {
+                Url = url,
+                Type = RequestType.GET,
+                Cookies = CookieHeader,
+                Referer = referer,
+                Headers = headers,
+                Encoding = Encoding
+            };
+
+            if (cookieOverride != null)
+                request.Cookies = cookieOverride;
+            WebClientStringResult result = await webclient.GetString(request);
+            UpdateCookieHeader(result.Cookies, cookieOverride);
+            return result;
+        }
+
+        protected async Task<WebClientStringResult> RequestStringWithCookiesAndRetry(string url, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null)
+        {
+            Exception lastException = null;
+            for (int i = 0; i < 3; i++)
+            {
+                try
+                {
+                    return await RequestStringWithCookies(url, cookieOverride, referer, headers);
+                }
+                catch (Exception e)
+                {
+                    logger.Error(string.Format("On attempt {0} checking for results from {1}: {2}", (i + 1), DisplayName, e.Message));
+                    lastException = e;
+                }
+                await Task.Delay(500);
+            }
+
+            throw lastException;
+        }
+
+        protected async Task<WebClientByteResult> RequestBytesWithCookies(string url, string cookieOverride = null, RequestType method = RequestType.GET, string referer = null, IEnumerable<KeyValuePair<string, string>> data = null, Dictionary<string, string> headers = null)
+        {
+            var request = new Utils.Clients.WebRequest()
+            {
+                Url = url,
+                Type = method,
+                Cookies = cookieOverride ?? CookieHeader,
+                PostData = data,
+                Referer = referer,
+                Headers = headers,
+                Encoding = Encoding
+            };
+
+            if (cookieOverride != null)
+                request.Cookies = cookieOverride;
+            return await webclient.GetBytes(request);
+        }
+
+        protected async Task<WebClientStringResult> PostDataWithCookies(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null, bool? emulateBrowser = null)
+        {
+            var request = new Utils.Clients.WebRequest()
+            {
+                Url = url,
+                Type = RequestType.POST,
+                Cookies = cookieOverride ?? CookieHeader,
+                PostData = data,
+                Referer = referer,
+                Headers = headers,
+                RawBody = rawbody,
+                Encoding = Encoding
+            };
+
+            if (emulateBrowser.HasValue)
+                request.EmulateBrowser = emulateBrowser.Value;
+            WebClientStringResult result = await webclient.GetString(request);
+            UpdateCookieHeader(result.Cookies, cookieOverride);
+            return result;
+        }
+
+        protected async Task<WebClientStringResult> PostDataWithCookiesAndRetry(string url, IEnumerable<KeyValuePair<string, string>> data, string cookieOverride = null, string referer = null, Dictionary<string, string> headers = null, string rawbody = null, bool? emulateBrowser = null)
+        {
+            Exception lastException = null;
+            for (int i = 0; i < 3; i++)
+            {
+                try
+                {
+                    return await PostDataWithCookies(url, data, cookieOverride, referer, headers, rawbody, emulateBrowser);
+                }
+                catch (Exception e)
+                {
+                    logger.Error(string.Format("On attempt {0} checking for results from {1}: {2}", (i + 1), DisplayName, e.Message));
+                    lastException = e;
+                }
+                await Task.Delay(500);
+            }
+
+            throw lastException;
+        }
+
+        protected async Task<WebClientStringResult> RequestLoginAndFollowRedirect(string url, IEnumerable<KeyValuePair<string, string>> data, string cookies, bool returnCookiesFromFirstCall, string redirectUrlOverride = null, string referer = null, bool accumulateCookies = false)
+        {
+            var request = new Utils.Clients.WebRequest()
+            {
+                Url = url,
+                Type = RequestType.POST,
+                Cookies = cookies,
+                Referer = referer,
+                PostData = data,
+                Encoding = Encoding
+            };
+            var response = await webclient.GetString(request);
+            if (accumulateCookies)
+            {
+                response.Cookies = ResolveCookies((request.Cookies == null ? "" : request.Cookies + " ") + response.Cookies);
+            }
+            var firstCallCookies = response.Cookies;
+
+            if (response.IsRedirect)
+            {
+                await FollowIfRedirect(response, request.Url, redirectUrlOverride, response.Cookies, accumulateCookies);
+            }
+
+            if (returnCookiesFromFirstCall)
+            {
+                response.Cookies = ResolveCookies(firstCallCookies + (accumulateCookies ? " " + response.Cookies : ""));
+            }
+            
+            return response;
+        }
+
+        protected async Task ConfigureIfOK(string cookies, bool isLoggedin, Func<Task> onError)
+        {
+            if (isLoggedin)
+            {
+                CookieHeader = cookies;
+                SaveConfig();
+                IsConfigured = true;
+            }
+            else
+            {
+                await onError();
+            }
+        }
+
+        public virtual IEnumerable<ReleaseInfo> FilterResults(TorznabQuery query, IEnumerable<ReleaseInfo> results)
+        {
+            foreach (var result in results)
+            {
+                if (query.Categories.Length == 0 || result.Category == null || result.Category.Count() == 0 || query.Categories.Intersect(result.Category).Any() || TorznabCatType.QueryContainsParentCategory(query.Categories, result.Category))
+                {
+                    yield return result;
+                }
+            }
+        }
+
+        protected List<string> GetAllTrackerCategories()
+        {
+            return categoryMapping.Select(x => x.TrackerCategory).ToList();
+        }
+
+        protected void AddCategoryMapping(string trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
+        {
+            categoryMapping.Add(new CategoryMapping(trackerCategory, trackerCategoryDesc, newznabCategory.ID));
+            if (!TorznabCaps.Categories.Contains(newznabCategory))
+            {
+                TorznabCaps.Categories.Add(newznabCategory);
+                if (TorznabCatType.Movies.Contains(newznabCategory))
+                    TorznabCaps.MovieSearchAvailable = true;
+            }
+
+            // add 1:1 categories
+            if (trackerCategoryDesc != null && trackerCategory != null)
+            {
+                try
+                {
+                    var trackerCategoryInt = int.Parse(trackerCategory);
+                    var CustomCat = new TorznabCategory(trackerCategoryInt + 100000, trackerCategoryDesc);
+                    if (!TorznabCaps.Categories.Contains(CustomCat))
+                        TorznabCaps.Categories.Add(CustomCat);
+                }
+                catch (FormatException)
+                {
+                    // trackerCategory is not an integer, continue
+                }
+            }
+        }
+
+        protected void AddCategoryMapping(int trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
+        {
+            AddCategoryMapping(trackerCategory.ToString(), newznabCategory, trackerCategoryDesc);
+        }
+
+        protected void AddMultiCategoryMapping(TorznabCategory newznabCategory, params int[] trackerCategories)
+        {
+            foreach (var trackerCat in trackerCategories)
+            {
+                AddCategoryMapping(trackerCat, newznabCategory);
+            }
+        }
+
+        protected virtual List<string> MapTorznabCapsToTrackers(TorznabQuery query, bool mapChildrenCatsToParent = false)
+        {
+            var result = new List<string>();
+            foreach (var cat in query.Categories)
+            {
+                // use 1:1 mapping to tracker categories for newznab categories >= 100000
+                if (cat >= 100000)
+                {
+                    result.Add((cat - 100000).ToString());
+                    continue;
+                }
+
+                var queryCats = new List<int> { cat };
+                var newznabCat = TorznabCatType.AllCats.FirstOrDefault(c => c.ID == cat);
+                if (newznabCat != null)
+                {
+                    queryCats.AddRange(newznabCat.SubCategories.Select(c => c.ID));
+                }
+
+                if (mapChildrenCatsToParent)
+                {
+                    var parentNewznabCat = TorznabCatType.AllCats.FirstOrDefault(c => c.SubCategories.Contains(newznabCat));
+                    if (parentNewznabCat != null)
+                    {
+                        queryCats.Add(parentNewznabCat.ID);
+                    }
+                }
+
+                foreach (var mapping in categoryMapping.Where(c => queryCats.Contains(c.NewzNabCategory)))
+                {
+                    result.Add(mapping.TrackerCategory);
+                }
+            }
+
+            return result.Distinct().ToList();
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/BestFriends.cs b/src/Jackett/Indexers/BestFriends.cs
index 0ce02cc50397783a7149013a7c8788a1aab3b1d2..d6e9868770197ae3809f2fb45f9c4f02e3283c4f 100644
--- a/src/Jackett/Indexers/BestFriends.cs
+++ b/src/Jackett/Indexers/BestFriends.cs
@@ -10,9 +10,9 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-
+using System.Collections.Specialized;
+using System.Text;
+
 namespace Jackett.Indexers
 {
     public class BestFriends : BaseIndexer, IIndexer
@@ -42,49 +42,49 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(18, TorznabCatType.TVAnime); // Anime
-            AddCategoryMapping(8,  TorznabCatType.PCMac); // Appz MAC
-            AddCategoryMapping(9,  TorznabCatType.PC); // Appz other
-            AddCategoryMapping(7,  TorznabCatType.PC); // Appz Windows
-            AddCategoryMapping(23, TorznabCatType.TVDocumentary); // Dokumentationen
-            AddCategoryMapping(32, TorznabCatType.Movies3D); // DVD 3D
-            AddCategoryMapping(15, TorznabCatType.Books); // eBooks
-            AddCategoryMapping(12, TorznabCatType.PCGames); // Games PC
-            AddCategoryMapping(37, TorznabCatType.PCPhoneOther); // Handy_Mobile 
-            AddCategoryMapping(24, TorznabCatType.TVHD); // HDTV
-            AddCategoryMapping(22, TorznabCatType.AudioAudiobook); // Hörbücher
-            AddCategoryMapping(1,  TorznabCatType.MoviesHD); // Movies 1080p/1080i
-            AddCategoryMapping(31, TorznabCatType.Movies3D); // Movies 3D
-            AddCategoryMapping(2,  TorznabCatType.MoviesHD); // Movies 720p/720i
-            AddCategoryMapping(21, TorznabCatType.MoviesBluRay); // Movies BluRay
-            AddCategoryMapping(5,  TorznabCatType.MoviesDVD); // Movies DVD/HDDVD
-            AddCategoryMapping(6,  TorznabCatType.MoviesSD); // Movies M/SVCD/Other
-            AddCategoryMapping(4,  TorznabCatType.MoviesSD); // Movies XVID/DIVX/h.264
-            AddCategoryMapping(10, TorznabCatType.Audio); // Music
-            AddCategoryMapping(25, TorznabCatType.AudioVideo); // Musikvideo
-            AddCategoryMapping(29, TorznabCatType.ConsoleNDS); // Nintendo DS
-            AddCategoryMapping(16, TorznabCatType.Other); // other
-            AddCategoryMapping(13, TorznabCatType.ConsolePS4); // Playstation
-            AddCategoryMapping(28, TorznabCatType.TVHD); // Serien HD
-            AddCategoryMapping(11, TorznabCatType.TVSD); // Serien XviD
-            AddCategoryMapping(33, TorznabCatType.Other); // Specials
-            AddCategoryMapping(30, TorznabCatType.TVSport); // Sport
-            AddCategoryMapping(19, TorznabCatType.TVOTHER); // TVRip
-            AddCategoryMapping(38, TorznabCatType.TVDocumentary); // US Dokus
-            AddCategoryMapping(20, TorznabCatType.MoviesForeign); // US Movies
-            AddCategoryMapping(14, TorznabCatType.TVFOREIGN); // US Serien
-            AddCategoryMapping(36, TorznabCatType.Other); // Wallpaper 
-            AddCategoryMapping(26, TorznabCatType.ConsoleWii); // Wii
-            AddCategoryMapping(27, TorznabCatType.ConsoleXbox360); // Xbox 360
+            AddCategoryMapping(18, TorznabCatType.TVAnime); // Anime
+            AddCategoryMapping(8,  TorznabCatType.PCMac); // Appz MAC
+            AddCategoryMapping(9,  TorznabCatType.PC); // Appz other
+            AddCategoryMapping(7,  TorznabCatType.PC); // Appz Windows
+            AddCategoryMapping(23, TorznabCatType.TVDocumentary); // Dokumentationen
+            AddCategoryMapping(32, TorznabCatType.Movies3D); // DVD 3D
+            AddCategoryMapping(15, TorznabCatType.Books); // eBooks
+            AddCategoryMapping(12, TorznabCatType.PCGames); // Games PC
+            AddCategoryMapping(37, TorznabCatType.PCPhoneOther); // Handy_Mobile 
+            AddCategoryMapping(24, TorznabCatType.TVHD); // HDTV
+            AddCategoryMapping(22, TorznabCatType.AudioAudiobook); // Hörbücher
+            AddCategoryMapping(1,  TorznabCatType.MoviesHD); // Movies 1080p/1080i
+            AddCategoryMapping(31, TorznabCatType.Movies3D); // Movies 3D
+            AddCategoryMapping(2,  TorznabCatType.MoviesHD); // Movies 720p/720i
+            AddCategoryMapping(21, TorznabCatType.MoviesBluRay); // Movies BluRay
+            AddCategoryMapping(5,  TorznabCatType.MoviesDVD); // Movies DVD/HDDVD
+            AddCategoryMapping(6,  TorznabCatType.MoviesSD); // Movies M/SVCD/Other
+            AddCategoryMapping(4,  TorznabCatType.MoviesSD); // Movies XVID/DIVX/h.264
+            AddCategoryMapping(10, TorznabCatType.Audio); // Music
+            AddCategoryMapping(25, TorznabCatType.AudioVideo); // Musikvideo
+            AddCategoryMapping(29, TorznabCatType.ConsoleNDS); // Nintendo DS
+            AddCategoryMapping(16, TorznabCatType.Other); // other
+            AddCategoryMapping(13, TorznabCatType.ConsolePS4); // Playstation
+            AddCategoryMapping(28, TorznabCatType.TVHD); // Serien HD
+            AddCategoryMapping(11, TorznabCatType.TVSD); // Serien XviD
+            AddCategoryMapping(33, TorznabCatType.Other); // Specials
+            AddCategoryMapping(30, TorznabCatType.TVSport); // Sport
+            AddCategoryMapping(19, TorznabCatType.TVOTHER); // TVRip
+            AddCategoryMapping(38, TorznabCatType.TVDocumentary); // US Dokus
+            AddCategoryMapping(20, TorznabCatType.MoviesForeign); // US Movies
+            AddCategoryMapping(14, TorznabCatType.TVFOREIGN); // US Serien
+            AddCategoryMapping(36, TorznabCatType.Other); // Wallpaper 
+            AddCategoryMapping(26, TorznabCatType.ConsoleWii); // Wii
+            AddCategoryMapping(27, TorznabCatType.ConsoleXbox360); // Xbox 360
             AddCategoryMapping(3,  TorznabCatType.XXX); // XXX
         }
 
         public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
-            CQ dom = loginPage.Content;
-            CQ qCaptchaImg = dom.Find("td.tablea > img").First();
-
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
+            CQ dom = loginPage.Content;
+            CQ qCaptchaImg = dom.Find("td.tablea > img").First();
+
             var CaptchaUrl = SiteLink + qCaptchaImg.Attr("src");
             var captchaImage = await RequestBytesWithCookies(CaptchaUrl, loginPage.Cookies);
             configData.CaptchaImage.Value = captchaImage.Content;
@@ -99,15 +99,15 @@ namespace Jackett.Indexers
             var pairs1 = new Dictionary<string, string>
             {
                 { "proofcode", configData.CaptchaText.Value }
-            };
-            var cookies = configData.CaptchaCookie.Value;
+            };
+            var cookies = configData.CaptchaCookie.Value;
             var result1 = await RequestLoginAndFollowRedirect(LoginUrl, pairs1, cookies, true, null, LoginUrl, true);
-            if(result1.Content == null || !result1.Content.Contains("takelogin.php"))
-            {
-                CQ dom = result1.Content;
-                var errorMessage = dom["#login_error"].Text().Trim();
-                errorMessage = result1.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            if(result1.Content == null || !result1.Content.Contains("takelogin.php"))
+            {
+                CQ dom = result1.Content;
+                var errorMessage = dom["#login_error"].Text().Trim();
+                errorMessage = result1.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             }
 
             var pairs2 = new Dictionary<string, string>
@@ -129,33 +129,33 @@ namespace Jackett.Indexers
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("showsearch", "1");
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("blah", "0");
-            queryCollection.Add("orderby", "added");
-            queryCollection.Add("sort", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("showsearch", "1");
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("blah", "0");
+            queryCollection.Add("orderby", "added");
+            queryCollection.Add("sort", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
@@ -168,55 +168,55 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 0.75;
+                    release.MinimumRatio = 0.75;
                     release.MinimumSeedTime = 0;
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    release.Title = qDetailsLink.Attr("title");
-
-                    if (!query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-
-                    // use negative indexes as if a user has "Wartezeit" there's an extra column after the title
-                    var qSeeders = qRow.Find("td:nth-last-child(4)");
-                    var qLeechers = qRow.Find("td:nth-last-child(3)");
-                    var qDateStr = qRow.Find("td:nth-last-child(7)");
-                    var qSize = qRow.Find("td:nth-last-child(6)");
-
-                    var torrentId = qDetailsLink.Attr("href").Replace("&hit=1", "").Split('=')[1];
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + "download.php?torrent="+torrentId);
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(",", "."));
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    release.Title = qDetailsLink.Attr("title");
+
+                    if (!query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+
+                    // use negative indexes as if a user has "Wartezeit" there's an extra column after the title
+                    var qSeeders = qRow.Find("td:nth-last-child(4)");
+                    var qLeechers = qRow.Find("td:nth-last-child(3)");
+                    var qDateStr = qRow.Find("td:nth-last-child(7)");
+                    var qSize = qRow.Find("td:nth-last-child(6)");
+
+                    var torrentId = qDetailsLink.Attr("href").Replace("&hit=1", "").Split('=')[1];
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + "download.php?torrent="+torrentId);
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(",", "."));
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text();
                     var dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyyHH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
-                    release.PublishDate = pubDateUtc;
-
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    release.PublishDate = pubDateUtc;
+
                     var files = qRow.Find("td:nth-last-child(9)").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
                     var grabs = qRow.Find("td:nth-last-child(5)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("font[color=\"red\"]:contains(OnlyUp)").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("font[color=\"red\"]:contains(OnlyUp)").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/BeyondHD.cs b/src/Jackett/Indexers/BeyondHD.cs
index e5f593855df1ccfa3ab6e40cd008f0596317e136..3c92bec0fb130706f8681071e885a96abf9cc0f5 100644
--- a/src/Jackett/Indexers/BeyondHD.cs
+++ b/src/Jackett/Indexers/BeyondHD.cs
@@ -107,8 +107,8 @@ namespace Jackett.Indexers
             var queryCollection = new NameValueCollection();
 
             if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
+            {
+                Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
                 searchString = "%" + ReplaceRegex.Replace(searchString, "%") + "%";
                 searchString = Regex.Replace(searchString, @"(%\d{3,4})[ip](%)", "$1$2"); // remove i/p from resolution tags (see #835)
                 queryCollection.Add("search", searchString);
@@ -164,7 +164,7 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(9) > a").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    release.DownloadVolumeFactor = 0; // ratioless
+                    release.DownloadVolumeFactor = 0; // ratioless
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/BitCityReloaded.cs b/src/Jackett/Indexers/BitCityReloaded.cs
index f2ed81fe29a167a4ee82c99ef577e0be5c631dca..96072a861c752e208601f082be9879761617caa9 100644
--- a/src/Jackett/Indexers/BitCityReloaded.cs
+++ b/src/Jackett/Indexers/BitCityReloaded.cs
@@ -12,8 +12,8 @@ using System;
 using System.Text;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
+using System.Collections.Specialized;
+
 namespace Jackett.Indexers
 {
     public class BitCityReloaded : BaseIndexer, IIndexer
@@ -43,43 +43,43 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show a reasonable amount (it looks like there's no maximum).";
+            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show a reasonable amount (it looks like there's no maximum).";
             this.configData.DisplayText.Name = "Notice";
 
-            AddCategoryMapping(1,  TorznabCatType.Other); // Anderes
-            AddCategoryMapping(2,  TorznabCatType.TVAnime); // Anime
-            AddCategoryMapping(34, TorznabCatType.PC); // Appz/Linux
-            AddCategoryMapping(35, TorznabCatType.PCMac); // Appz/Mac
-            AddCategoryMapping(36, TorznabCatType.PC); // Appz/Other
-            AddCategoryMapping(20, TorznabCatType.PC); // Appz/Win
-            AddCategoryMapping(3,  TorznabCatType.TVDocumentary); // Doku/Alle Formate
-            AddCategoryMapping(4,  TorznabCatType.Books); // EBooks
-            AddCategoryMapping(12, TorznabCatType.ConsolePS4); // Games PS / PSX
-            AddCategoryMapping(11, TorznabCatType.ConsoleNDS); // Games/Nintendo DS
-            AddCategoryMapping(10, TorznabCatType.PCGames); // Games/PC
-            AddCategoryMapping(13, TorznabCatType.ConsoleWii); // Games/Wii
-            AddCategoryMapping(14, TorznabCatType.ConsoleXbox); // Games/Xbox & 360
-            AddCategoryMapping(15, TorznabCatType.PCPhoneOther); // Handy & PDA
-            AddCategoryMapping(16, TorznabCatType.AudioAudiobook); // Hörspiel/Hörbuch
-            AddCategoryMapping(30, TorznabCatType.Other); // International
-            AddCategoryMapping(17, TorznabCatType.Other); // MegaPack
-            AddCategoryMapping(43, TorznabCatType.Movies3D); // Movie/3D
-            AddCategoryMapping(5,  TorznabCatType.MoviesDVD); // Movie/DVD/R
-            AddCategoryMapping(6,  TorznabCatType.MoviesHD); // Movie/HD 1080p
-            AddCategoryMapping(7,  TorznabCatType.MoviesHD); // Movie/HD 720p
-            AddCategoryMapping(32, TorznabCatType.MoviesOther); // Movie/TVRip
-            AddCategoryMapping(9,  TorznabCatType.MoviesOther); // Movie/XviD,DivX,h264
-            AddCategoryMapping(26, TorznabCatType.XXX); // Movie/XXX
-            AddCategoryMapping(41, TorznabCatType.XXXOther); // Movie/XXX/Other
-            AddCategoryMapping(42, TorznabCatType.XXXPacks); // Movie/XXX/Pack
-            AddCategoryMapping(45, TorznabCatType.MoviesHD); // Movies/4K
-            AddCategoryMapping(33, TorznabCatType.MoviesBluRay); // Movies/BluRay
-            AddCategoryMapping(18, TorznabCatType.Audio); // Musik
-            AddCategoryMapping(19, TorznabCatType.AudioVideo); // Musik Videos
-            AddCategoryMapping(44, TorznabCatType.TVOTHER); // Serie/DVD/R
-            AddCategoryMapping(22, TorznabCatType.TVHD); // Serie/HDTV
-            AddCategoryMapping(38, TorznabCatType.TV); // Serie/Pack
-            AddCategoryMapping(23, TorznabCatType.TVOTHER); // Serie/XviD,DivX,h264
+            AddCategoryMapping(1,  TorznabCatType.Other); // Anderes
+            AddCategoryMapping(2,  TorznabCatType.TVAnime); // Anime
+            AddCategoryMapping(34, TorznabCatType.PC); // Appz/Linux
+            AddCategoryMapping(35, TorznabCatType.PCMac); // Appz/Mac
+            AddCategoryMapping(36, TorznabCatType.PC); // Appz/Other
+            AddCategoryMapping(20, TorznabCatType.PC); // Appz/Win
+            AddCategoryMapping(3,  TorznabCatType.TVDocumentary); // Doku/Alle Formate
+            AddCategoryMapping(4,  TorznabCatType.Books); // EBooks
+            AddCategoryMapping(12, TorznabCatType.ConsolePS4); // Games PS / PSX
+            AddCategoryMapping(11, TorznabCatType.ConsoleNDS); // Games/Nintendo DS
+            AddCategoryMapping(10, TorznabCatType.PCGames); // Games/PC
+            AddCategoryMapping(13, TorznabCatType.ConsoleWii); // Games/Wii
+            AddCategoryMapping(14, TorznabCatType.ConsoleXbox); // Games/Xbox & 360
+            AddCategoryMapping(15, TorznabCatType.PCPhoneOther); // Handy & PDA
+            AddCategoryMapping(16, TorznabCatType.AudioAudiobook); // Hörspiel/Hörbuch
+            AddCategoryMapping(30, TorznabCatType.Other); // International
+            AddCategoryMapping(17, TorznabCatType.Other); // MegaPack
+            AddCategoryMapping(43, TorznabCatType.Movies3D); // Movie/3D
+            AddCategoryMapping(5,  TorznabCatType.MoviesDVD); // Movie/DVD/R
+            AddCategoryMapping(6,  TorznabCatType.MoviesHD); // Movie/HD 1080p
+            AddCategoryMapping(7,  TorznabCatType.MoviesHD); // Movie/HD 720p
+            AddCategoryMapping(32, TorznabCatType.MoviesOther); // Movie/TVRip
+            AddCategoryMapping(9,  TorznabCatType.MoviesOther); // Movie/XviD,DivX,h264
+            AddCategoryMapping(26, TorznabCatType.XXX); // Movie/XXX
+            AddCategoryMapping(41, TorznabCatType.XXXOther); // Movie/XXX/Other
+            AddCategoryMapping(42, TorznabCatType.XXXPacks); // Movie/XXX/Pack
+            AddCategoryMapping(45, TorznabCatType.MoviesHD); // Movies/4K
+            AddCategoryMapping(33, TorznabCatType.MoviesBluRay); // Movies/BluRay
+            AddCategoryMapping(18, TorznabCatType.Audio); // Musik
+            AddCategoryMapping(19, TorznabCatType.AudioVideo); // Musik Videos
+            AddCategoryMapping(44, TorznabCatType.TVOTHER); // Serie/DVD/R
+            AddCategoryMapping(22, TorznabCatType.TVHD); // Serie/HDTV
+            AddCategoryMapping(38, TorznabCatType.TV); // Serie/Pack
+            AddCategoryMapping(23, TorznabCatType.TVOTHER); // Serie/XviD,DivX,h264
             AddCategoryMapping(25, TorznabCatType.TVSport); // Sport
         }
 
@@ -107,25 +107,25 @@ namespace Jackett.Indexers
         {
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("showsearch", "0");
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("blah", "0");
-            queryCollection.Add("team", "0");
-            queryCollection.Add("orderby", "added");
-            queryCollection.Add("sort", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("showsearch", "0");
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("blah", "0");
+            queryCollection.Add("team", "0");
+            queryCollection.Add("orderby", "added");
+            queryCollection.Add("sort", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
@@ -138,7 +138,7 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 0.7;
+                    release.MinimumRatio = 0.7;
                     release.MinimumSeedTime = 48 * 60 * 60;
                     release.DownloadVolumeFactor = 1;
                     release.UploadVolumeFactor = 1;
@@ -146,21 +146,21 @@ namespace Jackett.Indexers
                     var qRow = row.Cq();
                     var flagImgs = qRow.Find("table tbody tr: eq(0) td > img");
                     List<string> flags = new List<string>();
-                    flagImgs.Each(flagImg => {
-                        var flag = flagImg.GetAttribute("src").Replace("pic/torrent_", "").Replace(".gif", "").ToUpper();
-                        if (flag == "OU")
-                            release.DownloadVolumeFactor = 0;
-                        else
-                            flags.Add(flag);
-                    });
-                        
+                    flagImgs.Each(flagImg => {
+                        var flag = flagImg.GetAttribute("src").Replace("pic/torrent_", "").Replace(".gif", "").ToUpper();
+                        if (flag == "OU")
+                            release.DownloadVolumeFactor = 0;
+                        else
+                            flags.Add(flag);
+                    });
+                        
                     var titleLink = qRow.Find("table tbody tr:eq(0) td a:has(b)").First();
-                    var DLLink = qRow.Find("td.tableb > a:has(img[title=\"Torrent herunterladen\"])").First();
-                    release.Comments = new Uri(SiteLink + titleLink.Attr("href").Replace("&hit=1", ""));
+                    var DLLink = qRow.Find("td.tableb > a:has(img[title=\"Torrent herunterladen\"])").First();
+                    release.Comments = new Uri(SiteLink + titleLink.Attr("href").Replace("&hit=1", ""));
                     release.Link = new Uri(SiteLink + DLLink.Attr("href"));
                     release.Title = titleLink.Text().Trim();
 
-                    if (!query.MatchQueryStringAND(release.Title))
+                    if (!query.MatchQueryStringAND(release.Title))
                         continue;
 
                     release.Description = String.Join(", ", flags);
@@ -168,7 +168,7 @@ namespace Jackett.Indexers
 
                     var dateStr = qRow.Find("table tbody tr:eq(1) td:eq(4)").Html().Replace("&nbsp;", " ").Trim();
                     var dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc.ToLocalTime();
 
                     var sizeStr = qRow.Find("table tbody tr:eq(1) td b").First().Text().Trim();
diff --git a/src/Jackett/Indexers/BitMeTV.cs b/src/Jackett/Indexers/BitMeTV.cs
index 3f01cad7da7b825e16430dd7a45155328d0b38bb..c707b77868b7ea82050f25c63952525290905fb9 100644
--- a/src/Jackett/Indexers/BitMeTV.cs
+++ b/src/Jackett/Indexers/BitMeTV.cs
@@ -138,7 +138,7 @@ namespace Jackett.Indexers
                     var grabs = row.Cq().Find("td:nth-child(8)").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    release.DownloadVolumeFactor = 1;
+                    release.DownloadVolumeFactor = 1;
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/BitSoup.cs b/src/Jackett/Indexers/BitSoup.cs
index 544be37500bf2c663422c59aa1ee80c6da171ac1..89448976ed973c69f3e3c5b892d5a45a6e5f693d 100644
--- a/src/Jackett/Indexers/BitSoup.cs
+++ b/src/Jackett/Indexers/BitSoup.cs
@@ -1,232 +1,232 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public class BitSoup : BaseIndexer, IIndexer
-    {
-        private string BrowseUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        private string LoginReferer { get { return SiteLink + "login.php"; } }
-        public new string[] AlternativeSiteLinks { get; protected set; } = new string[] { "https://www.bitsoup.me/", "https://www.bitsoup.org/" };
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public BitSoup(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "BitSoup",
-                description: "SoupieBits",
-                link: "https://www.bitsoup.me/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "en-us";
-            Type = "private";
-
-            //AddCategoryMapping("624", TorznabCatType.Console);
-            //AddCategoryMapping("307", TorznabCatType.ConsoleNDS);
-            //AddCategoryMapping("308", TorznabCatType.ConsolePSP);
-            AddCategoryMapping("35", TorznabCatType.ConsoleWii);
-            //AddCategoryMapping("309", TorznabCatType.ConsoleXbox);
-            AddCategoryMapping("12", TorznabCatType.ConsoleXbox360);
-            //AddCategoryMapping("305", TorznabCatType.ConsoleWiiwareVC);
-            //AddCategoryMapping("309", TorznabCatType.ConsoleXBOX360DLC);
-            AddCategoryMapping("38", TorznabCatType.ConsolePS3);
-            //AddCategoryMapping("239", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("245", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("246", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("626", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("628", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("630", TorznabCatType.ConsoleOther);
-            //AddCategoryMapping("307", TorznabCatType.Console3DS);
-            //AddCategoryMapping("308", TorznabCatType.ConsolePSVita);
-            //AddCategoryMapping("307", TorznabCatType.ConsoleWiiU);
-            //AddCategoryMapping("309", TorznabCatType.ConsoleXboxOne);
-            //AddCategoryMapping("308", TorznabCatType.ConsolePS4);
-            //AddCategoryMapping("631", TorznabCatType.Movies);
-            //AddCategoryMapping("631", TorznabCatType.MoviesForeign);
-            //AddCategoryMapping("455", TorznabCatType.MoviesOther);
-            //AddCategoryMapping("633", TorznabCatType.MoviesOther);
-            AddCategoryMapping("19", TorznabCatType.MoviesSD);
-            AddCategoryMapping("41", TorznabCatType.MoviesHD);
-            AddCategoryMapping("17", TorznabCatType.Movies3D);
-            AddCategoryMapping("80", TorznabCatType.MoviesBluRay);
-            AddCategoryMapping("20", TorznabCatType.MoviesDVD);
-            //AddCategoryMapping("631", TorznabCatType.MoviesWEBDL);
-            AddCategoryMapping("6", TorznabCatType.Audio);
-            //AddCategoryMapping("623", TorznabCatType.AudioMP3);
-            AddCategoryMapping("29", TorznabCatType.AudioVideo);
-            //AddCategoryMapping("402", TorznabCatType.AudioVideo);
-            AddCategoryMapping("5", TorznabCatType.AudioAudiobook);
-            //AddCategoryMapping("1", TorznabCatType.AudioLossless);
-            //AddCategoryMapping("403", TorznabCatType.AudioOther);
-            //AddCategoryMapping("642", TorznabCatType.AudioOther);
-            //AddCategoryMapping("1", TorznabCatType.AudioForeign);
-            //AddCategoryMapping("233", TorznabCatType.PC);
-            //AddCategoryMapping("236", TorznabCatType.PC);
-            //AddCategoryMapping("1", TorznabCatType.PC0day);
-            AddCategoryMapping("1", TorznabCatType.PCISO);
-            //AddCategoryMapping("235", TorznabCatType.PCMac);
-            //AddCategoryMapping("627", TorznabCatType.PCPhoneOther);
-            AddCategoryMapping("21", TorznabCatType.PCGames);
-            AddCategoryMapping("4", TorznabCatType.PCGames);
-            //AddCategoryMapping("625", TorznabCatType.PCPhoneIOS);
-            //AddCategoryMapping("625", TorznabCatType.PCPhoneAndroid);
-            AddCategoryMapping("45", TorznabCatType.TV);
-            //AddCategoryMapping("433", TorznabCatType.TV);
-            //AddCategoryMapping("639", TorznabCatType.TVWEBDL);
-            //AddCategoryMapping("433", TorznabCatType.TVWEBDL);
-            //AddCategoryMapping("639", TorznabCatType.TVFOREIGN);
-            //AddCategoryMapping("433", TorznabCatType.TVFOREIGN);
-            AddCategoryMapping("7", TorznabCatType.TVSD);
-            AddCategoryMapping("49", TorznabCatType.TVSD);
-            AddCategoryMapping("42", TorznabCatType.TVHD);
-            //AddCategoryMapping("433", TorznabCatType.TVHD);
-            //AddCategoryMapping("635", TorznabCatType.TVOTHER);
-            //AddCategoryMapping("636", TorznabCatType.TVSport);
-            AddCategoryMapping("23", TorznabCatType.TVAnime);
-            //AddCategoryMapping("634", TorznabCatType.TVDocumentary);
-            AddCategoryMapping("9", TorznabCatType.XXX);
-            //AddCategoryMapping("1", TorznabCatType.XXXDVD);
-            //AddCategoryMapping("1", TorznabCatType.XXXWMV);
-            //AddCategoryMapping("1", TorznabCatType.XXXXviD);
-            //AddCategoryMapping("1", TorznabCatType.XXXx264);
-            //AddCategoryMapping("1", TorznabCatType.XXXOther);
-            //AddCategoryMapping("1", TorznabCatType.XXXImageset);
-            //AddCategoryMapping("1", TorznabCatType.XXXPacks);
-            //AddCategoryMapping("340", TorznabCatType.Other);
-            //AddCategoryMapping("342", TorznabCatType.Other);
-            //AddCategoryMapping("344", TorznabCatType.Other);
-            //AddCategoryMapping("391", TorznabCatType.Other);
-            //AddCategoryMapping("392", TorznabCatType.Other);
-            //AddCategoryMapping("393", TorznabCatType.Other);
-            //AddCategoryMapping("394", TorznabCatType.Other);
-            //AddCategoryMapping("234", TorznabCatType.Other);
-            //AddCategoryMapping("638", TorznabCatType.Other);
-            //AddCategoryMapping("629", TorznabCatType.Other);
-            //AddCategoryMapping("1", TorznabCatType.OtherMisc);
-            //AddCategoryMapping("1", TorznabCatType.OtherHashed);
-            //AddCategoryMapping("408", TorznabCatType.Books);
-            AddCategoryMapping("24", TorznabCatType.BooksEbook);
-            //AddCategoryMapping("406", TorznabCatType.BooksComics);
-            //AddCategoryMapping("407", TorznabCatType.BooksComics);
-            //AddCategoryMapping("409", TorznabCatType.BooksComics);
-            //AddCategoryMapping("410", TorznabCatType.BooksMagazines);
-            //AddCategoryMapping("1", TorznabCatType.BooksTechnical);
-            //AddCategoryMapping("1", TorznabCatType.BooksOther);
-            //AddCategoryMapping("1", TorznabCatType.BooksForeign);
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-
-            };
-
-            var loginPage = await RequestStringWithCookies(SiteLink, string.Empty);
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginReferer, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var messageEl = dom["body > table.statusbar1 > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td"].First();
-                var errorMessage = messageEl.Text().Trim();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var trackerCats = MapTorznabCapsToTrackers(query);
-            var queryCollection = new NameValueCollection();
-
-
-            queryCollection.Add("search", string.IsNullOrWhiteSpace(searchString) ? "" : searchString);
-            if (trackerCats.Count > 1)
-            {
-                for (var ct = 0; ct < trackerCats.Count; ct++) queryCollection.Add("cat" + (ct + 1), trackerCats.ElementAt(ct));
-            }
-            else
-            {
-                queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
-            }
-            //queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
-            searchUrl += "?" + queryCollection.GetQueryString();
-            await ProcessPage(releases, searchUrl);
-
-            return releases;
-        }
-
-        private async Task ProcessPage(List<ReleaseInfo> releases, string searchUrl)
-        {
-            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
-            var results = response.Content;
-            try
-            {
-                CQ dom = results;
-
-                var rows = dom["table.koptekst tr"];
-                foreach (var row in rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-
-                    release.Title = row.Cq().Find("td:eq(1) a").First().Text().Trim();
-                    release.Comments = new Uri(SiteLink + row.Cq().Find("td:eq(1) a").First().Attr("href"));
-
-                    release.Link = new Uri(SiteLink + row.Cq().Find("td:eq(2) a").First().Attr("href"));
-                    release.Guid = release.Link;
-                    release.Description = release.Title;
-                    var cat = row.Cq().Find("td:eq(0) a").First().Attr("href").Substring(15);
-                    release.Category = MapTrackerCatToNewznab(cat);
-
-                    var added = row.Cq().Find("td:eq(7)").First().Text().Trim();
-                    release.PublishDate = DateTime.ParseExact(added, "yyyy-MM-ddH:mm:ss", CultureInfo.InvariantCulture);
-
-                    var sizeStr = row.Cq().Find("td:eq(8)").First().Text().Trim();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(row.Cq().Find("td:eq(10)").First().Text().Trim());
-                    release.Peers = ParseUtil.CoerceInt(row.Cq().Find("td:eq(11)").First().Text().Trim()) + release.Seeders;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results, ex);
-            }
-        }
-    }
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public class BitSoup : BaseIndexer, IIndexer
+    {
+        private string BrowseUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+        private string LoginReferer { get { return SiteLink + "login.php"; } }
+        public new string[] AlternativeSiteLinks { get; protected set; } = new string[] { "https://www.bitsoup.me/", "https://www.bitsoup.org/" };
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public BitSoup(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "BitSoup",
+                description: "SoupieBits",
+                link: "https://www.bitsoup.me/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "en-us";
+            Type = "private";
+
+            //AddCategoryMapping("624", TorznabCatType.Console);
+            //AddCategoryMapping("307", TorznabCatType.ConsoleNDS);
+            //AddCategoryMapping("308", TorznabCatType.ConsolePSP);
+            AddCategoryMapping("35", TorznabCatType.ConsoleWii);
+            //AddCategoryMapping("309", TorznabCatType.ConsoleXbox);
+            AddCategoryMapping("12", TorznabCatType.ConsoleXbox360);
+            //AddCategoryMapping("305", TorznabCatType.ConsoleWiiwareVC);
+            //AddCategoryMapping("309", TorznabCatType.ConsoleXBOX360DLC);
+            AddCategoryMapping("38", TorznabCatType.ConsolePS3);
+            //AddCategoryMapping("239", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("245", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("246", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("626", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("628", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("630", TorznabCatType.ConsoleOther);
+            //AddCategoryMapping("307", TorznabCatType.Console3DS);
+            //AddCategoryMapping("308", TorznabCatType.ConsolePSVita);
+            //AddCategoryMapping("307", TorznabCatType.ConsoleWiiU);
+            //AddCategoryMapping("309", TorznabCatType.ConsoleXboxOne);
+            //AddCategoryMapping("308", TorznabCatType.ConsolePS4);
+            //AddCategoryMapping("631", TorznabCatType.Movies);
+            //AddCategoryMapping("631", TorznabCatType.MoviesForeign);
+            //AddCategoryMapping("455", TorznabCatType.MoviesOther);
+            //AddCategoryMapping("633", TorznabCatType.MoviesOther);
+            AddCategoryMapping("19", TorznabCatType.MoviesSD);
+            AddCategoryMapping("41", TorznabCatType.MoviesHD);
+            AddCategoryMapping("17", TorznabCatType.Movies3D);
+            AddCategoryMapping("80", TorznabCatType.MoviesBluRay);
+            AddCategoryMapping("20", TorznabCatType.MoviesDVD);
+            //AddCategoryMapping("631", TorznabCatType.MoviesWEBDL);
+            AddCategoryMapping("6", TorznabCatType.Audio);
+            //AddCategoryMapping("623", TorznabCatType.AudioMP3);
+            AddCategoryMapping("29", TorznabCatType.AudioVideo);
+            //AddCategoryMapping("402", TorznabCatType.AudioVideo);
+            AddCategoryMapping("5", TorznabCatType.AudioAudiobook);
+            //AddCategoryMapping("1", TorznabCatType.AudioLossless);
+            //AddCategoryMapping("403", TorznabCatType.AudioOther);
+            //AddCategoryMapping("642", TorznabCatType.AudioOther);
+            //AddCategoryMapping("1", TorznabCatType.AudioForeign);
+            //AddCategoryMapping("233", TorznabCatType.PC);
+            //AddCategoryMapping("236", TorznabCatType.PC);
+            //AddCategoryMapping("1", TorznabCatType.PC0day);
+            AddCategoryMapping("1", TorznabCatType.PCISO);
+            //AddCategoryMapping("235", TorznabCatType.PCMac);
+            //AddCategoryMapping("627", TorznabCatType.PCPhoneOther);
+            AddCategoryMapping("21", TorznabCatType.PCGames);
+            AddCategoryMapping("4", TorznabCatType.PCGames);
+            //AddCategoryMapping("625", TorznabCatType.PCPhoneIOS);
+            //AddCategoryMapping("625", TorznabCatType.PCPhoneAndroid);
+            AddCategoryMapping("45", TorznabCatType.TV);
+            //AddCategoryMapping("433", TorznabCatType.TV);
+            //AddCategoryMapping("639", TorznabCatType.TVWEBDL);
+            //AddCategoryMapping("433", TorznabCatType.TVWEBDL);
+            //AddCategoryMapping("639", TorznabCatType.TVFOREIGN);
+            //AddCategoryMapping("433", TorznabCatType.TVFOREIGN);
+            AddCategoryMapping("7", TorznabCatType.TVSD);
+            AddCategoryMapping("49", TorznabCatType.TVSD);
+            AddCategoryMapping("42", TorznabCatType.TVHD);
+            //AddCategoryMapping("433", TorznabCatType.TVHD);
+            //AddCategoryMapping("635", TorznabCatType.TVOTHER);
+            //AddCategoryMapping("636", TorznabCatType.TVSport);
+            AddCategoryMapping("23", TorznabCatType.TVAnime);
+            //AddCategoryMapping("634", TorznabCatType.TVDocumentary);
+            AddCategoryMapping("9", TorznabCatType.XXX);
+            //AddCategoryMapping("1", TorznabCatType.XXXDVD);
+            //AddCategoryMapping("1", TorznabCatType.XXXWMV);
+            //AddCategoryMapping("1", TorznabCatType.XXXXviD);
+            //AddCategoryMapping("1", TorznabCatType.XXXx264);
+            //AddCategoryMapping("1", TorznabCatType.XXXOther);
+            //AddCategoryMapping("1", TorznabCatType.XXXImageset);
+            //AddCategoryMapping("1", TorznabCatType.XXXPacks);
+            //AddCategoryMapping("340", TorznabCatType.Other);
+            //AddCategoryMapping("342", TorznabCatType.Other);
+            //AddCategoryMapping("344", TorznabCatType.Other);
+            //AddCategoryMapping("391", TorznabCatType.Other);
+            //AddCategoryMapping("392", TorznabCatType.Other);
+            //AddCategoryMapping("393", TorznabCatType.Other);
+            //AddCategoryMapping("394", TorznabCatType.Other);
+            //AddCategoryMapping("234", TorznabCatType.Other);
+            //AddCategoryMapping("638", TorznabCatType.Other);
+            //AddCategoryMapping("629", TorznabCatType.Other);
+            //AddCategoryMapping("1", TorznabCatType.OtherMisc);
+            //AddCategoryMapping("1", TorznabCatType.OtherHashed);
+            //AddCategoryMapping("408", TorznabCatType.Books);
+            AddCategoryMapping("24", TorznabCatType.BooksEbook);
+            //AddCategoryMapping("406", TorznabCatType.BooksComics);
+            //AddCategoryMapping("407", TorznabCatType.BooksComics);
+            //AddCategoryMapping("409", TorznabCatType.BooksComics);
+            //AddCategoryMapping("410", TorznabCatType.BooksMagazines);
+            //AddCategoryMapping("1", TorznabCatType.BooksTechnical);
+            //AddCategoryMapping("1", TorznabCatType.BooksOther);
+            //AddCategoryMapping("1", TorznabCatType.BooksForeign);
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+
+            };
+
+            var loginPage = await RequestStringWithCookies(SiteLink, string.Empty);
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, null, LoginReferer, true);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var messageEl = dom["body > table.statusbar1 > tbody > tr > td > table > tbody > tr > td > table > tbody > tr > td"].First();
+                var errorMessage = messageEl.Text().Trim();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var trackerCats = MapTorznabCapsToTrackers(query);
+            var queryCollection = new NameValueCollection();
+
+
+            queryCollection.Add("search", string.IsNullOrWhiteSpace(searchString) ? "" : searchString);
+            if (trackerCats.Count > 1)
+            {
+                for (var ct = 0; ct < trackerCats.Count; ct++) queryCollection.Add("cat" + (ct + 1), trackerCats.ElementAt(ct));
+            }
+            else
+            {
+                queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
+            }
+            //queryCollection.Add("cat", (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0"));
+            searchUrl += "?" + queryCollection.GetQueryString();
+            await ProcessPage(releases, searchUrl);
+
+            return releases;
+        }
+
+        private async Task ProcessPage(List<ReleaseInfo> releases, string searchUrl)
+        {
+            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
+            var results = response.Content;
+            try
+            {
+                CQ dom = results;
+
+                var rows = dom["table.koptekst tr"];
+                foreach (var row in rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+
+                    release.Title = row.Cq().Find("td:eq(1) a").First().Text().Trim();
+                    release.Comments = new Uri(SiteLink + row.Cq().Find("td:eq(1) a").First().Attr("href"));
+
+                    release.Link = new Uri(SiteLink + row.Cq().Find("td:eq(2) a").First().Attr("href"));
+                    release.Guid = release.Link;
+                    release.Description = release.Title;
+                    var cat = row.Cq().Find("td:eq(0) a").First().Attr("href").Substring(15);
+                    release.Category = MapTrackerCatToNewznab(cat);
+
+                    var added = row.Cq().Find("td:eq(7)").First().Text().Trim();
+                    release.PublishDate = DateTime.ParseExact(added, "yyyy-MM-ddH:mm:ss", CultureInfo.InvariantCulture);
+
+                    var sizeStr = row.Cq().Find("td:eq(8)").First().Text().Trim();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(row.Cq().Find("td:eq(10)").First().Text().Trim());
+                    release.Peers = ParseUtil.CoerceInt(row.Cq().Find("td:eq(11)").First().Text().Trim()) + release.Seeders;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results, ex);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/BroadcastTheNet.cs b/src/Jackett/Indexers/BroadcastTheNet.cs
index 51b63b13492f384b62a0ed4972b0e2bad6351490..7387d052fcbf1c656a44cbfcbfd7403162181d8d 100644
--- a/src/Jackett/Indexers/BroadcastTheNet.cs
+++ b/src/Jackett/Indexers/BroadcastTheNet.cs
@@ -1,177 +1,177 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-using System.Dynamic;
-using Newtonsoft.Json;
-
-namespace Jackett.Indexers
-{
-    public class BroadcastTheNet : BaseIndexer, IIndexer
-    {
-        string APIBASE = "https://api.broadcasthe.net";
-
-        new ConfigurationDataAPIKey configData
-        {
-            get { return (ConfigurationDataAPIKey)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public BroadcastTheNet(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "BroadcastTheNet",
-                description: "Needs no description..",
-                link: "https://broadcasthe.net/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataAPIKey())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "en-us";
-            Type = "private";
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            IsConfigured = false;
-            try
-            {
-                var results = await PerformQuery(new TorznabQuery());
-                if (results.Count() == 0)
-                    throw new Exception("Testing returned no results!");
-                IsConfigured = true;
-                SaveConfig();
-            }
-            catch(Exception e)
-            {
-                throw new ExceptionWithConfigData(e.Message, configData);
-            }
-
-            return IndexerConfigurationStatus.Completed;
-        }
-
-
-        private string JsonRPCRequest(string method, JArray parameters)
-        {
-            dynamic request = new JObject();
-            request["jsonrpc"] = "2.0";
-            request["method"] = method;
-            request["params"] = parameters;
-            request["id"] = Guid.NewGuid().ToString().Substring(0, 8);
-            return request.ToString();
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var searchString = query.GetQueryString();
-            var releases = new List<ReleaseInfo>();
-
-            var parameters = new JArray();
-            parameters.Add(new JValue(configData.Key.Value));
-            parameters.Add(new JValue(searchString.Trim()));
-            parameters.Add(new JValue(100));
-            parameters.Add(new JValue(0));
-            var response = await PostDataWithCookiesAndRetry(APIBASE, null, null, null, new Dictionary<string, string>()
-            {
-                { "Accept", "application/json-rpc, application/json"},
-                {"Content-Type", "application/json-rpc"}
-            }, JsonRPCRequest("getTorrents", parameters),false);
-
-            try
-            {
-                var btnResponse = JsonConvert.DeserializeObject<BTNRPCResponse>(response.Content);
-
-                if (btnResponse != null && btnResponse.Result != null)
-                {
-                    foreach (var itemKey in btnResponse.Result.Torrents)
-                    {
-                        var btnResult = itemKey.Value;
-                        var item = new ReleaseInfo();
-                        if (!string.IsNullOrEmpty(btnResult.SeriesBanner))
-                            item.BannerUrl = new Uri(btnResult.SeriesBanner);
-                        item.Category = new List<int> { TorznabCatType.TV.ID };
-                        item.Comments = new Uri($"https://broadcasthe.net/torrents.php?id={btnResult.GroupID}&torrentid={btnResult.TorrentID}");
-                        item.Description = btnResult.ReleaseName;
-                        item.Guid = new Uri(btnResult.DownloadURL);
-                        if (!string.IsNullOrWhiteSpace(btnResult.ImdbID))
-                            item.Imdb = ParseUtil.CoerceLong(btnResult.ImdbID);
-                        item.Link = new Uri(btnResult.DownloadURL);
-                        item.MinimumRatio = 1;
-                        item.PublishDate = DateTimeUtil.UnixTimestampToDateTime(btnResult.Time);
-                        item.RageID = btnResult.TvrageID;
-                        item.Seeders = btnResult.Seeders;
-                        item.Peers = btnResult.Seeders + btnResult.Leechers;
-                        item.Size = btnResult.Size;
-                        item.TVDBId = btnResult.TvdbID;
-                        item.Title = btnResult.ReleaseName;
-                        releases.Add(item);
-                    }
-                }
-
-            }
-            catch (Exception ex)
-            {
-                OnParseError(response.Content, ex);
-            }
-            return releases;
-        }
-
-
-        public class BTNRPCResponse
-        {
-            public string Id { get; set; }
-            public BTNResultPage Result { get; set; }
-        }
-
-        public class BTNResultPage
-        {
-            public Dictionary<int, BTNResultItem> Torrents { get; set; }
-        }
-
-        public class BTNResultItem
-        {
-            public int TorrentID { get; set; }
-            public string DownloadURL { get; set; }
-            public string GroupName { get; set; }
-            public int GroupID { get; set; }
-            public int SeriesID { get; set; }
-            public string Series { get; set; }
-            public string SeriesBanner { get; set; }
-            public string SeriesPoster { get; set; }
-            public string YoutubeTrailer { get; set; }
-            public string Category { get; set; }
-            public int? Snatched { get; set; }
-            public int? Seeders { get; set; }
-            public int? Leechers { get; set; }
-            public string Source { get; set; }
-            public string Container { get; set; }
-            public string Codec { get; set; }
-            public string Resolution { get; set; }
-            public string Origin { get; set; }
-            public string ReleaseName { get; set; }
-            public long Size { get; set; }
-            public long Time { get; set; }
-            public int? TvdbID { get; set; }
-            public int? TvrageID { get; set; }
-            public string ImdbID { get; set; }
-            public string InfoHash { get; set; }
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+using System.Dynamic;
+using Newtonsoft.Json;
+
+namespace Jackett.Indexers
+{
+    public class BroadcastTheNet : BaseIndexer, IIndexer
+    {
+        string APIBASE = "https://api.broadcasthe.net";
+
+        new ConfigurationDataAPIKey configData
+        {
+            get { return (ConfigurationDataAPIKey)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public BroadcastTheNet(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "BroadcastTheNet",
+                description: "Needs no description..",
+                link: "https://broadcasthe.net/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataAPIKey())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "en-us";
+            Type = "private";
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            IsConfigured = false;
+            try
+            {
+                var results = await PerformQuery(new TorznabQuery());
+                if (results.Count() == 0)
+                    throw new Exception("Testing returned no results!");
+                IsConfigured = true;
+                SaveConfig();
+            }
+            catch(Exception e)
+            {
+                throw new ExceptionWithConfigData(e.Message, configData);
+            }
+
+            return IndexerConfigurationStatus.Completed;
+        }
+
+
+        private string JsonRPCRequest(string method, JArray parameters)
+        {
+            dynamic request = new JObject();
+            request["jsonrpc"] = "2.0";
+            request["method"] = method;
+            request["params"] = parameters;
+            request["id"] = Guid.NewGuid().ToString().Substring(0, 8);
+            return request.ToString();
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var searchString = query.GetQueryString();
+            var releases = new List<ReleaseInfo>();
+
+            var parameters = new JArray();
+            parameters.Add(new JValue(configData.Key.Value));
+            parameters.Add(new JValue(searchString.Trim()));
+            parameters.Add(new JValue(100));
+            parameters.Add(new JValue(0));
+            var response = await PostDataWithCookiesAndRetry(APIBASE, null, null, null, new Dictionary<string, string>()
+            {
+                { "Accept", "application/json-rpc, application/json"},
+                {"Content-Type", "application/json-rpc"}
+            }, JsonRPCRequest("getTorrents", parameters),false);
+
+            try
+            {
+                var btnResponse = JsonConvert.DeserializeObject<BTNRPCResponse>(response.Content);
+
+                if (btnResponse != null && btnResponse.Result != null)
+                {
+                    foreach (var itemKey in btnResponse.Result.Torrents)
+                    {
+                        var btnResult = itemKey.Value;
+                        var item = new ReleaseInfo();
+                        if (!string.IsNullOrEmpty(btnResult.SeriesBanner))
+                            item.BannerUrl = new Uri(btnResult.SeriesBanner);
+                        item.Category = new List<int> { TorznabCatType.TV.ID };
+                        item.Comments = new Uri($"https://broadcasthe.net/torrents.php?id={btnResult.GroupID}&torrentid={btnResult.TorrentID}");
+                        item.Description = btnResult.ReleaseName;
+                        item.Guid = new Uri(btnResult.DownloadURL);
+                        if (!string.IsNullOrWhiteSpace(btnResult.ImdbID))
+                            item.Imdb = ParseUtil.CoerceLong(btnResult.ImdbID);
+                        item.Link = new Uri(btnResult.DownloadURL);
+                        item.MinimumRatio = 1;
+                        item.PublishDate = DateTimeUtil.UnixTimestampToDateTime(btnResult.Time);
+                        item.RageID = btnResult.TvrageID;
+                        item.Seeders = btnResult.Seeders;
+                        item.Peers = btnResult.Seeders + btnResult.Leechers;
+                        item.Size = btnResult.Size;
+                        item.TVDBId = btnResult.TvdbID;
+                        item.Title = btnResult.ReleaseName;
+                        releases.Add(item);
+                    }
+                }
+
+            }
+            catch (Exception ex)
+            {
+                OnParseError(response.Content, ex);
+            }
+            return releases;
+        }
+
+
+        public class BTNRPCResponse
+        {
+            public string Id { get; set; }
+            public BTNResultPage Result { get; set; }
+        }
+
+        public class BTNResultPage
+        {
+            public Dictionary<int, BTNResultItem> Torrents { get; set; }
+        }
+
+        public class BTNResultItem
+        {
+            public int TorrentID { get; set; }
+            public string DownloadURL { get; set; }
+            public string GroupName { get; set; }
+            public int GroupID { get; set; }
+            public int SeriesID { get; set; }
+            public string Series { get; set; }
+            public string SeriesBanner { get; set; }
+            public string SeriesPoster { get; set; }
+            public string YoutubeTrailer { get; set; }
+            public string Category { get; set; }
+            public int? Snatched { get; set; }
+            public int? Seeders { get; set; }
+            public int? Leechers { get; set; }
+            public string Source { get; set; }
+            public string Container { get; set; }
+            public string Codec { get; set; }
+            public string Resolution { get; set; }
+            public string Origin { get; set; }
+            public string ReleaseName { get; set; }
+            public long Size { get; set; }
+            public long Time { get; set; }
+            public int? TvdbID { get; set; }
+            public int? TvrageID { get; set; }
+            public string ImdbID { get; set; }
+            public string InfoHash { get; set; }
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/CardigannIndexer.cs b/src/Jackett/Indexers/CardigannIndexer.cs
index 8b341e99217fa81e8ceb9ba3624bca3311bc9b5d..33ad85414d407e189e549ead5ca46740e8a9b383 100644
--- a/src/Jackett/Indexers/CardigannIndexer.cs
+++ b/src/Jackett/Indexers/CardigannIndexer.cs
@@ -8,232 +8,232 @@ using Newtonsoft.Json.Linq;
 using System.Collections.Generic;
 using System;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-using YamlDotNet.Serialization;
-using YamlDotNet.Serialization.NamingConventions;
-using static Jackett.Models.IndexerConfig.ConfigurationData;
-using AngleSharp.Parser.Html;
-using System.Text.RegularExpressions;
-using System.Web;
-using AngleSharp.Dom;
-using AngleSharp.Dom.Html;
-using System.Linq;
-
+using System.Collections.Specialized;
+using System.Text;
+using YamlDotNet.Serialization;
+using YamlDotNet.Serialization.NamingConventions;
+using static Jackett.Models.IndexerConfig.ConfigurationData;
+using AngleSharp.Parser.Html;
+using System.Text.RegularExpressions;
+using System.Web;
+using AngleSharp.Dom;
+using AngleSharp.Dom.Html;
+using System.Linq;
+
 namespace Jackett.Indexers
 {
     public class CardigannIndexer : BaseIndexer, IIndexer
     {
-        public string DefinitionString { get; protected set; }
-        protected IndexerDefinition Definition;
-        public new string ID { get { return (Definition != null ? Definition.Site : GetIndexerID(GetType())); } }
-
+        public string DefinitionString { get; protected set; }
+        protected IndexerDefinition Definition;
+        public new string ID { get { return (Definition != null ? Definition.Site : GetIndexerID(GetType())); } }
+
         protected WebClientStringResult landingResult;
-        protected IHtmlDocument landingResultDocument;
-
+        protected IHtmlDocument landingResultDocument;
+
         new ConfigurationData configData
         {
             get { return (ConfigurationData)base.configData; }
             set { base.configData = value; }
-        }
-
-        // A Dictionary allowing the same key multiple times
-        public class KeyValuePairList : List<KeyValuePair<string, selectorBlock>>, IDictionary<string, selectorBlock>
-        {
-            public selectorBlock this[string key]
-            {
-                get
-                {
-                    throw new NotImplementedException();
-                }
-
-                set
-                {
-                    base.Add(new KeyValuePair<string, selectorBlock>(key, value));
-                }
-            }
-
-            public ICollection<string> Keys
-            {
-                get
-                {
-                    throw new NotImplementedException();
-                }
-            }
-
-            public ICollection<selectorBlock> Values
-            {
-                get
-                {
-                    throw new NotImplementedException();
-                }
-            }
-
-            public void Add(string key, selectorBlock value)
-            {
-                base.Add(new KeyValuePair<string, selectorBlock>(key, value));
-            }
-
-            public bool ContainsKey(string key)
-            {
-                throw new NotImplementedException();
-            }
-
-            public bool Remove(string key)
-            {
-                throw new NotImplementedException();
-            }
-
-            public bool TryGetValue(string key, out selectorBlock value)
-            {
-                throw new NotImplementedException();
-            }
-        }
-
+        }
+
+        // A Dictionary allowing the same key multiple times
+        public class KeyValuePairList : List<KeyValuePair<string, selectorBlock>>, IDictionary<string, selectorBlock>
+        {
+            public selectorBlock this[string key]
+            {
+                get
+                {
+                    throw new NotImplementedException();
+                }
+
+                set
+                {
+                    base.Add(new KeyValuePair<string, selectorBlock>(key, value));
+                }
+            }
+
+            public ICollection<string> Keys
+            {
+                get
+                {
+                    throw new NotImplementedException();
+                }
+            }
+
+            public ICollection<selectorBlock> Values
+            {
+                get
+                {
+                    throw new NotImplementedException();
+                }
+            }
+
+            public void Add(string key, selectorBlock value)
+            {
+                base.Add(new KeyValuePair<string, selectorBlock>(key, value));
+            }
+
+            public bool ContainsKey(string key)
+            {
+                throw new NotImplementedException();
+            }
+
+            public bool Remove(string key)
+            {
+                throw new NotImplementedException();
+            }
+
+            public bool TryGetValue(string key, out selectorBlock value)
+            {
+                throw new NotImplementedException();
+            }
+        }
+
         // Cardigann yaml classes
         public class IndexerDefinition {
-            public string Site { get; set; }
-            public List<settingsField> Settings { get; set; }
-            public string Name { get; set; }
-            public string Description { get; set; }
-            public string Type { get; set; }
-            public string Language { get; set; }
-            public string Encoding { get; set; }
-            public List<string> Links { get; set; }
-            public List<string> Certificates { get; set; }
-            public capabilitiesBlock Caps { get; set; }
-            public loginBlock Login { get; set; }
-            public ratioBlock Ratio { get; set; }
-            public searchBlock Search { get; set; }
-            public downloadBlock Download { get; set; }
-            // IndexerDefinitionStats not needed/implemented
-        }
-        public class settingsField
-        {
-            public string Name { get; set; }
-            public string Type { get; set; }
-            public string Label { get; set; }
+            public string Site { get; set; }
+            public List<settingsField> Settings { get; set; }
+            public string Name { get; set; }
+            public string Description { get; set; }
+            public string Type { get; set; }
+            public string Language { get; set; }
+            public string Encoding { get; set; }
+            public List<string> Links { get; set; }
+            public List<string> Certificates { get; set; }
+            public capabilitiesBlock Caps { get; set; }
+            public loginBlock Login { get; set; }
+            public ratioBlock Ratio { get; set; }
+            public searchBlock Search { get; set; }
+            public downloadBlock Download { get; set; }
+            // IndexerDefinitionStats not needed/implemented
+        }
+        public class settingsField
+        {
+            public string Name { get; set; }
+            public string Type { get; set; }
+            public string Label { get; set; }
+        }
+
+        public class CategorymappingBlock
+        {
+            public string id { get; set; }
+            public string cat { get; set; }
+            public string desc { get; set; }
+        }
+
+        public class capabilitiesBlock
+        {
+            public Dictionary<string, string> Categories  { get; set; }
+            public List<CategorymappingBlock> Categorymappings { get; set; }
+            public Dictionary<string, List<string>> Modes { get; set; }
+        }
+
+        public class captchaBlock
+        {
+            public string Type { get; set; }
+            public string Image { get; set; }
+            public string Input { get; set; }
+        }
+
+        public class loginBlock
+        {
+            public string Path { get; set; }
+            public string Submitpath { get; set; }
+            public List<string> Cookies { get; set; }
+            public string Method { get; set; }
+            public string Form { get; set; }
+            public bool Selectors { get; set; } = false;
+            public Dictionary<string, string> Inputs { get; set; }
+            public Dictionary<string, selectorBlock> Selectorinputs { get; set; }
+            public Dictionary<string, selectorBlock> Getselectorinputs { get; set; }
+            public List<errorBlock> Error { get; set; }
+            public pageTestBlock Test { get; set; }
+            public captchaBlock Captcha { get; set; }
+        }
+
+        public class errorBlock
+        {
+            public string Path { get; set; }
+            public string Selector { get; set; }
+            public selectorBlock Message { get; set; }
         }
 
-        public class CategorymappingBlock
-        {
-            public string id { get; set; }
-            public string cat { get; set; }
-            public string desc { get; set; }
+        public class selectorBlock
+        {
+            public string Selector { get; set; }
+            public bool Optional { get; set; } = false;
+            public string Text { get; set; }
+            public string Attribute { get; set; }
+            public string Remove { get; set; }
+            public List<filterBlock> Filters { get; set; }
+            public Dictionary<string, string> Case { get; set; }
         }
 
-        public class capabilitiesBlock
-        {
-            public Dictionary<string, string> Categories  { get; set; }
-            public List<CategorymappingBlock> Categorymappings { get; set; }
-            public Dictionary<string, List<string>> Modes { get; set; }
-        }
-
-        public class captchaBlock
-        {
-            public string Type { get; set; }
-            public string Image { get; set; }
-            public string Input { get; set; }
-        }
-
-        public class loginBlock
-        {
-            public string Path { get; set; }
-            public string Submitpath { get; set; }
-            public List<string> Cookies { get; set; }
-            public string Method { get; set; }
-            public string Form { get; set; }
-            public bool Selectors { get; set; } = false;
-            public Dictionary<string, string> Inputs { get; set; }
-            public Dictionary<string, selectorBlock> Selectorinputs { get; set; }
-            public Dictionary<string, selectorBlock> Getselectorinputs { get; set; }
-            public List<errorBlock> Error { get; set; }
-            public pageTestBlock Test { get; set; }
-            public captchaBlock Captcha { get; set; }
-        }
-
-        public class errorBlock
-        {
-            public string Path { get; set; }
-            public string Selector { get; set; }
-            public selectorBlock Message { get; set; }
-        }
-
-        public class selectorBlock
-        {
-            public string Selector { get; set; }
-            public bool Optional { get; set; } = false;
-            public string Text { get; set; }
-            public string Attribute { get; set; }
-            public string Remove { get; set; }
-            public List<filterBlock> Filters { get; set; }
-            public Dictionary<string, string> Case { get; set; }
-        }
-
-        public class filterBlock
-        {
-            public string Name { get; set; }
-            public dynamic Args { get; set; }
-        }
-
-        public class pageTestBlock
-        {
-            public string Path { get; set; }
-            public string Selector { get; set; }
-        }
-
-        public class ratioBlock : selectorBlock
-        {
-            public string Path { get; set; }
-        }
-
-        public class searchBlock
-        {
-            public string Path { get; set; }
-            public List<searchPathBlock> Paths { get; set; }
-            public List<filterBlock> Keywordsfilters { get; set; }
-            public Dictionary<string, string> Inputs { get; set; }
-            public List<errorBlock> Error { get; set; }
-            public rowsBlock Rows { get; set; }
-            public KeyValuePairList Fields { get; set; }
-        }
-
-        public class rowsBlock : selectorBlock
-        {
-            public int After { get; set; }
-            //public string Remove { get; set; } // already inherited
-            public selectorBlock Dateheaders { get; set; }
-        }
-
-        public class searchPathBlock : requestBlock
-        {
-            public List<string> Categories { get; set; }
-            public bool Inheritinputs { get; set; } = true;
-        }
-
-        public class requestBlock
-        {
-            public string Path { get; set; }
-            public string Method { get; set; }
-            public Dictionary<string, string> Inputs { get; set; }
-        }
-
-        public class downloadBlock
-        {
-            public string Selector { get; set; }
-            public string Method { get; set; }
-            public requestBlock Before { get; set; }
-        }
-
-        protected readonly string[] OptionalFileds = new string[] { "imdb", "rageid", "tvdbid", "banner" };
-
+        public class filterBlock
+        {
+            public string Name { get; set; }
+            public dynamic Args { get; set; }
+        }
+
+        public class pageTestBlock
+        {
+            public string Path { get; set; }
+            public string Selector { get; set; }
+        }
+
+        public class ratioBlock : selectorBlock
+        {
+            public string Path { get; set; }
+        }
+
+        public class searchBlock
+        {
+            public string Path { get; set; }
+            public List<searchPathBlock> Paths { get; set; }
+            public List<filterBlock> Keywordsfilters { get; set; }
+            public Dictionary<string, string> Inputs { get; set; }
+            public List<errorBlock> Error { get; set; }
+            public rowsBlock Rows { get; set; }
+            public KeyValuePairList Fields { get; set; }
+        }
+
+        public class rowsBlock : selectorBlock
+        {
+            public int After { get; set; }
+            //public string Remove { get; set; } // already inherited
+            public selectorBlock Dateheaders { get; set; }
+        }
+
+        public class searchPathBlock : requestBlock
+        {
+            public List<string> Categories { get; set; }
+            public bool Inheritinputs { get; set; } = true;
+        }
+
+        public class requestBlock
+        {
+            public string Path { get; set; }
+            public string Method { get; set; }
+            public Dictionary<string, string> Inputs { get; set; }
+        }
+
+        public class downloadBlock
+        {
+            public string Selector { get; set; }
+            public string Method { get; set; }
+            public requestBlock Before { get; set; }
+        }
+
+        protected readonly string[] OptionalFileds = new string[] { "imdb", "rageid", "tvdbid", "banner" };
+
         public CardigannIndexer(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
             : base(manager: i,
                    client: wc,
                    logger: l,
                    p: ps)
         {
-        }
+        }
 
         public CardigannIndexer(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps, string DefinitionString)
             : base(manager: i,
@@ -244,665 +244,665 @@ namespace Jackett.Indexers
             Init(DefinitionString);
         }
 
-        protected void Init(string DefinitionString)
-        {
-            this.DefinitionString = DefinitionString;
-            var deserializer = new DeserializerBuilder()
-                .WithNamingConvention(new CamelCaseNamingConvention())
-                .IgnoreUnmatchedProperties()
-                .Build();
+        protected void Init(string DefinitionString)
+        {
+            this.DefinitionString = DefinitionString;
+            var deserializer = new DeserializerBuilder()
+                .WithNamingConvention(new CamelCaseNamingConvention())
+                .IgnoreUnmatchedProperties()
+                .Build();
             Definition = deserializer.Deserialize<IndexerDefinition>(DefinitionString);
 
             // Add default data if necessary
-            if (Definition.Settings == null)
+            if (Definition.Settings == null)
             { 
                 Definition.Settings = new List<settingsField>();
-                Definition.Settings.Add(new settingsField { Name = "username", Label = "Username", Type = "text" });
-                Definition.Settings.Add(new settingsField { Name = "password", Label = "Password", Type = "password" });
+                Definition.Settings.Add(new settingsField { Name = "username", Label = "Username", Type = "text" });
+                Definition.Settings.Add(new settingsField { Name = "password", Label = "Password", Type = "password" });
             }
 
-            if (Definition.Encoding == null)
+            if (Definition.Encoding == null)
                 Definition.Encoding = "UTF-8";
 
             if (Definition.Login != null && Definition.Login.Method == null)
-                Definition.Login.Method = "form";
-
-            if (Definition.Search.Paths == null)
-            {
-                Definition.Search.Paths = new List<searchPathBlock>();
-            }
-
-            // convert definitions with a single search Path to a Paths entry
-            if (Definition.Search.Path != null)
-            {
-                var legacySearchPath = new searchPathBlock();
-                legacySearchPath.Path = Definition.Search.Path;
-                legacySearchPath.Inheritinputs = true;
-                Definition.Search.Paths.Add(legacySearchPath);
-            }
-
-            // init missing mandatory attributes
-            DisplayName = Definition.Name;
-            DisplayDescription = Definition.Description;
-            if (Definition.Links.Count > 1)
-                AlternativeSiteLinks = Definition.Links.ToArray();
-            DefaultSiteLink = Definition.Links[0];
-            Encoding = Encoding.GetEncoding(Definition.Encoding);
-            if (!DefaultSiteLink.EndsWith("/"))
-                DefaultSiteLink += "/";
-            Language = Definition.Language;
-            Type = Definition.Type;
-            TorznabCaps = new TorznabCapabilities();
-
-            TorznabCaps.SupportsImdbSearch = Definition.Caps.Modes.Where(c => c.Key == "movie-search" && c.Value.Contains("imdbid")).Any();
-
-            // init config Data
+                Definition.Login.Method = "form";
+
+            if (Definition.Search.Paths == null)
+            {
+                Definition.Search.Paths = new List<searchPathBlock>();
+            }
+
+            // convert definitions with a single search Path to a Paths entry
+            if (Definition.Search.Path != null)
+            {
+                var legacySearchPath = new searchPathBlock();
+                legacySearchPath.Path = Definition.Search.Path;
+                legacySearchPath.Inheritinputs = true;
+                Definition.Search.Paths.Add(legacySearchPath);
+            }
+
+            // init missing mandatory attributes
+            DisplayName = Definition.Name;
+            DisplayDescription = Definition.Description;
+            if (Definition.Links.Count > 1)
+                AlternativeSiteLinks = Definition.Links.ToArray();
+            DefaultSiteLink = Definition.Links[0];
+            Encoding = Encoding.GetEncoding(Definition.Encoding);
+            if (!DefaultSiteLink.EndsWith("/"))
+                DefaultSiteLink += "/";
+            Language = Definition.Language;
+            Type = Definition.Type;
+            TorznabCaps = new TorznabCapabilities();
+
+            TorznabCaps.SupportsImdbSearch = Definition.Caps.Modes.Where(c => c.Key == "movie-search" && c.Value.Contains("imdbid")).Any();
+
+            // init config Data
             configData = new ConfigurationData();
-            foreach (var Setting in Definition.Settings)
-            {
-                Item item;
-                if (Setting.Type != null && Setting.Type == "checkbox")
-                {
-                    item = new BoolItem() { Value = false };
-                }
-                else if(Setting.Type != null && Setting.Type == "password")
-                {
-                    item = new StringItem();
-                }
-                else
-                {
-                    item = new StringItem(); 
-                }
-                item.Name = Setting.Label;
-                configData.AddDynamic(Setting.Name, item);
+            foreach (var Setting in Definition.Settings)
+            {
+                Item item;
+                if (Setting.Type != null && Setting.Type == "checkbox")
+                {
+                    item = new BoolItem() { Value = false };
+                }
+                else if(Setting.Type != null && Setting.Type == "password")
+                {
+                    item = new StringItem();
+                }
+                else
+                {
+                    item = new StringItem(); 
+                }
+                item.Name = Setting.Label;
+                configData.AddDynamic(Setting.Name, item);
             }
 
-            if (Definition.Caps.Categories != null)
+            if (Definition.Caps.Categories != null)
             { 
-                foreach (var Category in Definition.Caps.Categories)
-                {
-                    var cat = TorznabCatType.GetCatByName(Category.Value);
-                    if (cat == null)
-                    {
-                        logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", ID, Category.Key, Category.Value));
-                        continue;
-                    }
-                    AddCategoryMapping(Category.Key, cat);
-                }
-            }
-
-            if (Definition.Caps.Categorymappings != null)
-            {
-                foreach (var Categorymapping in Definition.Caps.Categorymappings)
-                {
-                    TorznabCategory TorznabCat = null;
-
-                    if (Categorymapping.cat != null)
-                    {
-                        TorznabCat = TorznabCatType.GetCatByName(Categorymapping.cat);
-                        if (TorznabCat == null)
-                        {
-                            logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", ID, Categorymapping.id, Categorymapping.cat));
-                            continue;
-                        }
-                    }
-                    AddCategoryMapping(Categorymapping.id, TorznabCat, Categorymapping.desc);
-                }
-            }
-            LoadValuesFromJson(null);
+                foreach (var Category in Definition.Caps.Categories)
+                {
+                    var cat = TorznabCatType.GetCatByName(Category.Value);
+                    if (cat == null)
+                    {
+                        logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", ID, Category.Key, Category.Value));
+                        continue;
+                    }
+                    AddCategoryMapping(Category.Key, cat);
+                }
+            }
+
+            if (Definition.Caps.Categorymappings != null)
+            {
+                foreach (var Categorymapping in Definition.Caps.Categorymappings)
+                {
+                    TorznabCategory TorznabCat = null;
+
+                    if (Categorymapping.cat != null)
+                    {
+                        TorznabCat = TorznabCatType.GetCatByName(Categorymapping.cat);
+                        if (TorznabCat == null)
+                        {
+                            logger.Error(string.Format("CardigannIndexer ({0}): invalid Torznab category for id {1}: {2}", ID, Categorymapping.id, Categorymapping.cat));
+                            continue;
+                        }
+                    }
+                    AddCategoryMapping(Categorymapping.id, TorznabCat, Categorymapping.desc);
+                }
+            }
+            LoadValuesFromJson(null);
         }
 
-        public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
-        {
-            base.LoadValuesFromJson(jsonConfig, useProtectionService);
-
-            // add self signed cert to trusted certs
-            if (Definition.Certificates != null)
-            {
-                foreach (var certificateHash in Definition.Certificates)
-                    webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
-            }
+        public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
+        {
+            base.LoadValuesFromJson(jsonConfig, useProtectionService);
+
+            // add self signed cert to trusted certs
+            if (Definition.Certificates != null)
+            {
+                foreach (var certificateHash in Definition.Certificates)
+                    webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
+            }
+        }
+
+        protected Dictionary<string, object> getTemplateVariablesFromConfigData()
+        {
+            Dictionary<string, object> variables = new Dictionary<string, object>();
+
+            foreach (settingsField Setting in Definition.Settings)
+            {
+                string value;
+                var item = configData.GetDynamic(Setting.Name);
+                if (item.GetType() == typeof(BoolItem))
+                {
+                    value = (((BoolItem)item).Value == true ? "true" : "");
+                }
+                else
+                { 
+                    value = ((StringItem)item).Value;
+                }
+                variables[".Config."+Setting.Name] = value;
+            }
+            return variables;
         }
 
-        protected Dictionary<string, object> getTemplateVariablesFromConfigData()
-        {
-            Dictionary<string, object> variables = new Dictionary<string, object>();
-
-            foreach (settingsField Setting in Definition.Settings)
-            {
-                string value;
-                var item = configData.GetDynamic(Setting.Name);
-                if (item.GetType() == typeof(BoolItem))
-                {
-                    value = (((BoolItem)item).Value == true ? "true" : "");
-                }
-                else
-                { 
-                    value = ((StringItem)item).Value;
-                }
-                variables[".Config."+Setting.Name] = value;
-            }
-            return variables;
-        }
-
-        // A very bad implementation of the golang template/text templating engine.
+        // A very bad implementation of the golang template/text templating engine.
         // But it should work for most basic constucts used by Cardigann definitions.
         protected delegate string TemplateTextModifier(string str);
-        protected string applyGoTemplateText(string template, Dictionary<string, object> variables = null, TemplateTextModifier modifier = null)
-        {
-            if (variables == null)
-            {
-                variables = getTemplateVariablesFromConfigData();
-            }
-
-            // handle re_replace expression
-            // Example: {{ re_replace .Query.Keywords "[^a-zA-Z0-9]+" "%" }}
-            Regex ReReplaceRegex = new Regex(@"{{\s*re_replace\s+(\..+?)\s+""(.+)""\s+""(.+?)""\s*}}");
-            var ReReplaceRegexMatches = ReReplaceRegex.Match(template);
-
-            while (ReReplaceRegexMatches.Success)
-            {
-                string all = ReReplaceRegexMatches.Groups[0].Value;
-                string variable = ReReplaceRegexMatches.Groups[1].Value;
-                string regexp = ReReplaceRegexMatches.Groups[2].Value;
-                string newvalue = ReReplaceRegexMatches.Groups[3].Value;
-
-                Regex ReplaceRegex = new Regex(regexp);
-                var input = (string)variables[variable];
-                var expanded = ReplaceRegex.Replace(input, newvalue);
-
-                if (modifier != null)
-                    expanded = modifier(expanded);
-
-                template = template.Replace(all, expanded);
-                ReReplaceRegexMatches = ReReplaceRegexMatches.NextMatch();
-            }
-
-            // handle if ... else ... expression
-            Regex IfElseRegex = new Regex(@"{{\s*if\s*(.+?)\s*}}(.*?){{\s*else\s*}}(.*?){{\s*end\s*}}");
-            var IfElseRegexMatches = IfElseRegex.Match(template);
-
-            while (IfElseRegexMatches.Success)
-            {
-                string conditionResult = null;
-
-                string all = IfElseRegexMatches.Groups[0].Value;
-                string condition = IfElseRegexMatches.Groups[1].Value;
-                string onTrue = IfElseRegexMatches.Groups[2].Value;
-                string onFalse = IfElseRegexMatches.Groups[3].Value;
-
-                if (condition.StartsWith("."))
-                {
-                    string value = (string)variables[condition];
-                    if (!string.IsNullOrWhiteSpace(value))
-                    {
-                        conditionResult = onTrue;
-                    }
-                    else
-                    {
-                        conditionResult = onFalse;
-                    }
-                }
-                else
-                {
-                    throw new NotImplementedException("CardigannIndexer: Condition operation '" + condition + "' not implemented");
-                }
-                template = template.Replace(all, conditionResult);
-                IfElseRegexMatches = IfElseRegexMatches.NextMatch();
-            }
-
-            // handle range expression
-            Regex RangeRegex = new Regex(@"{{\s*range\s*(.+?)\s*}}(.*?){{\.}}(.*?){{end}}");
-            var RangeRegexMatches = RangeRegex.Match(template);
-
-            while (RangeRegexMatches.Success)
-            {
-                string expanded = string.Empty;
-
-                string all = RangeRegexMatches.Groups[0].Value;
-                string variable = RangeRegexMatches.Groups[1].Value;
-                string prefix = RangeRegexMatches.Groups[2].Value;
-                string postfix = RangeRegexMatches.Groups[3].Value;
-
-                foreach (string value in (List<string>)variables[variable])
-                {
-                    var newvalue = value;
-                    if (modifier != null)
-                        newvalue = modifier(newvalue);
-                    expanded += prefix + newvalue + postfix;
-                }
-                template = template.Replace(all, expanded);
-                RangeRegexMatches = RangeRegexMatches.NextMatch();
-            }
-
-            // handle simple variables
-            Regex VariablesRegEx = new Regex(@"{{\s*(\..+?)\s*}}");
-            var VariablesRegExMatches = VariablesRegEx.Match(template);
-
-            while (VariablesRegExMatches.Success)
-            {
-                string expanded = string.Empty;
-
-                string all = VariablesRegExMatches.Groups[0].Value;
-                string variable = VariablesRegExMatches.Groups[1].Value;
-
-                string value = (string)variables[variable];
-                if (modifier != null)
-                    value = modifier(value);
-                template = template.Replace(all, value);
-                VariablesRegExMatches = VariablesRegExMatches.NextMatch();
-            }
-
-            return template;
-        }
-
-        protected bool checkForError(WebClientStringResult loginResult, IList<errorBlock> errorBlocks)
-        {
-            if (errorBlocks == null)
-                return true; // no error
-
-            var ResultParser = new HtmlParser();
-            var ResultDocument = ResultParser.Parse(loginResult.Content);
-            foreach (errorBlock error in errorBlocks)
-            {
-                var selection = ResultDocument.QuerySelector(error.Selector);
-                if (selection != null)
-                {
-                    string errorMessage = selection.TextContent;
-                    if (error.Message != null)
-                    {
-                        errorMessage = handleSelector(error.Message, ResultDocument.FirstElementChild);
-                    }
-                    throw new ExceptionWithConfigData(string.Format("Error: {0}", errorMessage.Trim()), configData);
-                }
-            }
-            return true; // no error
+        protected string applyGoTemplateText(string template, Dictionary<string, object> variables = null, TemplateTextModifier modifier = null)
+        {
+            if (variables == null)
+            {
+                variables = getTemplateVariablesFromConfigData();
+            }
+
+            // handle re_replace expression
+            // Example: {{ re_replace .Query.Keywords "[^a-zA-Z0-9]+" "%" }}
+            Regex ReReplaceRegex = new Regex(@"{{\s*re_replace\s+(\..+?)\s+""(.+)""\s+""(.+?)""\s*}}");
+            var ReReplaceRegexMatches = ReReplaceRegex.Match(template);
+
+            while (ReReplaceRegexMatches.Success)
+            {
+                string all = ReReplaceRegexMatches.Groups[0].Value;
+                string variable = ReReplaceRegexMatches.Groups[1].Value;
+                string regexp = ReReplaceRegexMatches.Groups[2].Value;
+                string newvalue = ReReplaceRegexMatches.Groups[3].Value;
+
+                Regex ReplaceRegex = new Regex(regexp);
+                var input = (string)variables[variable];
+                var expanded = ReplaceRegex.Replace(input, newvalue);
+
+                if (modifier != null)
+                    expanded = modifier(expanded);
+
+                template = template.Replace(all, expanded);
+                ReReplaceRegexMatches = ReReplaceRegexMatches.NextMatch();
+            }
+
+            // handle if ... else ... expression
+            Regex IfElseRegex = new Regex(@"{{\s*if\s*(.+?)\s*}}(.*?){{\s*else\s*}}(.*?){{\s*end\s*}}");
+            var IfElseRegexMatches = IfElseRegex.Match(template);
+
+            while (IfElseRegexMatches.Success)
+            {
+                string conditionResult = null;
+
+                string all = IfElseRegexMatches.Groups[0].Value;
+                string condition = IfElseRegexMatches.Groups[1].Value;
+                string onTrue = IfElseRegexMatches.Groups[2].Value;
+                string onFalse = IfElseRegexMatches.Groups[3].Value;
+
+                if (condition.StartsWith("."))
+                {
+                    string value = (string)variables[condition];
+                    if (!string.IsNullOrWhiteSpace(value))
+                    {
+                        conditionResult = onTrue;
+                    }
+                    else
+                    {
+                        conditionResult = onFalse;
+                    }
+                }
+                else
+                {
+                    throw new NotImplementedException("CardigannIndexer: Condition operation '" + condition + "' not implemented");
+                }
+                template = template.Replace(all, conditionResult);
+                IfElseRegexMatches = IfElseRegexMatches.NextMatch();
+            }
+
+            // handle range expression
+            Regex RangeRegex = new Regex(@"{{\s*range\s*(.+?)\s*}}(.*?){{\.}}(.*?){{end}}");
+            var RangeRegexMatches = RangeRegex.Match(template);
+
+            while (RangeRegexMatches.Success)
+            {
+                string expanded = string.Empty;
+
+                string all = RangeRegexMatches.Groups[0].Value;
+                string variable = RangeRegexMatches.Groups[1].Value;
+                string prefix = RangeRegexMatches.Groups[2].Value;
+                string postfix = RangeRegexMatches.Groups[3].Value;
+
+                foreach (string value in (List<string>)variables[variable])
+                {
+                    var newvalue = value;
+                    if (modifier != null)
+                        newvalue = modifier(newvalue);
+                    expanded += prefix + newvalue + postfix;
+                }
+                template = template.Replace(all, expanded);
+                RangeRegexMatches = RangeRegexMatches.NextMatch();
+            }
+
+            // handle simple variables
+            Regex VariablesRegEx = new Regex(@"{{\s*(\..+?)\s*}}");
+            var VariablesRegExMatches = VariablesRegEx.Match(template);
+
+            while (VariablesRegExMatches.Success)
+            {
+                string expanded = string.Empty;
+
+                string all = VariablesRegExMatches.Groups[0].Value;
+                string variable = VariablesRegExMatches.Groups[1].Value;
+
+                string value = (string)variables[variable];
+                if (modifier != null)
+                    value = modifier(value);
+                template = template.Replace(all, value);
+                VariablesRegExMatches = VariablesRegExMatches.NextMatch();
+            }
+
+            return template;
+        }
+
+        protected bool checkForError(WebClientStringResult loginResult, IList<errorBlock> errorBlocks)
+        {
+            if (errorBlocks == null)
+                return true; // no error
+
+            var ResultParser = new HtmlParser();
+            var ResultDocument = ResultParser.Parse(loginResult.Content);
+            foreach (errorBlock error in errorBlocks)
+            {
+                var selection = ResultDocument.QuerySelector(error.Selector);
+                if (selection != null)
+                {
+                    string errorMessage = selection.TextContent;
+                    if (error.Message != null)
+                    {
+                        errorMessage = handleSelector(error.Message, ResultDocument.FirstElementChild);
+                    }
+                    throw new ExceptionWithConfigData(string.Format("Error: {0}", errorMessage.Trim()), configData);
+                }
+            }
+            return true; // no error
         }
         
-        protected async Task<bool> DoLogin()
-        {
+        protected async Task<bool> DoLogin()
+        {
             var Login = Definition.Login;
 
             if (Login == null)
                 return true;
 
-            if (Login.Method == "post")
-            {
+            if (Login.Method == "post")
+            {
                 var pairs = new Dictionary<string, string>();
-                foreach (var Input in Definition.Login.Inputs)
-                {
-                    var value = applyGoTemplateText(Input.Value);
-                    pairs.Add(Input.Key, value);
+                foreach (var Input in Definition.Login.Inputs)
+                {
+                    var value = applyGoTemplateText(Input.Value);
+                    pairs.Add(Input.Key, value);
                 }
 
                 var LoginUrl = resolvePath(Login.Path).ToString();
                 configData.CookieHeader.Value = null;
                 var loginResult = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink, true);
                 configData.CookieHeader.Value = loginResult.Cookies;
-
+
                 checkForError(loginResult, Definition.Login.Error);
-            }
-            else if (Login.Method == "form")
-            {
-                var LoginUrl = resolvePath(Login.Path).ToString();
-
-                var queryCollection = new NameValueCollection();
-                var pairs = new Dictionary<string, string>();
-
-                var CaptchaConfigItem = (RecaptchaItem)configData.GetDynamic("Captcha");
-
-                if (CaptchaConfigItem != null)
-                { 
-                    if (!string.IsNullOrWhiteSpace(CaptchaConfigItem.Cookie))
-                    {
-                        // for remote users just set the cookie and return
-                        CookieHeader = CaptchaConfigItem.Cookie;
-                        return true;
-                    }
-
-                    var CloudFlareCaptchaChallenge = landingResultDocument.QuerySelector("script[src=\"/cdn-cgi/scripts/cf.challenge.js\"]");
-                    if (CloudFlareCaptchaChallenge != null)
-                    {
-                        var CloudFlareQueryCollection = new NameValueCollection();
-                        CloudFlareQueryCollection["id"] = CloudFlareCaptchaChallenge.GetAttribute("data-ray");
-                    
-                        CloudFlareQueryCollection["g-recaptcha-response"] = CaptchaConfigItem.Value;
-                        var ClearanceUrl = resolvePath("/cdn-cgi/l/chk_captcha?" + CloudFlareQueryCollection.GetQueryString());
-
-                        var ClearanceResult = await RequestStringWithCookies(ClearanceUrl.ToString(), null, SiteLink);
-
-                        if (ClearanceResult.IsRedirect) // clearance successfull
-                        {
-                            // request real login page again
-                            landingResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
-                            var htmlParser = new HtmlParser();
-                            landingResultDocument = htmlParser.Parse(landingResult.Content);
-                        }
-                        else
-                        {
-                            throw new ExceptionWithConfigData(string.Format("Login failed: Cloudflare clearance failed using cookies {0}: {1}", CookieHeader, ClearanceResult.Content), configData);
-                        }
-                    }
-                    else
-                    {
-                        pairs.Add("g-recaptcha-response", CaptchaConfigItem.Value);
-                    }
-                }
-
-                var FormSelector = Login.Form;
-                if (FormSelector == null)
-                    FormSelector = "form";
-
-                // landingResultDocument might not be initiated if the login is caused by a relogin during a query
-                if (landingResultDocument == null)
-                {
-                    var ConfigurationResult = await GetConfigurationForSetup(true);
-                    if (ConfigurationResult == null) // got captcha
-                    {
-                        return false;
-                    }
-                }
-
-                var form = landingResultDocument.QuerySelector(FormSelector);
-                if (form == null)
-                {
-                    throw new ExceptionWithConfigData(string.Format("Login failed: No form found on {0} using form selector {1}", LoginUrl, FormSelector), configData);
-                }
-
-                var inputs = form.QuerySelectorAll("input");
-                if (inputs == null)
-                {
-                    throw new ExceptionWithConfigData(string.Format("Login failed: No inputs found on {0} using form selector {1}", LoginUrl, FormSelector), configData);
-                }
-
-                var submitUrlstr = form.GetAttribute("action");
-                if (Login.Submitpath != null)
-                    submitUrlstr = Login.Submitpath;
-
-                foreach (var input in inputs)
-                {
-                    var name = input.GetAttribute("name");
-                    if (name == null)
-                        continue;
-
-                    var value = input.GetAttribute("value");
-                    if (value == null)
-                        value = "";
-
-                    pairs[name] = value;
-                }
+            }
+            else if (Login.Method == "form")
+            {
+                var LoginUrl = resolvePath(Login.Path).ToString();
+
+                var queryCollection = new NameValueCollection();
+                var pairs = new Dictionary<string, string>();
+
+                var CaptchaConfigItem = (RecaptchaItem)configData.GetDynamic("Captcha");
+
+                if (CaptchaConfigItem != null)
+                { 
+                    if (!string.IsNullOrWhiteSpace(CaptchaConfigItem.Cookie))
+                    {
+                        // for remote users just set the cookie and return
+                        CookieHeader = CaptchaConfigItem.Cookie;
+                        return true;
+                    }
+
+                    var CloudFlareCaptchaChallenge = landingResultDocument.QuerySelector("script[src=\"/cdn-cgi/scripts/cf.challenge.js\"]");
+                    if (CloudFlareCaptchaChallenge != null)
+                    {
+                        var CloudFlareQueryCollection = new NameValueCollection();
+                        CloudFlareQueryCollection["id"] = CloudFlareCaptchaChallenge.GetAttribute("data-ray");
+                    
+                        CloudFlareQueryCollection["g-recaptcha-response"] = CaptchaConfigItem.Value;
+                        var ClearanceUrl = resolvePath("/cdn-cgi/l/chk_captcha?" + CloudFlareQueryCollection.GetQueryString());
+
+                        var ClearanceResult = await RequestStringWithCookies(ClearanceUrl.ToString(), null, SiteLink);
+
+                        if (ClearanceResult.IsRedirect) // clearance successfull
+                        {
+                            // request real login page again
+                            landingResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
+                            var htmlParser = new HtmlParser();
+                            landingResultDocument = htmlParser.Parse(landingResult.Content);
+                        }
+                        else
+                        {
+                            throw new ExceptionWithConfigData(string.Format("Login failed: Cloudflare clearance failed using cookies {0}: {1}", CookieHeader, ClearanceResult.Content), configData);
+                        }
+                    }
+                    else
+                    {
+                        pairs.Add("g-recaptcha-response", CaptchaConfigItem.Value);
+                    }
+                }
+
+                var FormSelector = Login.Form;
+                if (FormSelector == null)
+                    FormSelector = "form";
+
+                // landingResultDocument might not be initiated if the login is caused by a relogin during a query
+                if (landingResultDocument == null)
+                {
+                    var ConfigurationResult = await GetConfigurationForSetup(true);
+                    if (ConfigurationResult == null) // got captcha
+                    {
+                        return false;
+                    }
+                }
+
+                var form = landingResultDocument.QuerySelector(FormSelector);
+                if (form == null)
+                {
+                    throw new ExceptionWithConfigData(string.Format("Login failed: No form found on {0} using form selector {1}", LoginUrl, FormSelector), configData);
+                }
+
+                var inputs = form.QuerySelectorAll("input");
+                if (inputs == null)
+                {
+                    throw new ExceptionWithConfigData(string.Format("Login failed: No inputs found on {0} using form selector {1}", LoginUrl, FormSelector), configData);
+                }
+
+                var submitUrlstr = form.GetAttribute("action");
+                if (Login.Submitpath != null)
+                    submitUrlstr = Login.Submitpath;
+
+                foreach (var input in inputs)
+                {
+                    var name = input.GetAttribute("name");
+                    if (name == null)
+                        continue;
+
+                    var value = input.GetAttribute("value");
+                    if (value == null)
+                        value = "";
+
+                    pairs[name] = value;
+                }
    
-                foreach (var Input in Definition.Login.Inputs)
-                {
-                    var value = applyGoTemplateText(Input.Value);
-                    var input = Input.Key;
-                    if (Login.Selectors)
-                    { 
-                        var inputElement = landingResultDocument.QuerySelector(Input.Key);
-                        if (inputElement == null)
-                            throw new ExceptionWithConfigData(string.Format("Login failed: No input found using selector {0}", Input.Key), configData);
-                        input = inputElement.GetAttribute("name");
-                    }
-                    pairs[input] = value;
-                }
-
-                // selector inputs
-                if (Login.Selectorinputs != null)
-                {
-                    foreach (var Selectorinput in Login.Selectorinputs)
-                    {
-                        string value = null;
-                        try
-                        {
-                            value = handleSelector(Selectorinput.Value, landingResultDocument.FirstElementChild);
-                            pairs[Selectorinput.Key] = value;
-                        }
-                        catch (Exception ex)
-                        {
-                            throw new Exception(string.Format("Error while parsing selector input={0}, selector={1}, value={2}: {3}", Selectorinput.Key, Selectorinput.Value.Selector, value, ex.Message));
-                        }
-                    }
-                }
-
-                // getselector inputs
-                if (Login.Getselectorinputs != null)
-                {
-                    foreach (var Selectorinput in Login.Getselectorinputs)
-                    {
-                        string value = null;
-                        try
-                        {
-                            value = handleSelector(Selectorinput.Value, landingResultDocument.FirstElementChild);
-                            queryCollection[Selectorinput.Key] = value;
-                        }
-                        catch (Exception ex)
-                        {
-                            throw new Exception(string.Format("Error while parsing get selector input={0}, selector={1}, value={2}: {3}", Selectorinput.Key, Selectorinput.Value.Selector, value, ex.Message));
-                        }
-                    }
-                }
-                if (queryCollection.Count > 0)
-                    submitUrlstr += "?" + queryCollection.GetQueryString();
-                var submitUrl = resolvePath(submitUrlstr, new Uri(LoginUrl));
-
-                // automatically solve simpleCaptchas, if used
-                var simpleCaptchaPresent = landingResultDocument.QuerySelector("script[src*=\"simpleCaptcha\"]");
-                if(simpleCaptchaPresent != null)
-                {
-                    var captchaUrl = resolvePath("simpleCaptcha.php?numImages=1");
-                    var simpleCaptchaResult = await RequestStringWithCookies(captchaUrl.ToString(), null, LoginUrl);
-                    var simpleCaptchaJSON = JObject.Parse(simpleCaptchaResult.Content);
-                    var captchaSelection = simpleCaptchaJSON["images"][0]["hash"].ToString();
-                    pairs["captchaSelection"] = captchaSelection;
-                    pairs["submitme"] = "X";
-                }
-
-                if (Login.Captcha != null)
-                {
-                    var Captcha = Login.Captcha;
-                    if (Captcha.Type == "image")
-                    {
-                        var CaptchaText = (StringItem)configData.GetDynamic("CaptchaText");
-                        if (CaptchaText != null)
-                        {
-                            var input = Captcha.Input;
-                            if (Login.Selectors)
-                            { 
-                                var inputElement = landingResultDocument.QuerySelector(Captcha.Input);
-                                if (inputElement == null)
-                                    throw new ExceptionWithConfigData(string.Format("Login failed: No captcha input found using {0}", Captcha.Input), configData);
-                                input = inputElement.GetAttribute("name");
-                            }
-                            pairs[input] = CaptchaText.Value;
-                        }
-                    }
-                }
-
-                // clear landingResults/Document, otherwise we might use an old version for a new relogin (if GetConfigurationForSetup() wasn't called before)
-                landingResult = null;
-                landingResultDocument = null;
-
-                WebClientStringResult loginResult = null;
-                var enctype = form.GetAttribute("enctype");
-                if (enctype == "multipart/form-data")
-                {
-                    var headers = new Dictionary<string, string>();
-                    var boundary = "---------------------------" + (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString().Replace(".", "");
-                    var bodyParts = new List<string>();
-
-                    foreach (var pair in pairs)
-                    {
-                        var part = "--" + boundary + "\r\n" +
-                          "Content-Disposition: form-data; name=\"" + pair.Key + "\"\r\n" +
-                          "\r\n" +
-                          pair.Value;
-                        bodyParts.Add(part);
-                    }
-
-                    bodyParts.Add("--" + boundary + "--");
-
-                    headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
-                    var body = string.Join("\r\n",  bodyParts);
-                    loginResult = await PostDataWithCookies(submitUrl.ToString(), pairs, configData.CookieHeader.Value, SiteLink, headers, body);
-                } else {
-                    loginResult = await RequestLoginAndFollowRedirect(submitUrl.ToString(), pairs, configData.CookieHeader.Value, true, null, LoginUrl, true);
-                }
-
+                foreach (var Input in Definition.Login.Inputs)
+                {
+                    var value = applyGoTemplateText(Input.Value);
+                    var input = Input.Key;
+                    if (Login.Selectors)
+                    { 
+                        var inputElement = landingResultDocument.QuerySelector(Input.Key);
+                        if (inputElement == null)
+                            throw new ExceptionWithConfigData(string.Format("Login failed: No input found using selector {0}", Input.Key), configData);
+                        input = inputElement.GetAttribute("name");
+                    }
+                    pairs[input] = value;
+                }
+
+                // selector inputs
+                if (Login.Selectorinputs != null)
+                {
+                    foreach (var Selectorinput in Login.Selectorinputs)
+                    {
+                        string value = null;
+                        try
+                        {
+                            value = handleSelector(Selectorinput.Value, landingResultDocument.FirstElementChild);
+                            pairs[Selectorinput.Key] = value;
+                        }
+                        catch (Exception ex)
+                        {
+                            throw new Exception(string.Format("Error while parsing selector input={0}, selector={1}, value={2}: {3}", Selectorinput.Key, Selectorinput.Value.Selector, value, ex.Message));
+                        }
+                    }
+                }
+
+                // getselector inputs
+                if (Login.Getselectorinputs != null)
+                {
+                    foreach (var Selectorinput in Login.Getselectorinputs)
+                    {
+                        string value = null;
+                        try
+                        {
+                            value = handleSelector(Selectorinput.Value, landingResultDocument.FirstElementChild);
+                            queryCollection[Selectorinput.Key] = value;
+                        }
+                        catch (Exception ex)
+                        {
+                            throw new Exception(string.Format("Error while parsing get selector input={0}, selector={1}, value={2}: {3}", Selectorinput.Key, Selectorinput.Value.Selector, value, ex.Message));
+                        }
+                    }
+                }
+                if (queryCollection.Count > 0)
+                    submitUrlstr += "?" + queryCollection.GetQueryString();
+                var submitUrl = resolvePath(submitUrlstr, new Uri(LoginUrl));
+
+                // automatically solve simpleCaptchas, if used
+                var simpleCaptchaPresent = landingResultDocument.QuerySelector("script[src*=\"simpleCaptcha\"]");
+                if(simpleCaptchaPresent != null)
+                {
+                    var captchaUrl = resolvePath("simpleCaptcha.php?numImages=1");
+                    var simpleCaptchaResult = await RequestStringWithCookies(captchaUrl.ToString(), null, LoginUrl);
+                    var simpleCaptchaJSON = JObject.Parse(simpleCaptchaResult.Content);
+                    var captchaSelection = simpleCaptchaJSON["images"][0]["hash"].ToString();
+                    pairs["captchaSelection"] = captchaSelection;
+                    pairs["submitme"] = "X";
+                }
+
+                if (Login.Captcha != null)
+                {
+                    var Captcha = Login.Captcha;
+                    if (Captcha.Type == "image")
+                    {
+                        var CaptchaText = (StringItem)configData.GetDynamic("CaptchaText");
+                        if (CaptchaText != null)
+                        {
+                            var input = Captcha.Input;
+                            if (Login.Selectors)
+                            { 
+                                var inputElement = landingResultDocument.QuerySelector(Captcha.Input);
+                                if (inputElement == null)
+                                    throw new ExceptionWithConfigData(string.Format("Login failed: No captcha input found using {0}", Captcha.Input), configData);
+                                input = inputElement.GetAttribute("name");
+                            }
+                            pairs[input] = CaptchaText.Value;
+                        }
+                    }
+                }
+
+                // clear landingResults/Document, otherwise we might use an old version for a new relogin (if GetConfigurationForSetup() wasn't called before)
+                landingResult = null;
+                landingResultDocument = null;
+
+                WebClientStringResult loginResult = null;
+                var enctype = form.GetAttribute("enctype");
+                if (enctype == "multipart/form-data")
+                {
+                    var headers = new Dictionary<string, string>();
+                    var boundary = "---------------------------" + (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds.ToString().Replace(".", "");
+                    var bodyParts = new List<string>();
+
+                    foreach (var pair in pairs)
+                    {
+                        var part = "--" + boundary + "\r\n" +
+                          "Content-Disposition: form-data; name=\"" + pair.Key + "\"\r\n" +
+                          "\r\n" +
+                          pair.Value;
+                        bodyParts.Add(part);
+                    }
+
+                    bodyParts.Add("--" + boundary + "--");
+
+                    headers.Add("Content-Type", "multipart/form-data; boundary=" + boundary);
+                    var body = string.Join("\r\n",  bodyParts);
+                    loginResult = await PostDataWithCookies(submitUrl.ToString(), pairs, configData.CookieHeader.Value, SiteLink, headers, body);
+                } else {
+                    loginResult = await RequestLoginAndFollowRedirect(submitUrl.ToString(), pairs, configData.CookieHeader.Value, true, null, LoginUrl, true);
+                }
+
                 configData.CookieHeader.Value = loginResult.Cookies;
 
                 checkForError(loginResult, Definition.Login.Error);
-            }
-            else if (Login.Method == "cookie")
-            {
-                configData.CookieHeader.Value = ((StringItem)configData.GetDynamic("cookie")).Value;
-            }
-            else if (Login.Method == "get")
-            {
-                var queryCollection = new NameValueCollection();
-                foreach (var Input in Definition.Login.Inputs)
-                {
-                    var value = applyGoTemplateText(Input.Value);
-                    queryCollection.Add(Input.Key, value);
-                }
-
-                var LoginUrl = resolvePath(Login.Path + "?" + queryCollection.GetQueryString()).ToString();
-                configData.CookieHeader.Value = null;
-                var loginResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
-                configData.CookieHeader.Value = loginResult.Cookies;
-
-                checkForError(loginResult, Definition.Login.Error);
-            }
-            else
-            {
-                throw new NotImplementedException("Login method " + Definition.Login.Method + " not implemented");
-            }
-            logger.Debug(string.Format("CardigannIndexer ({0}): Cookies after login: {1}", ID, CookieHeader));
-            return true;
+            }
+            else if (Login.Method == "cookie")
+            {
+                configData.CookieHeader.Value = ((StringItem)configData.GetDynamic("cookie")).Value;
+            }
+            else if (Login.Method == "get")
+            {
+                var queryCollection = new NameValueCollection();
+                foreach (var Input in Definition.Login.Inputs)
+                {
+                    var value = applyGoTemplateText(Input.Value);
+                    queryCollection.Add(Input.Key, value);
+                }
+
+                var LoginUrl = resolvePath(Login.Path + "?" + queryCollection.GetQueryString()).ToString();
+                configData.CookieHeader.Value = null;
+                var loginResult = await RequestStringWithCookies(LoginUrl, null, SiteLink);
+                configData.CookieHeader.Value = loginResult.Cookies;
+
+                checkForError(loginResult, Definition.Login.Error);
+            }
+            else
+            {
+                throw new NotImplementedException("Login method " + Definition.Login.Method + " not implemented");
+            }
+            logger.Debug(string.Format("CardigannIndexer ({0}): Cookies after login: {1}", ID, CookieHeader));
+            return true;
         }
 
-        protected async Task<bool> TestLogin()
-        {
-            var Login = Definition.Login;
-
+        protected async Task<bool> TestLogin()
+        {
+            var Login = Definition.Login;
+
             if (Login == null || Login.Test == null)
-                return false;
-
+                return false;
+
             // test if login was successful
             var LoginTestUrl = resolvePath(Login.Test.Path).ToString();
             var testResult = await RequestStringWithCookies(LoginTestUrl);
 
-            if (testResult.IsRedirect)
-            {
-                throw new ExceptionWithConfigData("Login Failed, got redirected", configData);
+            if (testResult.IsRedirect)
+            {
+                throw new ExceptionWithConfigData("Login Failed, got redirected", configData);
             }
-
-            if (Login.Test.Selector != null)
-            {
-                var testResultParser = new HtmlParser();
-                var testResultDocument = testResultParser.Parse(testResult.Content);
+
+            if (Login.Test.Selector != null)
+            {
+                var testResultParser = new HtmlParser();
+                var testResultDocument = testResultParser.Parse(testResult.Content);
                 var selection = testResultDocument.QuerySelectorAll(Login.Test.Selector);
-                if (selection.Length == 0)
-                {
-                    throw new ExceptionWithConfigData(string.Format("Login failed: Selector \"{0}\" didn't match", Login.Test.Selector), configData);
-                }
-            }
-            return true;
+                if (selection.Length == 0)
+                {
+                    throw new ExceptionWithConfigData(string.Format("Login failed: Selector \"{0}\" didn't match", Login.Test.Selector), configData);
+                }
+            }
+            return true;
         }
 
-        protected bool CheckIfLoginIsNeeded(WebClientStringResult Result, IHtmlDocument document)
-        {
-            if (Result.IsRedirect)
-            {
-                return true;
+        protected bool CheckIfLoginIsNeeded(WebClientStringResult Result, IHtmlDocument document)
+        {
+            if (Result.IsRedirect)
+            {
+                return true;
             }
-
-            if (Definition.Login == null || Definition.Login.Test == null)
-                return false;
-
-            if (Definition.Login.Test.Selector != null)
-            {
+
+            if (Definition.Login == null || Definition.Login.Test == null)
+                return false;
+
+            if (Definition.Login.Test.Selector != null)
+            {
                 var selection = document.QuerySelectorAll(Definition.Login.Test.Selector);
-                if (selection.Length == 0)
-                {
-                    return true;
-                }
-            }
-            return false;
-        }
-
+                if (selection.Length == 0)
+                {
+                    return true;
+                }
+            }
+            return false;
+        }
+
         public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            return await GetConfigurationForSetup(false);
-        }
-
+        {
+            return await GetConfigurationForSetup(false);
+        }
+
         public async Task<ConfigurationData> GetConfigurationForSetup(bool automaticlogin)
-        {
+        {
             var Login = Definition.Login;
 
             if (Login == null || Login.Method != "form")
                 return configData;
 
-            var LoginUrl = resolvePath(Login.Path);
-
-            configData.CookieHeader.Value = null;
-            if (Login.Cookies != null)
-                configData.CookieHeader.Value = String.Join("; ", Login.Cookies);
-            landingResult = await RequestStringWithCookies(LoginUrl.AbsoluteUri, null, SiteLink);
-
-            var htmlParser = new HtmlParser();
-            landingResultDocument = htmlParser.Parse(landingResult.Content);
-
-            var hasCaptcha = false;
-
-            var grecaptcha = landingResultDocument.QuerySelector(".g-recaptcha");
-            if (grecaptcha != null)
-            {
-                hasCaptcha = true;
-                var CaptchaItem = new RecaptchaItem();
-                CaptchaItem.Name = "Captcha";
-                CaptchaItem.Version = "2";
-                CaptchaItem.SiteKey = grecaptcha.GetAttribute("data-sitekey");
-                if (CaptchaItem.SiteKey == null) // some sites don't store the sitekey in the .g-recaptcha div (e.g. cloudflare captcha challenge page)
-                    CaptchaItem.SiteKey = landingResultDocument.QuerySelector("[data-sitekey]").GetAttribute("data-sitekey");
-
-                configData.AddDynamic("Captcha", CaptchaItem);
+            var LoginUrl = resolvePath(Login.Path);
+
+            configData.CookieHeader.Value = null;
+            if (Login.Cookies != null)
+                configData.CookieHeader.Value = String.Join("; ", Login.Cookies);
+            landingResult = await RequestStringWithCookies(LoginUrl.AbsoluteUri, null, SiteLink);
+
+            var htmlParser = new HtmlParser();
+            landingResultDocument = htmlParser.Parse(landingResult.Content);
+
+            var hasCaptcha = false;
+
+            var grecaptcha = landingResultDocument.QuerySelector(".g-recaptcha");
+            if (grecaptcha != null)
+            {
+                hasCaptcha = true;
+                var CaptchaItem = new RecaptchaItem();
+                CaptchaItem.Name = "Captcha";
+                CaptchaItem.Version = "2";
+                CaptchaItem.SiteKey = grecaptcha.GetAttribute("data-sitekey");
+                if (CaptchaItem.SiteKey == null) // some sites don't store the sitekey in the .g-recaptcha div (e.g. cloudflare captcha challenge page)
+                    CaptchaItem.SiteKey = landingResultDocument.QuerySelector("[data-sitekey]").GetAttribute("data-sitekey");
+
+                configData.AddDynamic("Captcha", CaptchaItem);
             }
 
-            if (Login.Captcha != null)
-            {
-                var Captcha = Login.Captcha;
-                if (Captcha.Type == "image")
-                {
-                    var captchaElement = landingResultDocument.QuerySelector(Captcha.Image);
-                    if (captchaElement != null) {
-                        hasCaptcha = true;
-
-                        var CaptchaUrl = resolvePath(captchaElement.GetAttribute("src"), LoginUrl);
-                        var captchaImageData = await RequestBytesWithCookies(CaptchaUrl.ToString(), landingResult.Cookies, RequestType.GET, LoginUrl.AbsoluteUri);
-                        var CaptchaImage = new ImageItem { Name = "Captcha Image" };
-                        var CaptchaText = new StringItem { Name = "Captcha Text" };
-
-                        CaptchaImage.Value = captchaImageData.Content;
-
-                        configData.AddDynamic("CaptchaImage", CaptchaImage);
-                        configData.AddDynamic("CaptchaText", CaptchaText);
-                    }
-                    else
-                    {
-                        logger.Debug(string.Format("CardigannIndexer ({0}): No captcha image found", ID));
-                    }
-                }
-                else
-                {
-                    throw new NotImplementedException(string.Format("Captcha type \"{0}\" is not implemented", Captcha.Type));
-                }
+            if (Login.Captcha != null)
+            {
+                var Captcha = Login.Captcha;
+                if (Captcha.Type == "image")
+                {
+                    var captchaElement = landingResultDocument.QuerySelector(Captcha.Image);
+                    if (captchaElement != null) {
+                        hasCaptcha = true;
+
+                        var CaptchaUrl = resolvePath(captchaElement.GetAttribute("src"), LoginUrl);
+                        var captchaImageData = await RequestBytesWithCookies(CaptchaUrl.ToString(), landingResult.Cookies, RequestType.GET, LoginUrl.AbsoluteUri);
+                        var CaptchaImage = new ImageItem { Name = "Captcha Image" };
+                        var CaptchaText = new StringItem { Name = "Captcha Text" };
+
+                        CaptchaImage.Value = captchaImageData.Content;
+
+                        configData.AddDynamic("CaptchaImage", CaptchaImage);
+                        configData.AddDynamic("CaptchaText", CaptchaText);
+                    }
+                    else
+                    {
+                        logger.Debug(string.Format("CardigannIndexer ({0}): No captcha image found", ID));
+                    }
+                }
+                else
+                {
+                    throw new NotImplementedException(string.Format("Captcha type \"{0}\" is not implemented", Captcha.Type));
+                }
             }
 
-            if (hasCaptcha && automaticlogin)
-            {
-                configData.LastError.Value = "Got captcha during automatic login, please reconfigure manually";
-                logger.Error(string.Format("CardigannIndexer ({0}): Found captcha during automatic login, aborting", ID));
-                return null;
+            if (hasCaptcha && automaticlogin)
+            {
+                configData.LastError.Value = "Got captcha during automatic login, please reconfigure manually";
+                logger.Error(string.Format("CardigannIndexer ({0}): Found captcha during automatic login, aborting", ID));
+                return null;
             }
 
             return configData;
@@ -915,190 +915,190 @@ namespace Jackett.Indexers
             await DoLogin();
             await TestLogin();
 
-            SaveConfig();
-            IsConfigured = true;
-            return IndexerConfigurationStatus.Completed;
+            SaveConfig();
+            IsConfigured = true;
+            return IndexerConfigurationStatus.Completed;
         }
 
-        protected string applyFilters(string Data, List<filterBlock> Filters, Dictionary<string, object> variables = null)
-        {
-            if (Filters == null)
-                return Data;
-
-            foreach(filterBlock Filter in Filters)
-            {
-                switch (Filter.Name)
-                {
-                    case "querystring":
-                        var param = (string)Filter.Args;
-                        Data = ParseUtil.GetArgumentFromQueryString(Data, param);
-                        break;
-                    case "timeparse":
-                    case "dateparse":
-                        var layout = (string)Filter.Args;
-                        try
-                        {
-                            var Date = DateTimeUtil.ParseDateTimeGoLang(Data, layout);
-                            Data = Date.ToString(DateTimeUtil.RFC1123ZPattern);
-                        }
-                        catch (FormatException ex)
-                        {
-                            logger.Debug(ex.Message);
-                        }
-                    break;
-                    case "regexp":
-                        var pattern = (string)Filter.Args;
-                        var Regexp = new Regex(pattern);
-                        var Match = Regexp.Match(Data);
-                        Data = Match.Groups[1].Value;
-                        break;
-                    case "re_replace":
-                        var regexpreplace_pattern = (string)Filter.Args[0];
-                        var regexpreplace_replacement = (string)Filter.Args[1];
-                        regexpreplace_replacement = applyGoTemplateText(regexpreplace_replacement, variables);
-                        Regex regexpreplace_regex = new Regex(regexpreplace_pattern);
-                        Data = regexpreplace_regex.Replace(Data, regexpreplace_replacement);
-                        break;                        
-                    case "split":
-                        var sep = (string)Filter.Args[0];
-                        var pos = (string)Filter.Args[1];
-                        var posInt = int.Parse(pos);
-                        var strParts = Data.Split(sep[0]);
-                        if (posInt < 0)
-                        {
-                            posInt += strParts.Length;
-                        }
-                        Data = strParts[posInt];
-                        break;
-                    case "replace":
-                        var from = (string)Filter.Args[0];
-                        var to = (string)Filter.Args[1];
-                        to = applyGoTemplateText(to, variables);
-                        Data = Data.Replace(from, to);
-                        break;
-                    case "trim":
-                        var cutset = (string)Filter.Args;
-                        if (cutset != null)
-                            Data = Data.Trim(cutset[0]);
-                        else
-                            Data = Data.Trim();
-                        break;
-                    case "prepend":
-                        var prependstr = (string)Filter.Args;
-                        Data = applyGoTemplateText(prependstr, variables) + Data;
-                        break;
-                    case "append":
-                        var str = (string)Filter.Args;
-                        Data += applyGoTemplateText(str, variables);
-                        break;
-                    case "tolower":
-                        Data = Data.ToLower();
-                        break;
-                    case "toupper":
-                        Data = Data.ToUpper();
-                        break;
-                    case "urldecode":
-                        Data = HttpUtility.UrlDecode(Data, Encoding);
-                        break;
-                    case "timeago":
-                    case "reltime":
-                        Data = DateTimeUtil.FromTimeAgo(Data).ToString(DateTimeUtil.RFC1123ZPattern);
-                        break;
-                    case "fuzzytime":
-                        var timestr = (string)Filter.Args;
-                        Data = DateTimeUtil.FromUnknown(timestr).ToString(DateTimeUtil.RFC1123ZPattern);
-                        break;
-                    case "hexdump":
-                        // this is mainly for debugging invisible special char related issues
-                        var HexData = string.Join("", Data.Select(c => c + "(" + ((int)c).ToString("X2") + ")"));
-                        logger.Info(string.Format("CardigannIndexer ({0}): strdump: {1}", ID, HexData));
-                        break;
-                    case "strdump":
-                        // for debugging
-                        var DebugData = Data.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\xA0", "\\xA0");
-                        logger.Info(string.Format("CardigannIndexer ({0}): strdump: {1}", ID, DebugData));
-                        break;
-                    default:
-                        break;
-                }
-            }
-            return Data;
+        protected string applyFilters(string Data, List<filterBlock> Filters, Dictionary<string, object> variables = null)
+        {
+            if (Filters == null)
+                return Data;
+
+            foreach(filterBlock Filter in Filters)
+            {
+                switch (Filter.Name)
+                {
+                    case "querystring":
+                        var param = (string)Filter.Args;
+                        Data = ParseUtil.GetArgumentFromQueryString(Data, param);
+                        break;
+                    case "timeparse":
+                    case "dateparse":
+                        var layout = (string)Filter.Args;
+                        try
+                        {
+                            var Date = DateTimeUtil.ParseDateTimeGoLang(Data, layout);
+                            Data = Date.ToString(DateTimeUtil.RFC1123ZPattern);
+                        }
+                        catch (FormatException ex)
+                        {
+                            logger.Debug(ex.Message);
+                        }
+                    break;
+                    case "regexp":
+                        var pattern = (string)Filter.Args;
+                        var Regexp = new Regex(pattern);
+                        var Match = Regexp.Match(Data);
+                        Data = Match.Groups[1].Value;
+                        break;
+                    case "re_replace":
+                        var regexpreplace_pattern = (string)Filter.Args[0];
+                        var regexpreplace_replacement = (string)Filter.Args[1];
+                        regexpreplace_replacement = applyGoTemplateText(regexpreplace_replacement, variables);
+                        Regex regexpreplace_regex = new Regex(regexpreplace_pattern);
+                        Data = regexpreplace_regex.Replace(Data, regexpreplace_replacement);
+                        break;                        
+                    case "split":
+                        var sep = (string)Filter.Args[0];
+                        var pos = (string)Filter.Args[1];
+                        var posInt = int.Parse(pos);
+                        var strParts = Data.Split(sep[0]);
+                        if (posInt < 0)
+                        {
+                            posInt += strParts.Length;
+                        }
+                        Data = strParts[posInt];
+                        break;
+                    case "replace":
+                        var from = (string)Filter.Args[0];
+                        var to = (string)Filter.Args[1];
+                        to = applyGoTemplateText(to, variables);
+                        Data = Data.Replace(from, to);
+                        break;
+                    case "trim":
+                        var cutset = (string)Filter.Args;
+                        if (cutset != null)
+                            Data = Data.Trim(cutset[0]);
+                        else
+                            Data = Data.Trim();
+                        break;
+                    case "prepend":
+                        var prependstr = (string)Filter.Args;
+                        Data = applyGoTemplateText(prependstr, variables) + Data;
+                        break;
+                    case "append":
+                        var str = (string)Filter.Args;
+                        Data += applyGoTemplateText(str, variables);
+                        break;
+                    case "tolower":
+                        Data = Data.ToLower();
+                        break;
+                    case "toupper":
+                        Data = Data.ToUpper();
+                        break;
+                    case "urldecode":
+                        Data = HttpUtility.UrlDecode(Data, Encoding);
+                        break;
+                    case "timeago":
+                    case "reltime":
+                        Data = DateTimeUtil.FromTimeAgo(Data).ToString(DateTimeUtil.RFC1123ZPattern);
+                        break;
+                    case "fuzzytime":
+                        var timestr = (string)Filter.Args;
+                        Data = DateTimeUtil.FromUnknown(timestr).ToString(DateTimeUtil.RFC1123ZPattern);
+                        break;
+                    case "hexdump":
+                        // this is mainly for debugging invisible special char related issues
+                        var HexData = string.Join("", Data.Select(c => c + "(" + ((int)c).ToString("X2") + ")"));
+                        logger.Info(string.Format("CardigannIndexer ({0}): strdump: {1}", ID, HexData));
+                        break;
+                    case "strdump":
+                        // for debugging
+                        var DebugData = Data.Replace("\r", "\\r").Replace("\n", "\\n").Replace("\xA0", "\\xA0");
+                        logger.Info(string.Format("CardigannIndexer ({0}): strdump: {1}", ID, DebugData));
+                        break;
+                    default:
+                        break;
+                }
+            }
+            return Data;
         }
 
-        protected IElement QuerySelector(IElement Element, string Selector)
-        {
-            // AngleSharp doesn't support the :root pseudo selector, so we check for it manually
-            if (Selector.StartsWith(":root"))
-            {
-                Selector = Selector.Substring(5);
-                while (Element.ParentElement != null)
-                {
-                    Element = Element.ParentElement;
-                }
-            }
-            return Element.QuerySelector(Selector);
+        protected IElement QuerySelector(IElement Element, string Selector)
+        {
+            // AngleSharp doesn't support the :root pseudo selector, so we check for it manually
+            if (Selector.StartsWith(":root"))
+            {
+                Selector = Selector.Substring(5);
+                while (Element.ParentElement != null)
+                {
+                    Element = Element.ParentElement;
+                }
+            }
+            return Element.QuerySelector(Selector);
         }
 
-        protected string handleSelector(selectorBlock Selector, IElement Dom, Dictionary<string, object> variables = null)
-        {
-            if (Selector.Text != null)
-            {
-                return applyFilters(applyGoTemplateText(Selector.Text, variables), Selector.Filters, variables);
-            }
-
-            IElement selection = Dom;
-            string value = null;
-
-            if (Selector.Selector != null)
-            {
-                selection = QuerySelector(Dom, Selector.Selector);
-                if (selection == null)
-                {
-                    throw new Exception(string.Format("Selector \"{0}\" didn't match {1}", Selector.Selector, Dom.ToHtmlPretty()));
-                }
-            }
-
-            if (Selector.Remove != null)
-            {
-                foreach(var i in selection.QuerySelectorAll(Selector.Remove))
-                {
-                    i.Remove();
-                }
-            }
-
-            if (Selector.Case != null)
-            {
-                foreach(var Case in Selector.Case)
-                {
-                    if (selection.Matches(Case.Key) || QuerySelector(selection, Case.Key) != null)
-                    {
-                        value = Case.Value;
-                        break;
-                    }
-                }
-                if(value == null)
-                    throw new Exception(string.Format("None of the case selectors \"{0}\" matched {1}", string.Join(",", Selector.Case), selection.ToHtmlPretty()));
-            }
-            else if (Selector.Attribute != null)
-            {
-                value = selection.GetAttribute(Selector.Attribute);
-                if (value == null)
-                    throw new Exception(string.Format("Attribute \"{0}\" is not set for element {1}", Selector.Attribute, selection.ToHtmlPretty()));
-            }
-            else
-            {
-                value = selection.TextContent;
-            }
-
-            return applyFilters(ParseUtil.NormalizeSpace(value), Selector.Filters, variables);
+        protected string handleSelector(selectorBlock Selector, IElement Dom, Dictionary<string, object> variables = null)
+        {
+            if (Selector.Text != null)
+            {
+                return applyFilters(applyGoTemplateText(Selector.Text, variables), Selector.Filters, variables);
+            }
+
+            IElement selection = Dom;
+            string value = null;
+
+            if (Selector.Selector != null)
+            {
+                selection = QuerySelector(Dom, Selector.Selector);
+                if (selection == null)
+                {
+                    throw new Exception(string.Format("Selector \"{0}\" didn't match {1}", Selector.Selector, Dom.ToHtmlPretty()));
+                }
+            }
+
+            if (Selector.Remove != null)
+            {
+                foreach(var i in selection.QuerySelectorAll(Selector.Remove))
+                {
+                    i.Remove();
+                }
+            }
+
+            if (Selector.Case != null)
+            {
+                foreach(var Case in Selector.Case)
+                {
+                    if (selection.Matches(Case.Key) || QuerySelector(selection, Case.Key) != null)
+                    {
+                        value = Case.Value;
+                        break;
+                    }
+                }
+                if(value == null)
+                    throw new Exception(string.Format("None of the case selectors \"{0}\" matched {1}", string.Join(",", Selector.Case), selection.ToHtmlPretty()));
+            }
+            else if (Selector.Attribute != null)
+            {
+                value = selection.GetAttribute(Selector.Attribute);
+                if (value == null)
+                    throw new Exception(string.Format("Attribute \"{0}\" is not set for element {1}", Selector.Attribute, selection.ToHtmlPretty()));
+            }
+            else
+            {
+                value = selection.TextContent;
+            }
+
+            return applyFilters(ParseUtil.NormalizeSpace(value), Selector.Filters, variables);
         }
 
-        protected Uri resolvePath(string path, Uri currentUrl = null)
-        {
-            if (currentUrl == null)
-                currentUrl = new Uri(SiteLink);
-
-            return new Uri(currentUrl, path);
+        protected Uri resolvePath(string path, Uri currentUrl = null)
+        {
+            if (currentUrl == null)
+                currentUrl = new Uri(SiteLink);
+
+            return new Uri(currentUrl, path);
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
@@ -1108,511 +1108,511 @@ namespace Jackett.Indexers
             searchBlock Search = Definition.Search;
 
             // init template context
-            var variables = getTemplateVariablesFromConfigData();
-
-            variables[".Query.Type"] = query.QueryType;
-            variables[".Query.Q"] = query.SearchTerm;
-            variables[".Query.Series"] = null;
-            variables[".Query.Ep"] = query.Episode;
-            variables[".Query.Season"] = query.Season;
-            variables[".Query.Movie"] = null;
-            variables[".Query.Year"] = null;
-            variables[".Query.Limit"] = query.Limit;
-            variables[".Query.Offset"] = query.Offset;
-            variables[".Query.Extended"] = query.Extended;
-            variables[".Query.Categories"] = query.Categories;
-            variables[".Query.APIKey"] = query.ApiKey;
-            variables[".Query.TVDBID"] = null;
-            variables[".Query.TVRageID"] = query.RageID;
-            variables[".Query.IMDBID"] = query.ImdbID;
-            variables[".Query.IMDBIDShort"] = query.ImdbIDShort;
-            variables[".Query.TVMazeID"] = null;
-            variables[".Query.TraktID"] = null;
-
-            variables[".Query.Episode"] = query.GetEpisodeSearchString();
-
-            var mappedCategories = MapTorznabCapsToTrackers(query);
-            variables[".Categories"] = mappedCategories;
-
-            var KeywordTokens = new List<string>();
-            var KeywordTokenKeys = new List<string> { "Q", "Series", "Movie", "Year" };
-            foreach (var key in KeywordTokenKeys)
-            {
-                var Value = (string)variables[".Query." + key];
-                if (!string.IsNullOrWhiteSpace(Value))
-                    KeywordTokens.Add(Value);
-            }
-
-            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
-                KeywordTokens.Add((string)variables[".Query.Episode"]);
-            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
-            variables[".Keywords"] = applyFilters((string)variables[".Query.Keywords"], Search.Keywordsfilters);
-
-            // TODO: prepare queries first and then send them parallel 
-            var SearchPaths = Search.Paths;
-            foreach (var SearchPath in SearchPaths)
-            {
-                // skip path if categories don't match
-                if (SearchPath.Categories != null && mappedCategories.Count > 0)
-                {
-                    var invertMatch = (SearchPath.Categories[0] == "!");
-                    var hasIntersect = mappedCategories.Intersect(SearchPath.Categories).Any();
-                    if (invertMatch)
-                        hasIntersect = !hasIntersect;
-                    if (!hasIntersect)
-                        continue;
-                }
-
-                // build search URL
-                // HttpUtility.UrlPathEncode seems to only encode spaces, we use UrlEncode and replace + with %20 as a workaround
-                var searchUrl = resolvePath(applyGoTemplateText(SearchPath.Path, variables, HttpUtility.UrlEncode).Replace("+", "%20")).AbsoluteUri;
-                var queryCollection = new List<KeyValuePair<string, string>>();
-                RequestType method = RequestType.GET;
-
-                if (String.Equals(SearchPath.Method, "post", StringComparison.OrdinalIgnoreCase))
-                {
-                    method = RequestType.POST;
-                }
-
-                var InputsList = new List<Dictionary<string, string>>();
-                if (SearchPath.Inheritinputs)
-                    InputsList.Add(Search.Inputs);
-                InputsList.Add(SearchPath.Inputs);
-
-                foreach (var Inputs in InputsList)
-                { 
-                    if (Inputs != null)
-                    {
-                        foreach (var Input in Inputs)
-                        {
-                            if (Input.Key == "$raw")
-                            {
-                                var rawStr = applyGoTemplateText(Input.Value, variables, HttpUtility.UrlEncode);
-                                foreach (string part in rawStr.Split('&'))
-                                {
-                                    var parts = part.Split(new char[] { '=' }, 2);
-                                    var key = parts[0];
-                                    if (key.Length == 0)
-                                        continue;
-                                    var value = "";
-                                    if (parts.Count() == 2)
-                                        value = parts[1];
-                                    queryCollection.Add(key, value);
-                                }
-                            }
-                            else
-                                queryCollection.Add(Input.Key, applyGoTemplateText(Input.Value, variables));
-                        }
-                    }
-                }
-
-                if (method == RequestType.GET)
-                {
-                    if (queryCollection.Count > 0)
-                        searchUrl += "?" + queryCollection.GetQueryString(Encoding);
-                }
-
-                // send HTTP request
-                WebClientStringResult response = null;
-                if (method == RequestType.POST)
+            var variables = getTemplateVariablesFromConfigData();
+
+            variables[".Query.Type"] = query.QueryType;
+            variables[".Query.Q"] = query.SearchTerm;
+            variables[".Query.Series"] = null;
+            variables[".Query.Ep"] = query.Episode;
+            variables[".Query.Season"] = query.Season;
+            variables[".Query.Movie"] = null;
+            variables[".Query.Year"] = null;
+            variables[".Query.Limit"] = query.Limit;
+            variables[".Query.Offset"] = query.Offset;
+            variables[".Query.Extended"] = query.Extended;
+            variables[".Query.Categories"] = query.Categories;
+            variables[".Query.APIKey"] = query.ApiKey;
+            variables[".Query.TVDBID"] = null;
+            variables[".Query.TVRageID"] = query.RageID;
+            variables[".Query.IMDBID"] = query.ImdbID;
+            variables[".Query.IMDBIDShort"] = query.ImdbIDShort;
+            variables[".Query.TVMazeID"] = null;
+            variables[".Query.TraktID"] = null;
+
+            variables[".Query.Episode"] = query.GetEpisodeSearchString();
+
+            var mappedCategories = MapTorznabCapsToTrackers(query);
+            variables[".Categories"] = mappedCategories;
+
+            var KeywordTokens = new List<string>();
+            var KeywordTokenKeys = new List<string> { "Q", "Series", "Movie", "Year" };
+            foreach (var key in KeywordTokenKeys)
+            {
+                var Value = (string)variables[".Query." + key];
+                if (!string.IsNullOrWhiteSpace(Value))
+                    KeywordTokens.Add(Value);
+            }
+
+            if (!string.IsNullOrWhiteSpace((string)variables[".Query.Episode"]))
+                KeywordTokens.Add((string)variables[".Query.Episode"]);
+            variables[".Query.Keywords"] = string.Join(" ", KeywordTokens);
+            variables[".Keywords"] = applyFilters((string)variables[".Query.Keywords"], Search.Keywordsfilters);
+
+            // TODO: prepare queries first and then send them parallel 
+            var SearchPaths = Search.Paths;
+            foreach (var SearchPath in SearchPaths)
+            {
+                // skip path if categories don't match
+                if (SearchPath.Categories != null && mappedCategories.Count > 0)
+                {
+                    var invertMatch = (SearchPath.Categories[0] == "!");
+                    var hasIntersect = mappedCategories.Intersect(SearchPath.Categories).Any();
+                    if (invertMatch)
+                        hasIntersect = !hasIntersect;
+                    if (!hasIntersect)
+                        continue;
+                }
+
+                // build search URL
+                // HttpUtility.UrlPathEncode seems to only encode spaces, we use UrlEncode and replace + with %20 as a workaround
+                var searchUrl = resolvePath(applyGoTemplateText(SearchPath.Path, variables, HttpUtility.UrlEncode).Replace("+", "%20")).AbsoluteUri;
+                var queryCollection = new List<KeyValuePair<string, string>>();
+                RequestType method = RequestType.GET;
+
+                if (String.Equals(SearchPath.Method, "post", StringComparison.OrdinalIgnoreCase))
+                {
+                    method = RequestType.POST;
+                }
+
+                var InputsList = new List<Dictionary<string, string>>();
+                if (SearchPath.Inheritinputs)
+                    InputsList.Add(Search.Inputs);
+                InputsList.Add(SearchPath.Inputs);
+
+                foreach (var Inputs in InputsList)
+                { 
+                    if (Inputs != null)
+                    {
+                        foreach (var Input in Inputs)
+                        {
+                            if (Input.Key == "$raw")
+                            {
+                                var rawStr = applyGoTemplateText(Input.Value, variables, HttpUtility.UrlEncode);
+                                foreach (string part in rawStr.Split('&'))
+                                {
+                                    var parts = part.Split(new char[] { '=' }, 2);
+                                    var key = parts[0];
+                                    if (key.Length == 0)
+                                        continue;
+                                    var value = "";
+                                    if (parts.Count() == 2)
+                                        value = parts[1];
+                                    queryCollection.Add(key, value);
+                                }
+                            }
+                            else
+                                queryCollection.Add(Input.Key, applyGoTemplateText(Input.Value, variables));
+                        }
+                    }
+                }
+
+                if (method == RequestType.GET)
+                {
+                    if (queryCollection.Count > 0)
+                        searchUrl += "?" + queryCollection.GetQueryString(Encoding);
+                }
+
+                // send HTTP request
+                WebClientStringResult response = null;
+                if (method == RequestType.POST)
                     response = await PostDataWithCookies(searchUrl, queryCollection);
                 else
                     response = await RequestStringWithCookies(searchUrl);
                 var results = response.Content;
                 try
                 {
-                    var SearchResultParser = new HtmlParser();
-                    var SearchResultDocument = SearchResultParser.Parse(results);
-
-                    // check if we need to login again
-                    var loginNeeded = CheckIfLoginIsNeeded(response, SearchResultDocument);
-                    if (loginNeeded)
-                    {
-                        logger.Info(string.Format("CardigannIndexer ({0}): Relogin required", ID));
-                        var LoginResult = await DoLogin();
-                        if (!LoginResult)
-                            throw new Exception(string.Format("Relogin failed"));
-                        await TestLogin();
-                        if (method == RequestType.POST)
-                            response = await PostDataWithCookies(searchUrl, queryCollection);
-                        else
-                            response = await RequestStringWithCookies(searchUrl);
-                        results = response.Content;
-                        SearchResultDocument = SearchResultParser.Parse(results);
-                    }
-
-                    checkForError(response, Definition.Search.Error);
-
-
-                    var RowsDom = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
-                    List<IElement> Rows = new List<IElement>();
-                    foreach (var RowDom in RowsDom)
-                    {
-                        Rows.Add(RowDom);
-                    }
-
-                    // merge following rows for After selector
-                    var After = Definition.Search.Rows.After;
-                    if (After > 0)
-                    {
-                        for (int i = 0; i < Rows.Count; i += 1)
-                        {
-                            var CurrentRow = Rows[i];
-                            for (int j = 0; j < After; j += 1)
-                            {
-                                var MergeRowIndex = i + j + 1;
-                                var MergeRow = Rows[MergeRowIndex];
-                                List<INode> MergeNodes = new List<INode>();
-                                foreach (var node in MergeRow.ChildNodes)
-                                {
-                                    MergeNodes.Add(node);
-                                }
-                                CurrentRow.Append(MergeNodes.ToArray());
-                            }
-                            Rows.RemoveRange(i + 1, After);
-                        }
-                    }
-
-                    foreach (var Row in Rows)
+                    var SearchResultParser = new HtmlParser();
+                    var SearchResultDocument = SearchResultParser.Parse(results);
+
+                    // check if we need to login again
+                    var loginNeeded = CheckIfLoginIsNeeded(response, SearchResultDocument);
+                    if (loginNeeded)
+                    {
+                        logger.Info(string.Format("CardigannIndexer ({0}): Relogin required", ID));
+                        var LoginResult = await DoLogin();
+                        if (!LoginResult)
+                            throw new Exception(string.Format("Relogin failed"));
+                        await TestLogin();
+                        if (method == RequestType.POST)
+                            response = await PostDataWithCookies(searchUrl, queryCollection);
+                        else
+                            response = await RequestStringWithCookies(searchUrl);
+                        results = response.Content;
+                        SearchResultDocument = SearchResultParser.Parse(results);
+                    }
+
+                    checkForError(response, Definition.Search.Error);
+
+
+                    var RowsDom = SearchResultDocument.QuerySelectorAll(Search.Rows.Selector);
+                    List<IElement> Rows = new List<IElement>();
+                    foreach (var RowDom in RowsDom)
+                    {
+                        Rows.Add(RowDom);
+                    }
+
+                    // merge following rows for After selector
+                    var After = Definition.Search.Rows.After;
+                    if (After > 0)
+                    {
+                        for (int i = 0; i < Rows.Count; i += 1)
+                        {
+                            var CurrentRow = Rows[i];
+                            for (int j = 0; j < After; j += 1)
+                            {
+                                var MergeRowIndex = i + j + 1;
+                                var MergeRow = Rows[MergeRowIndex];
+                                List<INode> MergeNodes = new List<INode>();
+                                foreach (var node in MergeRow.ChildNodes)
+                                {
+                                    MergeNodes.Add(node);
+                                }
+                                CurrentRow.Append(MergeNodes.ToArray());
+                            }
+                            Rows.RemoveRange(i + 1, After);
+                        }
+                    }
+
+                    foreach (var Row in Rows)
                     {
-                        try
-                        {
+                        try
+                        {
                             var release = new ReleaseInfo();
-                            release.MinimumRatio = 1;
+                            release.MinimumRatio = 1;
                             release.MinimumSeedTime = 48 * 60 * 60;
 
                             // Parse fields
-                            foreach (var Field in Search.Fields)
-                            {
-                                var FieldParts = Field.Key.Split('|');
-                                var FieldName = FieldParts[0];
-                                var FieldModifiers = new List<string>();
-                                for (var i = 1; i < FieldParts.Length; i++)
-                                    FieldModifiers.Add(FieldParts[i]);
-
-                                string value = null;
-                                var variablesKey = ".Result." + FieldName;
-                                try
-                                {
-                                    value = handleSelector(Field.Value, Row, variables);
-                                    switch (FieldName)
-                                    {
+                            foreach (var Field in Search.Fields)
+                            {
+                                var FieldParts = Field.Key.Split('|');
+                                var FieldName = FieldParts[0];
+                                var FieldModifiers = new List<string>();
+                                for (var i = 1; i < FieldParts.Length; i++)
+                                    FieldModifiers.Add(FieldParts[i]);
+
+                                string value = null;
+                                var variablesKey = ".Result." + FieldName;
+                                try
+                                {
+                                    value = handleSelector(Field.Value, Row, variables);
+                                    switch (FieldName)
+                                    {
                                         case "download":
-                                            if (string.IsNullOrEmpty(value))
-                                            {
-                                                value = null;
-                                                release.Link = null;
-                                                break;
+                                            if (string.IsNullOrEmpty(value))
+                                            {
+                                                value = null;
+                                                release.Link = null;
+                                                break;
+                                            }
+                                            if (value.StartsWith("magnet:"))
+                                            {
+                                                release.MagnetUri = new Uri(value);
+                                                //release.Link = release.MagnetUri;
+                                                value = release.MagnetUri.ToString();
+                                            }
+                                            else
+                                            {
+                                                release.Link = resolvePath(value);
+                                                value = release.Link.ToString();
                                             }
-                                            if (value.StartsWith("magnet:"))
-                                            {
-                                                release.MagnetUri = new Uri(value);
-                                                //release.Link = release.MagnetUri;
-                                                value = release.MagnetUri.ToString();
-                                            }
-                                            else
-                                            {
-                                                release.Link = resolvePath(value);
-                                                value = release.Link.ToString();
-                                            }
-                                            break;
-                                        case "magnet":
-                                            release.MagnetUri = new Uri(value);
-                                            value = release.MagnetUri.ToString();
-                                            break;
+                                            break;
+                                        case "magnet":
+                                            release.MagnetUri = new Uri(value);
+                                            value = release.MagnetUri.ToString();
+                                            break;
                                         case "details":
-                                            var url = resolvePath(value);
-                                            release.Guid = url;
-                                            release.Comments = url;
-                                            if (release.Guid == null)
-                                                release.Guid = url;
-                                            value = url.ToString();
-                                            break;
+                                            var url = resolvePath(value);
+                                            release.Guid = url;
+                                            release.Comments = url;
+                                            if (release.Guid == null)
+                                                release.Guid = url;
+                                            value = url.ToString();
+                                            break;
                                         case "comments":
-                                            var CommentsUrl = resolvePath(value);
-                                            if (release.Comments == null)
-                                                release.Comments = CommentsUrl;
-                                            if (release.Guid == null)
-                                                release.Guid = CommentsUrl;
-                                            value = CommentsUrl.ToString();
-                                            break;
+                                            var CommentsUrl = resolvePath(value);
+                                            if (release.Comments == null)
+                                                release.Comments = CommentsUrl;
+                                            if (release.Guid == null)
+                                                release.Guid = CommentsUrl;
+                                            value = CommentsUrl.ToString();
+                                            break;
                                         case "title":
                                             if (FieldModifiers.Contains("append"))
                                                 release.Title += value;
                                             else
-                                                release.Title = value;
-                                            value = release.Title;
-                                            break;
+                                                release.Title = value;
+                                            value = release.Title;
+                                            break;
                                         case "description":
                                             if (FieldModifiers.Contains("append"))
                                                 release.Description += value;
                                             else
                                                 release.Description = value;
                                             value = release.Description;
-                                            break;
+                                            break;
                                         case "category":
-                                            release.Category = MapTrackerCatToNewznab(value);
-                                            value = release.Category.ToString();
-                                            break;
+                                            release.Category = MapTrackerCatToNewznab(value);
+                                            value = release.Category.ToString();
+                                            break;
                                         case "size":
-                                            release.Size = ReleaseInfo.GetBytes(value);
-                                            value = release.Size.ToString();
-                                            break;
+                                            release.Size = ReleaseInfo.GetBytes(value);
+                                            value = release.Size.ToString();
+                                            break;
                                         case "leechers":
                                             var Leechers = ParseUtil.CoerceInt(value);
-                                            if (release.Peers == null)
-                                                release.Peers = Leechers;
-                                            else
-                                                release.Peers += Leechers;
-                                            value = Leechers.ToString();
-                                            break;
+                                            if (release.Peers == null)
+                                                release.Peers = Leechers;
+                                            else
+                                                release.Peers += Leechers;
+                                            value = Leechers.ToString();
+                                            break;
                                         case "seeders":
-                                            release.Seeders = ParseUtil.CoerceInt(value);
-                                            if (release.Peers == null)
-                                                release.Peers = release.Seeders;
-                                            else
-                                                release.Peers += release.Seeders;
-                                            value = release.Seeders.ToString();
-                                            break;
+                                            release.Seeders = ParseUtil.CoerceInt(value);
+                                            if (release.Peers == null)
+                                                release.Peers = release.Seeders;
+                                            else
+                                                release.Peers += release.Seeders;
+                                            value = release.Seeders.ToString();
+                                            break;
                                         case "date":
-                                            release.PublishDate = DateTimeUtil.FromUnknown(value);
-                                            value = release.PublishDate.ToString(DateTimeUtil.RFC1123ZPattern);
-                                            break;
+                                            release.PublishDate = DateTimeUtil.FromUnknown(value);
+                                            value = release.PublishDate.ToString(DateTimeUtil.RFC1123ZPattern);
+                                            break;
                                         case "files":
-                                            release.Files = ParseUtil.CoerceLong(value);
-                                            value = release.Files.ToString();
-                                            break;
+                                            release.Files = ParseUtil.CoerceLong(value);
+                                            value = release.Files.ToString();
+                                            break;
                                         case "grabs":
-                                            release.Grabs = ParseUtil.CoerceLong(value);
-                                            value = release.Grabs.ToString();
-                                            break;
+                                            release.Grabs = ParseUtil.CoerceLong(value);
+                                            value = release.Grabs.ToString();
+                                            break;
                                         case "downloadvolumefactor":
-                                            release.DownloadVolumeFactor = ParseUtil.CoerceDouble(value);
-                                            value = release.DownloadVolumeFactor.ToString();
-                                            break;
+                                            release.DownloadVolumeFactor = ParseUtil.CoerceDouble(value);
+                                            value = release.DownloadVolumeFactor.ToString();
+                                            break;
                                         case "uploadvolumefactor":
-                                            release.UploadVolumeFactor = ParseUtil.CoerceDouble(value);
-                                            value = release.UploadVolumeFactor.ToString();
-                                            break;
+                                            release.UploadVolumeFactor = ParseUtil.CoerceDouble(value);
+                                            value = release.UploadVolumeFactor.ToString();
+                                            break;
                                         case "minimumratio":
-                                            release.MinimumRatio = ParseUtil.CoerceDouble(value);
-                                            value = release.MinimumRatio.ToString();
-                                            break;
+                                            release.MinimumRatio = ParseUtil.CoerceDouble(value);
+                                            value = release.MinimumRatio.ToString();
+                                            break;
                                         case "minimumseedtime":
-                                            release.MinimumSeedTime = ParseUtil.CoerceLong(value);
-                                            value = release.MinimumSeedTime.ToString();
-                                            break;
+                                            release.MinimumSeedTime = ParseUtil.CoerceLong(value);
+                                            value = release.MinimumSeedTime.ToString();
+                                            break;
                                         case "imdb":
-                                            release.Imdb = ParseUtil.GetLongFromString(value);
-                                            value = release.Imdb.ToString();
-                                            break;
+                                            release.Imdb = ParseUtil.GetLongFromString(value);
+                                            value = release.Imdb.ToString();
+                                            break;
                                         case "rageid":
-                                            Regex RageIDRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
-                                            var RageIDMatch = RageIDRegEx.Match(value);
-                                            var RageID = RageIDMatch.Groups[1].Value;
-                                            release.RageID = ParseUtil.CoerceLong(RageID);
-                                            value = release.RageID.ToString();
-                                            break;
+                                            Regex RageIDRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
+                                            var RageIDMatch = RageIDRegEx.Match(value);
+                                            var RageID = RageIDMatch.Groups[1].Value;
+                                            release.RageID = ParseUtil.CoerceLong(RageID);
+                                            value = release.RageID.ToString();
+                                            break;
                                         case "tvdbid":
-                                            Regex TVDBIdRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
-                                            var TVDBIdMatch = TVDBIdRegEx.Match(value);
-                                            var TVDBId = TVDBIdMatch.Groups[1].Value;
-                                            release.TVDBId = ParseUtil.CoerceLong(TVDBId);
-                                            value = release.TVDBId.ToString();
-                                            break;
+                                            Regex TVDBIdRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
+                                            var TVDBIdMatch = TVDBIdRegEx.Match(value);
+                                            var TVDBId = TVDBIdMatch.Groups[1].Value;
+                                            release.TVDBId = ParseUtil.CoerceLong(TVDBId);
+                                            value = release.TVDBId.ToString();
+                                            break;
                                         case "banner":
                                             if(!string.IsNullOrWhiteSpace(value)) { 
-                                                var bannerurl = resolvePath(value);
-                                                release.BannerUrl = bannerurl;
-                                            }
-                                            value = release.BannerUrl.ToString();
-                                            break;
-                                        default:
-                                            break;
-                                    }
-                                    variables[variablesKey] = value;
-                                }
-                                catch (Exception ex)
-                                {
-                                    if (!variables.ContainsKey(variablesKey))
-                                        variables[variablesKey] = null;
-                                    if (OptionalFileds.Contains(Field.Key) || FieldModifiers.Contains("optional") || Field.Value.Optional)
-                                        continue;
-                                    throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, (value == null ? "<null>" : value), ex.Message));
-                                }
-                            }
-
-                            var Filters = Definition.Search.Rows.Filters;
-                            var SkipRelease = false;
-                            if (Filters != null)
-                            {
-                                foreach (filterBlock Filter in Filters)
-                                {
-                                    switch (Filter.Name)
-                                    {
-                                        case "andmatch":
-                                            int CharacterLimit = -1;
-                                            if (Filter.Args != null)
-                                                CharacterLimit = int.Parse(Filter.Args);
-
-                                            if (query.ImdbID != null && TorznabCaps.SupportsImdbSearch)
-                                                break; // skip andmatch filter for imdb searches
-
-                                            if (!query.MatchQueryStringAND(release.Title, CharacterLimit))
-                                            {
-                                                logger.Debug(string.Format("CardigannIndexer ({0}): skipping {1} (andmatch filter)", ID, release.Title));
-                                                SkipRelease = true;
-                                            }
-                                            break;
-                                        case "strdump":
-                                            // for debugging
-                                            logger.Info(string.Format("CardigannIndexer ({0}): row strdump: {1}", ID, Row.ToHtmlPretty()));
-                                            break;
-                                        default:
-                                            logger.Error(string.Format("CardigannIndexer ({0}): Unsupported rows filter: {1}", ID, Filter.Name));
-                                            break;
-                                    }
-                                }
-                            }
-
-                            if (SkipRelease)
-                                continue;
-
-                            // if DateHeaders is set go through the previous rows and look for the header selector
-                            var DateHeaders = Definition.Search.Rows.Dateheaders;
-                            if (release.PublishDate == DateTime.MinValue && DateHeaders != null)
-                            {
-                                var PrevRow = Row.PreviousElementSibling;
-                                string value = null;
-                                while (PrevRow != null)
-                                {
-                                    try
-                                    {
-                                        value = handleSelector(DateHeaders, PrevRow);
-                                        break;
-                                    }
-                                    catch (Exception)
-                                    {
-                                        // do nothing
-                                    }
-                                    PrevRow = PrevRow.PreviousElementSibling;
-                                }
-                            
-                                if (value == null && DateHeaders.Optional == false)
-                                    throw new Exception(string.Format("No date header row found for {0}", release.ToString()));
-                                if (value != null)
-                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
-                            }
-
-                            releases.Add(release);
-                        }
-                        catch (Exception ex)
-                        {
-                            logger.Error(string.Format("CardigannIndexer ({0}): Error while parsing row '{1}':\n\n{2}", ID, Row.ToHtmlPretty(), ex));
-                        }
+                                                var bannerurl = resolvePath(value);
+                                                release.BannerUrl = bannerurl;
+                                            }
+                                            value = release.BannerUrl.ToString();
+                                            break;
+                                        default:
+                                            break;
+                                    }
+                                    variables[variablesKey] = value;
+                                }
+                                catch (Exception ex)
+                                {
+                                    if (!variables.ContainsKey(variablesKey))
+                                        variables[variablesKey] = null;
+                                    if (OptionalFileds.Contains(Field.Key) || FieldModifiers.Contains("optional") || Field.Value.Optional)
+                                        continue;
+                                    throw new Exception(string.Format("Error while parsing field={0}, selector={1}, value={2}: {3}", Field.Key, Field.Value.Selector, (value == null ? "<null>" : value), ex.Message));
+                                }
+                            }
+
+                            var Filters = Definition.Search.Rows.Filters;
+                            var SkipRelease = false;
+                            if (Filters != null)
+                            {
+                                foreach (filterBlock Filter in Filters)
+                                {
+                                    switch (Filter.Name)
+                                    {
+                                        case "andmatch":
+                                            int CharacterLimit = -1;
+                                            if (Filter.Args != null)
+                                                CharacterLimit = int.Parse(Filter.Args);
+
+                                            if (query.ImdbID != null && TorznabCaps.SupportsImdbSearch)
+                                                break; // skip andmatch filter for imdb searches
+
+                                            if (!query.MatchQueryStringAND(release.Title, CharacterLimit))
+                                            {
+                                                logger.Debug(string.Format("CardigannIndexer ({0}): skipping {1} (andmatch filter)", ID, release.Title));
+                                                SkipRelease = true;
+                                            }
+                                            break;
+                                        case "strdump":
+                                            // for debugging
+                                            logger.Info(string.Format("CardigannIndexer ({0}): row strdump: {1}", ID, Row.ToHtmlPretty()));
+                                            break;
+                                        default:
+                                            logger.Error(string.Format("CardigannIndexer ({0}): Unsupported rows filter: {1}", ID, Filter.Name));
+                                            break;
+                                    }
+                                }
+                            }
+
+                            if (SkipRelease)
+                                continue;
+
+                            // if DateHeaders is set go through the previous rows and look for the header selector
+                            var DateHeaders = Definition.Search.Rows.Dateheaders;
+                            if (release.PublishDate == DateTime.MinValue && DateHeaders != null)
+                            {
+                                var PrevRow = Row.PreviousElementSibling;
+                                string value = null;
+                                while (PrevRow != null)
+                                {
+                                    try
+                                    {
+                                        value = handleSelector(DateHeaders, PrevRow);
+                                        break;
+                                    }
+                                    catch (Exception)
+                                    {
+                                        // do nothing
+                                    }
+                                    PrevRow = PrevRow.PreviousElementSibling;
+                                }
+                            
+                                if (value == null && DateHeaders.Optional == false)
+                                    throw new Exception(string.Format("No date header row found for {0}", release.ToString()));
+                                if (value != null)
+                                    release.PublishDate = DateTimeUtil.FromUnknown(value);
+                            }
+
+                            releases.Add(release);
+                        }
+                        catch (Exception ex)
+                        {
+                            logger.Error(string.Format("CardigannIndexer ({0}): Error while parsing row '{1}':\n\n{2}", ID, Row.ToHtmlPretty(), ex));
+                        }
                     }
                 }
                 catch (Exception ex)
                 {
                     OnParseError(results, ex);
-                }
+                }
             }
             return releases;
         }
 
-        protected async Task<WebClientByteResult> handleRequest(requestBlock request, Dictionary<string, object> variables = null, string referer = null)
-        {
-            var requestLinkStr = resolvePath(applyGoTemplateText(request.Path, variables)).ToString();
-
-            Dictionary<string, string> pairs = null;
-            var queryCollection = new NameValueCollection();
-
-            RequestType method = RequestType.GET;
-            if (String.Equals(request.Method, "post", StringComparison.OrdinalIgnoreCase))
-            {
-                method = RequestType.POST;
-                pairs = new Dictionary<string, string>();
-            }
-
-            foreach (var Input in request.Inputs)
-            {
-                var value = applyGoTemplateText(Input.Value, variables);
-                if (method == RequestType.GET)
-                    queryCollection.Add(Input.Key, value);
-                else if (method == RequestType.POST)
-                    pairs.Add(Input.Key, value);
-            }
-
-            if (queryCollection.Count > 0)
-            {
-                if (!requestLinkStr.Contains("?"))
-                    requestLinkStr += "?" + queryCollection.GetQueryString(Encoding).Substring(1);
-                else
-                    requestLinkStr += queryCollection.GetQueryString(Encoding);
-            }
-
-            var response = await RequestBytesWithCookiesAndRetry(requestLinkStr, null, method, referer, pairs);
-            logger.Debug($"CardigannIndexer ({ID}): handleRequest() remote server returned {response.Status.ToString()}" + (response.IsRedirect ? " => " + response.RedirectingTo : ""));
-            return response;
+        protected async Task<WebClientByteResult> handleRequest(requestBlock request, Dictionary<string, object> variables = null, string referer = null)
+        {
+            var requestLinkStr = resolvePath(applyGoTemplateText(request.Path, variables)).ToString();
+
+            Dictionary<string, string> pairs = null;
+            var queryCollection = new NameValueCollection();
+
+            RequestType method = RequestType.GET;
+            if (String.Equals(request.Method, "post", StringComparison.OrdinalIgnoreCase))
+            {
+                method = RequestType.POST;
+                pairs = new Dictionary<string, string>();
+            }
+
+            foreach (var Input in request.Inputs)
+            {
+                var value = applyGoTemplateText(Input.Value, variables);
+                if (method == RequestType.GET)
+                    queryCollection.Add(Input.Key, value);
+                else if (method == RequestType.POST)
+                    pairs.Add(Input.Key, value);
+            }
+
+            if (queryCollection.Count > 0)
+            {
+                if (!requestLinkStr.Contains("?"))
+                    requestLinkStr += "?" + queryCollection.GetQueryString(Encoding).Substring(1);
+                else
+                    requestLinkStr += queryCollection.GetQueryString(Encoding);
+            }
+
+            var response = await RequestBytesWithCookiesAndRetry(requestLinkStr, null, method, referer, pairs);
+            logger.Debug($"CardigannIndexer ({ID}): handleRequest() remote server returned {response.Status.ToString()}" + (response.IsRedirect ? " => " + response.RedirectingTo : ""));
+            return response;
         }
 
-        protected IDictionary<string, object> AddTemplateVariablesFromUri(IDictionary<string, object> variables, Uri uri, string prefix = "")
-        {
-            variables[prefix + ".AbsoluteUri"] = uri.AbsoluteUri;
-            variables[prefix + ".AbsolutePath"] = uri.AbsolutePath;
-            variables[prefix + ".Scheme"] = uri.Scheme;
-            variables[prefix + ".Host"] = uri.Host;
-            variables[prefix + ".Port"] = uri.Port.ToString();
-            variables[prefix + ".PathAndQuery"] = uri.PathAndQuery;
-            variables[prefix + ".Query"] = uri.Query;
-            var queryString = HttpUtility.ParseQueryString(uri.Query);
-            foreach (string key in queryString.Keys)
-            {
-                variables[prefix + ".Query." + key] = queryString.Get(key);
-            }
-            return variables;
+        protected IDictionary<string, object> AddTemplateVariablesFromUri(IDictionary<string, object> variables, Uri uri, string prefix = "")
+        {
+            variables[prefix + ".AbsoluteUri"] = uri.AbsoluteUri;
+            variables[prefix + ".AbsolutePath"] = uri.AbsolutePath;
+            variables[prefix + ".Scheme"] = uri.Scheme;
+            variables[prefix + ".Host"] = uri.Host;
+            variables[prefix + ".Port"] = uri.Port.ToString();
+            variables[prefix + ".PathAndQuery"] = uri.PathAndQuery;
+            variables[prefix + ".Query"] = uri.Query;
+            var queryString = HttpUtility.ParseQueryString(uri.Query);
+            foreach (string key in queryString.Keys)
+            {
+                variables[prefix + ".Query." + key] = queryString.Get(key);
+            }
+            return variables;
         }
 
-        public override async Task<byte[]> Download(Uri link)
-        {
-            var method = RequestType.GET;
-            if (Definition.Download != null)
-            {
-                var Download = Definition.Download;
-                if (Download.Before != null)
-                {
-                    var beforeVariables = getTemplateVariablesFromConfigData();
-                    AddTemplateVariablesFromUri(beforeVariables, link, ".DownloadUri");
-                    var beforeresult = await handleRequest(Download.Before, beforeVariables, link.ToString());
-                }
-                if (Download.Method != null)
-                {
-                    if (Download.Method == "post")
-                        method = RequestType.POST;
-                }
-                if (Download.Selector != null)
-                {
-                    var response = await RequestStringWithCookies(link.ToString());
-                    if (response.IsRedirect)
-                        response = await RequestStringWithCookies(response.RedirectingTo);
-                    var results = response.Content;
-                    var SearchResultParser = new HtmlParser();
-                    var SearchResultDocument = SearchResultParser.Parse(results);
-                    var DlUri = SearchResultDocument.QuerySelector(Download.Selector);
-                    if (DlUri != null)
-                    {
-                        logger.Debug(string.Format("CardigannIndexer ({0}): Download selector {1} matched:{2}", ID, Download.Selector, DlUri.ToHtmlPretty()));
-                        var href = DlUri.GetAttribute("href");
-                        link = resolvePath(href);
-                    }
-                    else
-                    {
-                        logger.Error(string.Format("CardigannIndexer ({0}): Download selector {1} didn't match:\n{2}", ID, Download.Selector, results));
-                        throw new Exception(string.Format("Download selector {0} didn't match", Download.Selector));
-                    }
-                }
-            }
-            return await base.Download(link, method);
+        public override async Task<byte[]> Download(Uri link)
+        {
+            var method = RequestType.GET;
+            if (Definition.Download != null)
+            {
+                var Download = Definition.Download;
+                if (Download.Before != null)
+                {
+                    var beforeVariables = getTemplateVariablesFromConfigData();
+                    AddTemplateVariablesFromUri(beforeVariables, link, ".DownloadUri");
+                    var beforeresult = await handleRequest(Download.Before, beforeVariables, link.ToString());
+                }
+                if (Download.Method != null)
+                {
+                    if (Download.Method == "post")
+                        method = RequestType.POST;
+                }
+                if (Download.Selector != null)
+                {
+                    var response = await RequestStringWithCookies(link.ToString());
+                    if (response.IsRedirect)
+                        response = await RequestStringWithCookies(response.RedirectingTo);
+                    var results = response.Content;
+                    var SearchResultParser = new HtmlParser();
+                    var SearchResultDocument = SearchResultParser.Parse(results);
+                    var DlUri = SearchResultDocument.QuerySelector(Download.Selector);
+                    if (DlUri != null)
+                    {
+                        logger.Debug(string.Format("CardigannIndexer ({0}): Download selector {1} matched:{2}", ID, Download.Selector, DlUri.ToHtmlPretty()));
+                        var href = DlUri.GetAttribute("href");
+                        link = resolvePath(href);
+                    }
+                    else
+                    {
+                        logger.Error(string.Format("CardigannIndexer ({0}): Download selector {1} didn't match:\n{2}", ID, Download.Selector, results));
+                        throw new Exception(string.Format("Download selector {0} didn't match", Download.Selector));
+                    }
+                }
+            }
+            return await base.Download(link, method);
         }
     }
 }
diff --git a/src/Jackett/Indexers/DanishBits.cs b/src/Jackett/Indexers/DanishBits.cs
index 316501ebb42e6fc24c5aa77ce96b4972c4cda479..a6f9a834ad00689604c263a13a0c0693ee203007 100644
--- a/src/Jackett/Indexers/DanishBits.cs
+++ b/src/Jackett/Indexers/DanishBits.cs
@@ -14,8 +14,8 @@ using System.Threading.Tasks;
 using System.Web;
 using CsQuery.ExtensionMethods;
 using Jackett.Models.IndexerConfig;
-using Jackett.Utils;
-
+using Jackett.Utils;
+
 namespace Jackett.Indexers
 {
     public class DanishBits : BaseIndexer, IIndexer
@@ -274,15 +274,15 @@ namespace Jackett.Indexers
                     var Grabs = qRow.Find("td:nth-child(6)");
                     release.Grabs = ParseUtil.CoerceLong(Grabs.Text());
 
-                    if (qRow.Find("span.freeleech, img[src=\"/static/common/torrents/gratis.png\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("span.freeleech, img[src=\"/static/common/torrents/gratis.png\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
-                    if (qRow.Find("img[src=\"/static/common/torrents/toxupload.png\"]").Length >= 1)
-                        release.UploadVolumeFactor = 2;
+                        release.DownloadVolumeFactor = 1;
+
+                    if (qRow.Find("img[src=\"/static/common/torrents/toxupload.png\"]").Length >= 1)
+                        release.UploadVolumeFactor = 2;
                     else
-                        release.UploadVolumeFactor = 1;
+                        release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
                 }
diff --git a/src/Jackett/Indexers/Demonoid.cs b/src/Jackett/Indexers/Demonoid.cs
index 785965b46837688667c59718070a63efdaad1d0e..2725bd91c31ea3c0be8923aa2cac2ac3fc128e42 100644
--- a/src/Jackett/Indexers/Demonoid.cs
+++ b/src/Jackett/Indexers/Demonoid.cs
@@ -1,173 +1,173 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-
-namespace Jackett.Indexers
-{
-    public class Demonoid : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "account_handler.php"; } }
-        private string SearchUrl { get { return SiteLink + "files/?category={0}&subcategory=All&quality=All&seeded=2&to=1&query={1}&external=2"; } }
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public Demonoid(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
-            : base(name: "Demonoid",
-                description: "Demonoid",
-                link: "https://www.demonoid.pw/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(5, TorznabCatType.PC0day, "Applications");
-            AddCategoryMapping(17, TorznabCatType.AudioAudiobook, "Audio Books");
-            AddCategoryMapping(11, TorznabCatType.Books, "Books");
-            AddCategoryMapping(10, TorznabCatType.BooksComics, "Comics");
-            AddCategoryMapping(4, TorznabCatType.PCGames, "Games");
-            AddCategoryMapping(9, TorznabCatType.TVAnime, "Japanese Anime");
-            AddCategoryMapping(6, TorznabCatType.Other, "Miscellaneous");
-            AddCategoryMapping(1, TorznabCatType.Movies, "Movies");
-            AddCategoryMapping(2, TorznabCatType.Audio, "Music");
-            AddCategoryMapping(13, TorznabCatType.AudioVideo, "Music Videos");
-            AddCategoryMapping(8, TorznabCatType.Other, "Pictures");
-            AddCategoryMapping(3, TorznabCatType.TV, "TV");
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "nickname", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "returnpath", "/" },
-                { "withq", "0" },
-                { "Submit", "Submit" }
-            };
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, SiteLink);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Cookies.Contains("uid="), () =>
-            {
-                CQ dom = result.Content;
-                string errorMessage = dom["form[id='bb_code_form']"].Parent().Find("font[class='red']").Text();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var trackerCats = MapTorznabCapsToTrackers(query);
-            var cat = (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0");
-            var episodeSearchUrl = string.Format(SearchUrl, cat, HttpUtility.UrlEncode(query.GetQueryString()));
-            var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
-
-            
-            if (results.Content.Contains("No torrents found"))
-            {
-                return releases;
-            }
-
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom[".ctable_content_no_pad > table > tbody > tr"].ToArray();
-                DateTime lastDateTime = default(DateTime);
-                for (var i = 0; i < rows.Length; i++)
-                {
-                    var rowA = rows[i];
-                    var rAlign = rowA.Attributes["align"];
-                    if (rAlign == "right" || rAlign == "center")
-                        continue;
-                    if (rAlign == "left")
-                    {
-                        // ex: "Monday, Jun 01, 2015", "Monday, Aug 03, 2015"
-                        var dateStr = rowA.Cq().Text().Trim().Replace("Added on ", "");
-                        if (dateStr.ToLowerInvariant().Contains("today"))
-                            lastDateTime = DateTime.Now;
-                        else
-                            lastDateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dddd, MMM dd, yyyy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime();
-                        continue;
-                    }
-                    if (rowA.ChildElements.Count() < 2)
-                        continue;
-
-                    var rowB = rows[++i];
-
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-
-                    release.PublishDate = lastDateTime;
-
-                    var catUrl = rowA.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href");
-                    var catId = HttpUtility.ParseQueryString(catUrl).Get("category");
-                    release.Category = MapTrackerCatToNewznab(catId);
-
-                    var qLink = rowA.ChildElements.ElementAt(1).FirstElementChild.Cq();
-                    release.Title = qLink.Text().Trim();
-                    release.Description = rowB.ChildElements.ElementAt(0).Cq().Text();
-
-                    if (release.Category != null && release.Category.Contains(TorznabCatType.Audio.ID))
-                    {
-                        if (release.Description.Contains("Lossless"))
-                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
-                        else if (release.Description.Contains("MP3"))
-                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
-                        else
-                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
-                    }
-
-                    release.Comments = new Uri(SiteLink + qLink.Attr("href"));
-                    release.Guid = release.Comments;
-
-                    var qDownload = rowB.ChildElements.ElementAt(2).ChildElements.ElementAt(0).Cq();
-                    release.Link = new Uri(SiteLink + qDownload.Attr("href"));
-
-                    var sizeStr = rowB.ChildElements.ElementAt(3).Cq().Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text());
-                    release.Peers = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace Jackett.Indexers
+{
+    public class Demonoid : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "account_handler.php"; } }
+        private string SearchUrl { get { return SiteLink + "files/?category={0}&subcategory=All&quality=All&seeded=2&to=1&query={1}&external=2"; } }
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public Demonoid(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
+            : base(name: "Demonoid",
+                description: "Demonoid",
+                link: "https://www.demonoid.pw/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(5, TorznabCatType.PC0day, "Applications");
+            AddCategoryMapping(17, TorznabCatType.AudioAudiobook, "Audio Books");
+            AddCategoryMapping(11, TorznabCatType.Books, "Books");
+            AddCategoryMapping(10, TorznabCatType.BooksComics, "Comics");
+            AddCategoryMapping(4, TorznabCatType.PCGames, "Games");
+            AddCategoryMapping(9, TorznabCatType.TVAnime, "Japanese Anime");
+            AddCategoryMapping(6, TorznabCatType.Other, "Miscellaneous");
+            AddCategoryMapping(1, TorznabCatType.Movies, "Movies");
+            AddCategoryMapping(2, TorznabCatType.Audio, "Music");
+            AddCategoryMapping(13, TorznabCatType.AudioVideo, "Music Videos");
+            AddCategoryMapping(8, TorznabCatType.Other, "Pictures");
+            AddCategoryMapping(3, TorznabCatType.TV, "TV");
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "nickname", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "returnpath", "/" },
+                { "withq", "0" },
+                { "Submit", "Submit" }
+            };
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, SiteLink);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Cookies.Contains("uid="), () =>
+            {
+                CQ dom = result.Content;
+                string errorMessage = dom["form[id='bb_code_form']"].Parent().Find("font[class='red']").Text();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var trackerCats = MapTorznabCapsToTrackers(query);
+            var cat = (trackerCats.Count == 1 ? trackerCats.ElementAt(0) : "0");
+            var episodeSearchUrl = string.Format(SearchUrl, cat, HttpUtility.UrlEncode(query.GetQueryString()));
+            var results = await RequestStringWithCookiesAndRetry(episodeSearchUrl);
+
+            
+            if (results.Content.Contains("No torrents found"))
+            {
+                return releases;
+            }
+
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom[".ctable_content_no_pad > table > tbody > tr"].ToArray();
+                DateTime lastDateTime = default(DateTime);
+                for (var i = 0; i < rows.Length; i++)
+                {
+                    var rowA = rows[i];
+                    var rAlign = rowA.Attributes["align"];
+                    if (rAlign == "right" || rAlign == "center")
+                        continue;
+                    if (rAlign == "left")
+                    {
+                        // ex: "Monday, Jun 01, 2015", "Monday, Aug 03, 2015"
+                        var dateStr = rowA.Cq().Text().Trim().Replace("Added on ", "");
+                        if (dateStr.ToLowerInvariant().Contains("today"))
+                            lastDateTime = DateTime.Now;
+                        else
+                            lastDateTime = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dddd, MMM dd, yyyy", CultureInfo.InvariantCulture), DateTimeKind.Utc).ToLocalTime();
+                        continue;
+                    }
+                    if (rowA.ChildElements.Count() < 2)
+                        continue;
+
+                    var rowB = rows[++i];
+
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+
+                    release.PublishDate = lastDateTime;
+
+                    var catUrl = rowA.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href");
+                    var catId = HttpUtility.ParseQueryString(catUrl).Get("category");
+                    release.Category = MapTrackerCatToNewznab(catId);
+
+                    var qLink = rowA.ChildElements.ElementAt(1).FirstElementChild.Cq();
+                    release.Title = qLink.Text().Trim();
+                    release.Description = rowB.ChildElements.ElementAt(0).Cq().Text();
+
+                    if (release.Category != null && release.Category.Contains(TorznabCatType.Audio.ID))
+                    {
+                        if (release.Description.Contains("Lossless"))
+                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
+                        else if (release.Description.Contains("MP3"))
+                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
+                        else
+                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
+                    }
+
+                    release.Comments = new Uri(SiteLink + qLink.Attr("href"));
+                    release.Guid = release.Comments;
+
+                    var qDownload = rowB.ChildElements.ElementAt(2).ChildElements.ElementAt(0).Cq();
+                    release.Link = new Uri(SiteLink + qDownload.Attr("href"));
+
+                    var sizeStr = rowB.ChildElements.ElementAt(3).Cq().Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text());
+                    release.Peers = ParseUtil.CoerceInt(rowB.ChildElements.ElementAt(6).Cq().Text()) + release.Seeders;
+
                     var grabs = rowB.Cq().Find("td:nth-child(6)").Text();
-                    release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                    release.DownloadVolumeFactor = 0; // ratioless
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-            return releases;
-        }
-    }
-}
+                    release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                    release.DownloadVolumeFactor = 0; // ratioless
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/DigitalHive.cs b/src/Jackett/Indexers/DigitalHive.cs
index 570925c445bbcba2bd43a850d5c5c352ba21006b..e9689e5e0cc58607b4bd4baa4a6fb8113314c799 100644
--- a/src/Jackett/Indexers/DigitalHive.cs
+++ b/src/Jackett/Indexers/DigitalHive.cs
@@ -1,234 +1,234 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text.RegularExpressions;
-using System.IO;
-
-namespace Jackett.Indexers
-{
-    public class DigitalHive : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "login.php?returnto=%2F"; } }
-        private string AjaxLoginUrl { get { return SiteLink + "takelogin.php"; } }
-
-        new ConfigurationDataRecaptchaLogin configData
-        {
-            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public DigitalHive(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "DigitalHive",
-                description: "DigitalHive is one of the oldest general trackers",
-                link: "https://www.digitalhive.org/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataRecaptchaLogin())
-        {
-            Encoding = Encoding.GetEncoding("iso-8859-1");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(0, TorznabCatType.Other);
-            AddCategoryMapping(48, TorznabCatType.Other); // 0Day
-            AddCategoryMapping(56, TorznabCatType.XXXImageset); // 0Day-Imagesets
-            AddCategoryMapping(6, TorznabCatType.Audio); // 0Day-Music
-            AddCategoryMapping(51, TorznabCatType.XXX); // 0Day-XXX
-            AddCategoryMapping(2, TorznabCatType.TVAnime); // Anime
-            AddCategoryMapping(59, TorznabCatType.MoviesBluRay); // BluRay
-            AddCategoryMapping(40, TorznabCatType.TVDocumentary); // Documentary
-            AddCategoryMapping(20, TorznabCatType.MoviesDVD); // DVD-R
-            AddCategoryMapping(25, TorznabCatType.BooksEbook); // Ebooks
-            AddCategoryMapping(38, TorznabCatType.PCPhoneIOS); // HandHeld
-            AddCategoryMapping(38, TorznabCatType.PCPhoneAndroid); // HandHeld
-            AddCategoryMapping(38, TorznabCatType.PCPhoneOther); // HandHeld
-            AddCategoryMapping(37, TorznabCatType.Other); // Kids Stuff
-            AddCategoryMapping(23, TorznabCatType.PC); // Linux
-            AddCategoryMapping(24, TorznabCatType.PCMac); // Mac
-            AddCategoryMapping(22, TorznabCatType.OtherMisc); // Misc
-            AddCategoryMapping(35, TorznabCatType.MoviesOther); // Movie Pack
-            AddCategoryMapping(36, TorznabCatType.MoviesHD); // Movie-HD
-            AddCategoryMapping(19, TorznabCatType.MoviesSD); // Movie-SD
-            AddCategoryMapping(50, TorznabCatType.Audio); // Music
-            AddCategoryMapping(53, TorznabCatType.AudioLossless); // Music-FLAC
-            AddCategoryMapping(49, TorznabCatType.AudioVideo); // MVID
-            AddCategoryMapping(1, TorznabCatType.PC); // PC Apps
-            AddCategoryMapping(4, TorznabCatType.PCGames); // PC Games
-            AddCategoryMapping(17, TorznabCatType.ConsolePS3); // Playstation
-            AddCategoryMapping(17, TorznabCatType.ConsolePS4); // Playstation
-            AddCategoryMapping(17, TorznabCatType.ConsolePSVita); // Playstation
-            AddCategoryMapping(17, TorznabCatType.ConsolePSP); // Playstation
-            AddCategoryMapping(28, TorznabCatType.ConsolePSP); // PSP
-            AddCategoryMapping(34, TorznabCatType.TVOTHER); // TV Pack
-            AddCategoryMapping(32, TorznabCatType.TVHD); // TV-HD
-            AddCategoryMapping(55, TorznabCatType.TVOTHER); // TV-HDRip
-            AddCategoryMapping(7, TorznabCatType.TVSD); // TV-SD
-            AddCategoryMapping(57, TorznabCatType.TVOTHER); // TV-SDRip
-            AddCategoryMapping(33, TorznabCatType.ConsoleWii); // WII
-            AddCategoryMapping(33, TorznabCatType.ConsoleWiiU); // WII
-            AddCategoryMapping(45, TorznabCatType.ConsoleXbox); // XBox
-            AddCategoryMapping(45, TorznabCatType.ConsoleXbox360); // XBox
-            AddCategoryMapping(45, TorznabCatType.ConsoleXBOX360DLC); // XBox
-            AddCategoryMapping(45, TorznabCatType.ConsoleXboxOne); // XBox
-            AddCategoryMapping(9, TorznabCatType.XXX); // XXX
-            AddCategoryMapping(52, TorznabCatType.XXXOther); // XXX-ISO
-        }
-
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, configData.CookieHeader.Value);
-            CQ cq = loginPage.Content;
-            string recaptchaSiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
-            var result = this.configData;
-            result.CookieHeader.Value = loginPage.Cookies;
-            result.Captcha.SiteKey = recaptchaSiteKey;
-            result.Captcha.Version = "2";
-            return result;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "returnto" , "/" },
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "g-recaptcha-response", configData.Captcha.Value }
-            };
-
-            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
-            {
-                // Cookie was manually supplied
-                CookieHeader = configData.Captcha.Cookie;
-                try
-                {
-                    var results = await PerformQuery(new TorznabQuery());
-                    if (!results.Any())
-                    {
-                        throw new Exception("Your cookie did not work");
-                    }
-
-                    SaveConfig();
-                    IsConfigured = true;
-                    return IndexerConfigurationStatus.Completed;
-                }
-                catch (Exception e)
-                {
-                    IsConfigured = false;
-                    throw new Exception("Your cookie did not work: " + e.Message);
-                }
-            }
-
-            var result = await RequestLoginAndFollowRedirect(AjaxLoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
-
-            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var queryCollection = new NameValueCollection();
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
-            
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            queryCollection.Add("blah", "0");
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl + "?" + queryCollection.GetQueryString());
-            if (results.IsRedirect)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookiesAndRetry(searchUrl + "?" + queryCollection.GetQueryString());
-            }
-            try
-            {
-                releases.AddRange(contentToReleaseInfos(query, results.Content));
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-
-        private IEnumerable<ReleaseInfo> contentToReleaseInfos(TorznabQuery query, CQ dom)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            // Doesn't handle pagination yet...
-            var rows = dom["div.panel-body > table.table > tbody > tr"];
-            foreach (var row in rows)
-            {
-                var release = new ReleaseInfo();
-                release.MinimumRatio = 1;
-                release.MinimumSeedTime = 259200;
-
-                var qRow = row.Cq();
-                release.Title = qRow.Find("td:nth-child(2) > a").First().Text().Trim();
-
-                if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
-                    continue;
-
-                release.Guid = new Uri(SiteLink + qRow.Find("td:nth-child(2) > a").First().Attr("href"));
-                release.Comments = release.Guid;
-                release.Link = new Uri(SiteLink + qRow.Find("td:nth-child(3) > a").First().Attr("href"));
-                var pubDate = new StringReader(qRow.Find("td:nth-child(2) > span").First().Text()).ReadLine().Trim().Replace("Added: ", "");
-                release.PublishDate = DateTime.Parse(pubDate).ToLocalTime();
-                release.Category = MapTrackerCatToNewznab(qRow.Find("td:nth-child(1) > a").First().Attr("href").Split('=')[1]);
-                release.Size = ReleaseInfo.GetBytes(qRow.Find("td:nth-child(7)").First().Text());
-                release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(9)").First().Text());
-                release.Peers = ParseUtil.CoerceInt(qRow.Find("td:nth-child(10)").First().Text()) + release.Seeders;
-
-                var files = row.Cq().Find("td:nth-child(5)").Text();
-                release.Files = ParseUtil.CoerceInt(files);
-
-                var grabs = row.Cq().Find("td:nth-child(8)").Text();
-                release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                if (row.Cq().Find("i.fa-star").Any())
-                    release.DownloadVolumeFactor = 0;
-                else
-                    release.DownloadVolumeFactor = 1;
-
-                release.UploadVolumeFactor = 1;
-
-                releases.Add(release);
-            }
-
-            return releases;
-        }
-    }
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using System.Text.RegularExpressions;
+using System.IO;
+
+namespace Jackett.Indexers
+{
+    public class DigitalHive : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "login.php?returnto=%2F"; } }
+        private string AjaxLoginUrl { get { return SiteLink + "takelogin.php"; } }
+
+        new ConfigurationDataRecaptchaLogin configData
+        {
+            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public DigitalHive(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "DigitalHive",
+                description: "DigitalHive is one of the oldest general trackers",
+                link: "https://www.digitalhive.org/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataRecaptchaLogin())
+        {
+            Encoding = Encoding.GetEncoding("iso-8859-1");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(0, TorznabCatType.Other);
+            AddCategoryMapping(48, TorznabCatType.Other); // 0Day
+            AddCategoryMapping(56, TorznabCatType.XXXImageset); // 0Day-Imagesets
+            AddCategoryMapping(6, TorznabCatType.Audio); // 0Day-Music
+            AddCategoryMapping(51, TorznabCatType.XXX); // 0Day-XXX
+            AddCategoryMapping(2, TorznabCatType.TVAnime); // Anime
+            AddCategoryMapping(59, TorznabCatType.MoviesBluRay); // BluRay
+            AddCategoryMapping(40, TorznabCatType.TVDocumentary); // Documentary
+            AddCategoryMapping(20, TorznabCatType.MoviesDVD); // DVD-R
+            AddCategoryMapping(25, TorznabCatType.BooksEbook); // Ebooks
+            AddCategoryMapping(38, TorznabCatType.PCPhoneIOS); // HandHeld
+            AddCategoryMapping(38, TorznabCatType.PCPhoneAndroid); // HandHeld
+            AddCategoryMapping(38, TorznabCatType.PCPhoneOther); // HandHeld
+            AddCategoryMapping(37, TorznabCatType.Other); // Kids Stuff
+            AddCategoryMapping(23, TorznabCatType.PC); // Linux
+            AddCategoryMapping(24, TorznabCatType.PCMac); // Mac
+            AddCategoryMapping(22, TorznabCatType.OtherMisc); // Misc
+            AddCategoryMapping(35, TorznabCatType.MoviesOther); // Movie Pack
+            AddCategoryMapping(36, TorznabCatType.MoviesHD); // Movie-HD
+            AddCategoryMapping(19, TorznabCatType.MoviesSD); // Movie-SD
+            AddCategoryMapping(50, TorznabCatType.Audio); // Music
+            AddCategoryMapping(53, TorznabCatType.AudioLossless); // Music-FLAC
+            AddCategoryMapping(49, TorznabCatType.AudioVideo); // MVID
+            AddCategoryMapping(1, TorznabCatType.PC); // PC Apps
+            AddCategoryMapping(4, TorznabCatType.PCGames); // PC Games
+            AddCategoryMapping(17, TorznabCatType.ConsolePS3); // Playstation
+            AddCategoryMapping(17, TorznabCatType.ConsolePS4); // Playstation
+            AddCategoryMapping(17, TorznabCatType.ConsolePSVita); // Playstation
+            AddCategoryMapping(17, TorznabCatType.ConsolePSP); // Playstation
+            AddCategoryMapping(28, TorznabCatType.ConsolePSP); // PSP
+            AddCategoryMapping(34, TorznabCatType.TVOTHER); // TV Pack
+            AddCategoryMapping(32, TorznabCatType.TVHD); // TV-HD
+            AddCategoryMapping(55, TorznabCatType.TVOTHER); // TV-HDRip
+            AddCategoryMapping(7, TorznabCatType.TVSD); // TV-SD
+            AddCategoryMapping(57, TorznabCatType.TVOTHER); // TV-SDRip
+            AddCategoryMapping(33, TorznabCatType.ConsoleWii); // WII
+            AddCategoryMapping(33, TorznabCatType.ConsoleWiiU); // WII
+            AddCategoryMapping(45, TorznabCatType.ConsoleXbox); // XBox
+            AddCategoryMapping(45, TorznabCatType.ConsoleXbox360); // XBox
+            AddCategoryMapping(45, TorznabCatType.ConsoleXBOX360DLC); // XBox
+            AddCategoryMapping(45, TorznabCatType.ConsoleXboxOne); // XBox
+            AddCategoryMapping(9, TorznabCatType.XXX); // XXX
+            AddCategoryMapping(52, TorznabCatType.XXXOther); // XXX-ISO
+        }
+
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, configData.CookieHeader.Value);
+            CQ cq = loginPage.Content;
+            string recaptchaSiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
+            var result = this.configData;
+            result.CookieHeader.Value = loginPage.Cookies;
+            result.Captcha.SiteKey = recaptchaSiteKey;
+            result.Captcha.Version = "2";
+            return result;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "returnto" , "/" },
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "g-recaptcha-response", configData.Captcha.Value }
+            };
+
+            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
+            {
+                // Cookie was manually supplied
+                CookieHeader = configData.Captcha.Cookie;
+                try
+                {
+                    var results = await PerformQuery(new TorznabQuery());
+                    if (!results.Any())
+                    {
+                        throw new Exception("Your cookie did not work");
+                    }
+
+                    SaveConfig();
+                    IsConfigured = true;
+                    return IndexerConfigurationStatus.Completed;
+                }
+                catch (Exception e)
+                {
+                    IsConfigured = false;
+                    throw new Exception("Your cookie did not work: " + e.Message);
+                }
+            }
+
+            var result = await RequestLoginAndFollowRedirect(AjaxLoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
+
+            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var queryCollection = new NameValueCollection();
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
+            
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            queryCollection.Add("blah", "0");
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl + "?" + queryCollection.GetQueryString());
+            if (results.IsRedirect)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookiesAndRetry(searchUrl + "?" + queryCollection.GetQueryString());
+            }
+            try
+            {
+                releases.AddRange(contentToReleaseInfos(query, results.Content));
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+
+        private IEnumerable<ReleaseInfo> contentToReleaseInfos(TorznabQuery query, CQ dom)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            // Doesn't handle pagination yet...
+            var rows = dom["div.panel-body > table.table > tbody > tr"];
+            foreach (var row in rows)
+            {
+                var release = new ReleaseInfo();
+                release.MinimumRatio = 1;
+                release.MinimumSeedTime = 259200;
+
+                var qRow = row.Cq();
+                release.Title = qRow.Find("td:nth-child(2) > a").First().Text().Trim();
+
+                if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
+                    continue;
+
+                release.Guid = new Uri(SiteLink + qRow.Find("td:nth-child(2) > a").First().Attr("href"));
+                release.Comments = release.Guid;
+                release.Link = new Uri(SiteLink + qRow.Find("td:nth-child(3) > a").First().Attr("href"));
+                var pubDate = new StringReader(qRow.Find("td:nth-child(2) > span").First().Text()).ReadLine().Trim().Replace("Added: ", "");
+                release.PublishDate = DateTime.Parse(pubDate).ToLocalTime();
+                release.Category = MapTrackerCatToNewznab(qRow.Find("td:nth-child(1) > a").First().Attr("href").Split('=')[1]);
+                release.Size = ReleaseInfo.GetBytes(qRow.Find("td:nth-child(7)").First().Text());
+                release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:nth-child(9)").First().Text());
+                release.Peers = ParseUtil.CoerceInt(qRow.Find("td:nth-child(10)").First().Text()) + release.Seeders;
+
+                var files = row.Cq().Find("td:nth-child(5)").Text();
+                release.Files = ParseUtil.CoerceInt(files);
+
+                var grabs = row.Cq().Find("td:nth-child(8)").Text();
+                release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                if (row.Cq().Find("i.fa-star").Any())
+                    release.DownloadVolumeFactor = 0;
+                else
+                    release.DownloadVolumeFactor = 1;
+
+                release.UploadVolumeFactor = 1;
+
+                releases.Add(release);
+            }
+
+            return releases;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/EliteTracker.cs b/src/Jackett/Indexers/EliteTracker.cs
index d0b5aa99a9b824ff58379e01a143eadc44eb97c1..e469798cc85113aa6df9bd0e00c582c44f3d7e67 100644
--- a/src/Jackett/Indexers/EliteTracker.cs
+++ b/src/Jackett/Indexers/EliteTracker.cs
@@ -1,34 +1,34 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-using AngleSharp.Parser.Html;
-using Newtonsoft.Json.Linq;
-using NLog;
-
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-
-namespace Jackett.Indexers
-{
-    class EliteTracker : BaseIndexer, IIndexer
-    {
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using AngleSharp.Parser.Html;
+using Newtonsoft.Json.Linq;
+using NLog;
+
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+
+namespace Jackett.Indexers
+{
+    class EliteTracker : BaseIndexer, IIndexer
+    {
         string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        string BrowseUrl { get { return SiteLink + "browse.php"; } }
-
+        string BrowseUrl { get { return SiteLink + "browse.php"; } }
+
         new ConfigurationDataBasicLogin configData
         {
             get { return (ConfigurationDataBasicLogin)base.configData; }
             set { base.configData = value; }
-        }
-
+        }
+
         public EliteTracker(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService)
             : base(name: "Elite-Tracker",
                 description: "French Torrent Tracker",
@@ -39,235 +39,235 @@ namespace Jackett.Indexers
                 client: webClient,
                 configData: new ConfigurationDataBasicLogin()
                 )
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "fr-fr";
-            Type = "private";
-
-            AddCategoryMapping(27, TorznabCatType.TVAnime, "Animation/Animes");
-            AddCategoryMapping(63, TorznabCatType.TVAnime, "Animes DVD");
-            AddCategoryMapping(56, TorznabCatType.TVAnime, "Animes HD");
-            AddCategoryMapping(59, TorznabCatType.TVAnime, "Animes Serie");
-
-            AddCategoryMapping(3, TorznabCatType.PC0day, "APPLICATION");
-            AddCategoryMapping(74, TorznabCatType.PCPhoneAndroid, "ANDROID");
-            AddCategoryMapping(57, TorznabCatType.PCPhoneIOS, "IPHONE");
-            AddCategoryMapping(6, TorznabCatType.PC0day, "LINUX");
-            AddCategoryMapping(5, TorznabCatType.PCMac, "MAC");
-            AddCategoryMapping(4, TorznabCatType.PC0day, "WINDOWS");
-
-            AddCategoryMapping(38, TorznabCatType.TVDocumentary, "DOCUMENTAIRES");
-
-            AddCategoryMapping(34, TorznabCatType.Books, "EBOOKS");
-
-            AddCategoryMapping(7, TorznabCatType.Movies, "FILMS");
-            AddCategoryMapping(11, TorznabCatType.MoviesDVD, "DVD");
-            AddCategoryMapping(10, TorznabCatType.MoviesSD, "DVD-RIP/BD-RIP");
-            AddCategoryMapping(53, TorznabCatType.MoviesSD, "DVD-SCREENER");
-            AddCategoryMapping(9, TorznabCatType.MoviesDVD, "R5");
-            AddCategoryMapping(8, TorznabCatType.MoviesSD, "SCREENER");
-            AddCategoryMapping(40, TorznabCatType.Movies, "VO");
-            AddCategoryMapping(39, TorznabCatType.Movies, "VOSTFR");
-            AddCategoryMapping(48, TorznabCatType.MoviesHD, "HD");
-            AddCategoryMapping(51, TorznabCatType.MoviesHD, "1080P");
-            AddCategoryMapping(70, TorznabCatType.Movies3D, "3D");
-            AddCategoryMapping(50, TorznabCatType.MoviesHD, "720P");
-            AddCategoryMapping(49, TorznabCatType.MoviesBluRay, "BluRay");
-            AddCategoryMapping(78, TorznabCatType.MoviesHD, "M - HD");
-
-            AddCategoryMapping(15, TorznabCatType.Console, "JEUX VIDEO");
-            AddCategoryMapping(76, TorznabCatType.Console3DS, "3DS");
-            AddCategoryMapping(18, TorznabCatType.ConsoleNDS, "DS");
-            AddCategoryMapping(55, TorznabCatType.PCPhoneIOS, "IPHONE");
-            AddCategoryMapping(80, TorznabCatType.PCGames, "LINUX");
-            AddCategoryMapping(79, TorznabCatType.PCMac, "OSX");
-            AddCategoryMapping(22, TorznabCatType.PCGames, "PC");
-            AddCategoryMapping(66, TorznabCatType.ConsolePS3, "PS2");
-            AddCategoryMapping(58, TorznabCatType.ConsolePS3, "PS3");
-            AddCategoryMapping(81, TorznabCatType.ConsolePS4, "PS4");
-            AddCategoryMapping(20, TorznabCatType.ConsolePSP, "PSP");
-            AddCategoryMapping(75, TorznabCatType.ConsolePS3, "PSX");
-            AddCategoryMapping(19, TorznabCatType.ConsoleWii, "WII");
-            AddCategoryMapping(83, TorznabCatType.ConsoleWiiU, "WiiU");
-            AddCategoryMapping(16, TorznabCatType.ConsoleXbox, "XBOX");
-            AddCategoryMapping(82, TorznabCatType.ConsoleXboxOne, "XBOX ONE");
-            AddCategoryMapping(17, TorznabCatType.ConsoleXbox360, "XBOX360");
-            AddCategoryMapping(44, TorznabCatType.ConsoleXbox360, "XBOX360.E");
-            AddCategoryMapping(54, TorznabCatType.ConsoleXbox360, "XBOX360.JTAG");
-            AddCategoryMapping(43, TorznabCatType.ConsoleXbox360, "XBOX360.NTSC");
-
-            AddCategoryMapping(23, TorznabCatType.Audio, "MUSIQUES");
-            AddCategoryMapping(26, TorznabCatType.Audio, "CLIP/CONCERT");
-            AddCategoryMapping(61, TorznabCatType.AudioLossless, "FLAC");
-            AddCategoryMapping(60, TorznabCatType.AudioMP3, "MP3");
-
-            AddCategoryMapping(30, TorznabCatType.TV, "SERIES");
-            AddCategoryMapping(73, TorznabCatType.TV, "Pack TV");
-            AddCategoryMapping(31, TorznabCatType.TV, "Series FR");
-            AddCategoryMapping(32, TorznabCatType.TV, "Series VO");
-            AddCategoryMapping(33, TorznabCatType.TV, "Series VO-STFR");
-            AddCategoryMapping(77, TorznabCatType.TVSD, "Series.DVD");
-            AddCategoryMapping(67, TorznabCatType.TVHD, "Series.FR.HD");
-            AddCategoryMapping(68, TorznabCatType.TVHD, "Series.VO.HD");
-            AddCategoryMapping(69, TorznabCatType.TVHD, "Series.VOSTFR.HD");
-
-            AddCategoryMapping(47, TorznabCatType.TV, "SPECTACLES/EMISSIONS");
-            AddCategoryMapping(71, TorznabCatType.TV, "Emissions");
-            AddCategoryMapping(72, TorznabCatType.TV, "Spectacles");
-
-            AddCategoryMapping(35, TorznabCatType.TVSport, "SPORT");
-            AddCategoryMapping(36, TorznabCatType.TVSport, "CATCH");
-            AddCategoryMapping(65, TorznabCatType.TVSport, "UFC");
-
-            AddCategoryMapping(37, TorznabCatType.XXX, "XXX");
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "fr-fr";
+            Type = "private";
+
+            AddCategoryMapping(27, TorznabCatType.TVAnime, "Animation/Animes");
+            AddCategoryMapping(63, TorznabCatType.TVAnime, "Animes DVD");
+            AddCategoryMapping(56, TorznabCatType.TVAnime, "Animes HD");
+            AddCategoryMapping(59, TorznabCatType.TVAnime, "Animes Serie");
+
+            AddCategoryMapping(3, TorznabCatType.PC0day, "APPLICATION");
+            AddCategoryMapping(74, TorznabCatType.PCPhoneAndroid, "ANDROID");
+            AddCategoryMapping(57, TorznabCatType.PCPhoneIOS, "IPHONE");
+            AddCategoryMapping(6, TorznabCatType.PC0day, "LINUX");
+            AddCategoryMapping(5, TorznabCatType.PCMac, "MAC");
+            AddCategoryMapping(4, TorznabCatType.PC0day, "WINDOWS");
+
+            AddCategoryMapping(38, TorznabCatType.TVDocumentary, "DOCUMENTAIRES");
+
+            AddCategoryMapping(34, TorznabCatType.Books, "EBOOKS");
+
+            AddCategoryMapping(7, TorznabCatType.Movies, "FILMS");
+            AddCategoryMapping(11, TorznabCatType.MoviesDVD, "DVD");
+            AddCategoryMapping(10, TorznabCatType.MoviesSD, "DVD-RIP/BD-RIP");
+            AddCategoryMapping(53, TorznabCatType.MoviesSD, "DVD-SCREENER");
+            AddCategoryMapping(9, TorznabCatType.MoviesDVD, "R5");
+            AddCategoryMapping(8, TorznabCatType.MoviesSD, "SCREENER");
+            AddCategoryMapping(40, TorznabCatType.Movies, "VO");
+            AddCategoryMapping(39, TorznabCatType.Movies, "VOSTFR");
+            AddCategoryMapping(48, TorznabCatType.MoviesHD, "HD");
+            AddCategoryMapping(51, TorznabCatType.MoviesHD, "1080P");
+            AddCategoryMapping(70, TorznabCatType.Movies3D, "3D");
+            AddCategoryMapping(50, TorznabCatType.MoviesHD, "720P");
+            AddCategoryMapping(49, TorznabCatType.MoviesBluRay, "BluRay");
+            AddCategoryMapping(78, TorznabCatType.MoviesHD, "M - HD");
+
+            AddCategoryMapping(15, TorznabCatType.Console, "JEUX VIDEO");
+            AddCategoryMapping(76, TorznabCatType.Console3DS, "3DS");
+            AddCategoryMapping(18, TorznabCatType.ConsoleNDS, "DS");
+            AddCategoryMapping(55, TorznabCatType.PCPhoneIOS, "IPHONE");
+            AddCategoryMapping(80, TorznabCatType.PCGames, "LINUX");
+            AddCategoryMapping(79, TorznabCatType.PCMac, "OSX");
+            AddCategoryMapping(22, TorznabCatType.PCGames, "PC");
+            AddCategoryMapping(66, TorznabCatType.ConsolePS3, "PS2");
+            AddCategoryMapping(58, TorznabCatType.ConsolePS3, "PS3");
+            AddCategoryMapping(81, TorznabCatType.ConsolePS4, "PS4");
+            AddCategoryMapping(20, TorznabCatType.ConsolePSP, "PSP");
+            AddCategoryMapping(75, TorznabCatType.ConsolePS3, "PSX");
+            AddCategoryMapping(19, TorznabCatType.ConsoleWii, "WII");
+            AddCategoryMapping(83, TorznabCatType.ConsoleWiiU, "WiiU");
+            AddCategoryMapping(16, TorznabCatType.ConsoleXbox, "XBOX");
+            AddCategoryMapping(82, TorznabCatType.ConsoleXboxOne, "XBOX ONE");
+            AddCategoryMapping(17, TorznabCatType.ConsoleXbox360, "XBOX360");
+            AddCategoryMapping(44, TorznabCatType.ConsoleXbox360, "XBOX360.E");
+            AddCategoryMapping(54, TorznabCatType.ConsoleXbox360, "XBOX360.JTAG");
+            AddCategoryMapping(43, TorznabCatType.ConsoleXbox360, "XBOX360.NTSC");
+
+            AddCategoryMapping(23, TorznabCatType.Audio, "MUSIQUES");
+            AddCategoryMapping(26, TorznabCatType.Audio, "CLIP/CONCERT");
+            AddCategoryMapping(61, TorznabCatType.AudioLossless, "FLAC");
+            AddCategoryMapping(60, TorznabCatType.AudioMP3, "MP3");
+
+            AddCategoryMapping(30, TorznabCatType.TV, "SERIES");
+            AddCategoryMapping(73, TorznabCatType.TV, "Pack TV");
+            AddCategoryMapping(31, TorznabCatType.TV, "Series FR");
+            AddCategoryMapping(32, TorznabCatType.TV, "Series VO");
+            AddCategoryMapping(33, TorznabCatType.TV, "Series VO-STFR");
+            AddCategoryMapping(77, TorznabCatType.TVSD, "Series.DVD");
+            AddCategoryMapping(67, TorznabCatType.TVHD, "Series.FR.HD");
+            AddCategoryMapping(68, TorznabCatType.TVHD, "Series.VO.HD");
+            AddCategoryMapping(69, TorznabCatType.TVHD, "Series.VOSTFR.HD");
+
+            AddCategoryMapping(47, TorznabCatType.TV, "SPECTACLES/EMISSIONS");
+            AddCategoryMapping(71, TorznabCatType.TV, "Emissions");
+            AddCategoryMapping(72, TorznabCatType.TV, "Spectacles");
+
+            AddCategoryMapping(35, TorznabCatType.TVSport, "SPORT");
+            AddCategoryMapping(36, TorznabCatType.TVSport, "CATCH");
+            AddCategoryMapping(65, TorznabCatType.TVSport, "UFC");
+
+            AddCategoryMapping(37, TorznabCatType.XXX, "XXX");
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
             configData.LoadValuesFromJson(configJson);
 
             var pairs = new Dictionary<string, string>
             {
                 { "username", configData.Username.Value },
                 { "password", configData.Password.Value }
-            };
-
-            var result = await PostDataWithCookies(LoginUrl, pairs);
-
-            await ConfigureIfOK(result.Cookies, result.Cookies != null, () =>
-           {
-               var errorMessage = result.Content;
-               throw new ExceptionWithConfigData(errorMessage, configData);
-           });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            var queryCollection = new Dictionary<string, string>();
-            queryCollection.Add("search_type", "t_name");
-            queryCollection.Add("do", "search");
-            queryCollection.Add("keywords", searchString);
-            queryCollection.Add("category", "0"); // multi cat search not supported
-
-            var results = await PostDataWithCookies(BrowseUrl, queryCollection);
-            if (results.IsRedirect)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                results = await PostDataWithCookies(BrowseUrl, queryCollection);
-            }
-
+            };
+
+            var result = await PostDataWithCookies(LoginUrl, pairs);
+
+            await ConfigureIfOK(result.Cookies, result.Cookies != null, () =>
+           {
+               var errorMessage = result.Content;
+               throw new ExceptionWithConfigData(errorMessage, configData);
+           });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+
+            var queryCollection = new Dictionary<string, string>();
+            queryCollection.Add("search_type", "t_name");
+            queryCollection.Add("do", "search");
+            queryCollection.Add("keywords", searchString);
+            queryCollection.Add("category", "0"); // multi cat search not supported
+
+            var results = await PostDataWithCookies(BrowseUrl, queryCollection);
+            if (results.IsRedirect)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                results = await PostDataWithCookies(BrowseUrl, queryCollection);
+            }
+
             try
             {
                 var RowsSelector = "table[id='sortabletable'] > tbody > tr";
-                var SearchResultParser = new HtmlParser();
-                var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                var lastDate = DateTime.Now;
-
-                foreach (var Row in Rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 0;
+                var SearchResultParser = new HtmlParser();
+                var SearchResultDocument = SearchResultParser.Parse(results.Content);
+                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                var lastDate = DateTime.Now;
+
+                foreach (var Row in Rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 0;
 
                     var category = Row.QuerySelector("td:nth-child(1) > a");
-                    var title = Row.QuerySelector("td:nth-child(2) a");
-                    var added = Row.QuerySelector("td:nth-child(2) > div:has(span[style=\"float: right;\"])");
-                    if (added == null) // not a torrent line
-                        continue;
-                    var pretime = added.QuerySelector("font.mkprettytime");
-                    var tooltip = Row.QuerySelector("td:nth-child(2) > div.tooltip-content");
-
-                    var link = Row.QuerySelector("td:nth-child(3)").QuerySelector("a");
-                    var comments = Row.QuerySelector("td:nth-child(2)").QuerySelector("a");
-                    var Size = Row.QuerySelector("td:nth-child(5)");
-                    var Grabs = Row.QuerySelector("td:nth-child(6)").QuerySelector("a");
-                    var Seeders = Row.QuerySelector("td:nth-child(7)").QuerySelector("a");
-                    var Leechers = Row.QuerySelector("td:nth-child(8)").QuerySelector("a");
-
-                    var categoryIdparts = category.GetAttribute("href").Split('-');
-                    var categoryId = categoryIdparts[categoryIdparts.Length-1].Replace(".ts", "");
-
-                    release.Title = title.TextContent;
-                    release.Category = MapTrackerCatToNewznab(categoryId);
-                    release.Link = new Uri(link.GetAttribute("href"));
-                    release.Comments = new Uri(comments.GetAttribute("href"));
-                    release.Guid = release.Link;
-                    release.Size = ReleaseInfo.GetBytes(Size.TextContent);
-                    release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
-                    release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
-                    release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
-
-                    if (added.QuerySelector("img[alt^=\"TORRENT GRATUIT\"]") != null)
-                        release.DownloadVolumeFactor = 0;
-                    else if (added.QuerySelector("img[alt^=\"TORRENT SILVER\"]") != null)
-                        release.DownloadVolumeFactor = 0.5;
-                    else
-                        release.DownloadVolumeFactor = 1;
-
-                    if (added.QuerySelector("img[alt^=\"TORRENT X2\"]") != null)
-                        release.UploadVolumeFactor = 2;
-                    else
-                        release.UploadVolumeFactor = 1;
-
-                    if (tooltip != null)
-                    {
-                        var banner = tooltip.QuerySelector("img");
-                        if (banner != null)
-                        {
-                            release.BannerUrl = new Uri(banner.GetAttribute("src"));
-                            banner.Remove();
-                        }
-
-                        tooltip.QuerySelector("div:contains(\"Total Hits: \")").Remove();
-
-                        var longtitle = tooltip.QuerySelectorAll("div").First();
-                        release.Title = longtitle.TextContent;
-                        longtitle.Remove();
-
-                        var desc = tooltip.TextContent.Trim();
-                        if (!string.IsNullOrWhiteSpace(desc))
-                            release.Description = desc;
-                    }
-
-                    // if even the tooltip title is shortened we use the URL
-                    if (release.Title.EndsWith("..."))
-                    {
-                        var tregex = new Regex(@"/([^/]+)-s-\d+\.ts");
-                        var tmatch = tregex.Match(release.Comments.ToString());
-                        release.Title = tmatch.Groups[1].Value;
-                    }
-
-                    if (pretime != null)
-                    {
-                        if (release.Description == null)
-                            release.Description = pretime.TextContent;
-                        else
-                            release.Description += "<br>\n" + pretime.TextContent;
-                        release.PublishDate = lastDate;
-                    }
-                    else
-                    {
-                        release.PublishDate = DateTime.ParseExact(added.TextContent.Trim(), "dd.M.yyyy HH:mm", CultureInfo.InvariantCulture);
-                        lastDate = release.PublishDate;
-                    }
-
+                    var title = Row.QuerySelector("td:nth-child(2) a");
+                    var added = Row.QuerySelector("td:nth-child(2) > div:has(span[style=\"float: right;\"])");
+                    if (added == null) // not a torrent line
+                        continue;
+                    var pretime = added.QuerySelector("font.mkprettytime");
+                    var tooltip = Row.QuerySelector("td:nth-child(2) > div.tooltip-content");
+
+                    var link = Row.QuerySelector("td:nth-child(3)").QuerySelector("a");
+                    var comments = Row.QuerySelector("td:nth-child(2)").QuerySelector("a");
+                    var Size = Row.QuerySelector("td:nth-child(5)");
+                    var Grabs = Row.QuerySelector("td:nth-child(6)").QuerySelector("a");
+                    var Seeders = Row.QuerySelector("td:nth-child(7)").QuerySelector("a");
+                    var Leechers = Row.QuerySelector("td:nth-child(8)").QuerySelector("a");
+
+                    var categoryIdparts = category.GetAttribute("href").Split('-');
+                    var categoryId = categoryIdparts[categoryIdparts.Length-1].Replace(".ts", "");
+
+                    release.Title = title.TextContent;
+                    release.Category = MapTrackerCatToNewznab(categoryId);
+                    release.Link = new Uri(link.GetAttribute("href"));
+                    release.Comments = new Uri(comments.GetAttribute("href"));
+                    release.Guid = release.Link;
+                    release.Size = ReleaseInfo.GetBytes(Size.TextContent);
+                    release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
+                    release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
+                    release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
+
+                    if (added.QuerySelector("img[alt^=\"TORRENT GRATUIT\"]") != null)
+                        release.DownloadVolumeFactor = 0;
+                    else if (added.QuerySelector("img[alt^=\"TORRENT SILVER\"]") != null)
+                        release.DownloadVolumeFactor = 0.5;
+                    else
+                        release.DownloadVolumeFactor = 1;
+
+                    if (added.QuerySelector("img[alt^=\"TORRENT X2\"]") != null)
+                        release.UploadVolumeFactor = 2;
+                    else
+                        release.UploadVolumeFactor = 1;
+
+                    if (tooltip != null)
+                    {
+                        var banner = tooltip.QuerySelector("img");
+                        if (banner != null)
+                        {
+                            release.BannerUrl = new Uri(banner.GetAttribute("src"));
+                            banner.Remove();
+                        }
+
+                        tooltip.QuerySelector("div:contains(\"Total Hits: \")").Remove();
+
+                        var longtitle = tooltip.QuerySelectorAll("div").First();
+                        release.Title = longtitle.TextContent;
+                        longtitle.Remove();
+
+                        var desc = tooltip.TextContent.Trim();
+                        if (!string.IsNullOrWhiteSpace(desc))
+                            release.Description = desc;
+                    }
+
+                    // if even the tooltip title is shortened we use the URL
+                    if (release.Title.EndsWith("..."))
+                    {
+                        var tregex = new Regex(@"/([^/]+)-s-\d+\.ts");
+                        var tmatch = tregex.Match(release.Comments.ToString());
+                        release.Title = tmatch.Groups[1].Value;
+                    }
+
+                    if (pretime != null)
+                    {
+                        if (release.Description == null)
+                            release.Description = pretime.TextContent;
+                        else
+                            release.Description += "<br>\n" + pretime.TextContent;
+                        release.PublishDate = lastDate;
+                    }
+                    else
+                    {
+                        release.PublishDate = DateTime.ParseExact(added.TextContent.Trim(), "dd.M.yyyy HH:mm", CultureInfo.InvariantCulture);
+                        lastDate = release.PublishDate;
+                    }
+
                     releases.Add(release);
-                }
+                }
             }
             catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
+            {
+                OnParseError(results.Content, ex);
             }
 
-            return releases;
-        }
-
-    }
-}
+            return releases;
+        }
+
+    }
+}
diff --git a/src/Jackett/Indexers/FileList.cs b/src/Jackett/Indexers/FileList.cs
index a0cd20d5f0f044975e3c1fe3c7615c1cd48ebf81..ecb6cae41335f34a111111d15cc1767a0ac898f1 100644
--- a/src/Jackett/Indexers/FileList.cs
+++ b/src/Jackett/Indexers/FileList.cs
@@ -1,196 +1,196 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-using Jackett.Models.IndexerConfig.Bespoke;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public class FileList : BaseIndexer, IIndexer
-    {
-        string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        string BrowseUrl { get { return SiteLink + "browse.php"; } }
-
-        new ConfigurationDataFileList configData
-        {
-            get { return (ConfigurationDataFileList)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public FileList(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "FileList",
-                description: "The best Romanian site.",
-                link: "http://filelist.ro/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataFileList())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "ro-ro";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(24, TorznabCatType.TVAnime); //Anime
-            AddCategoryMapping(11, TorznabCatType.Audio); //Audio
-            AddCategoryMapping(18, TorznabCatType.Other); //Misc
-            AddCategoryMapping(16, TorznabCatType.Books); //Docs
-            AddCategoryMapping(25, TorznabCatType.Movies3D); //Movies 3D
-            AddCategoryMapping(20, TorznabCatType.MoviesBluRay); // Movies Blu-Ray
-            AddCategoryMapping(2, TorznabCatType.MoviesDVD); //Movies DVD
-            AddCategoryMapping(3, TorznabCatType.MoviesForeign); //Movies DVD-RO
-            AddCategoryMapping(4, TorznabCatType.MoviesHD); //Movies HD
-            AddCategoryMapping(19, TorznabCatType.MoviesForeign); //Movies HD-RO
-            AddCategoryMapping(1, TorznabCatType.MoviesSD); //Movies SD
-            AddCategoryMapping(10, TorznabCatType.Console); //Console Games
-            AddCategoryMapping(9, TorznabCatType.PCGames); //PC Games
-            AddCategoryMapping(17, TorznabCatType.PC); //Linux
-            AddCategoryMapping(22, TorznabCatType.PCPhoneOther); //Apps/mobile
-            AddCategoryMapping(8, TorznabCatType.PC); //Software
-            AddCategoryMapping(21, TorznabCatType.TVHD); //TV HD
-            AddCategoryMapping(23, TorznabCatType.TVSD); //TV SD
-            AddCategoryMapping(13, TorznabCatType.TVSport); //Sport
-            AddCategoryMapping(14, TorznabCatType.TV); //TV
-            AddCategoryMapping(12, TorznabCatType.AudioVideo); //Music Video
-            AddCategoryMapping(7, TorznabCatType.XXX); //XXX
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value }
-            };
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom[".main"].Text().Trim();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchUrl = BrowseUrl;
-            var searchString = query.GetQueryString();
-
-            var cats = MapTorznabCapsToTrackers(query);
-            string cat = "0";
-            if (cats.Count == 1)
-            {
-                cat = cats[0];
-            }
-
-            var queryCollection = new NameValueCollection();
-
-            if (query.ImdbID != null)
-            {
-                queryCollection.Add("search", query.ImdbID);
-            }
-            else if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            queryCollection.Add("cat", cat);
-            queryCollection.Add("searchin", "0");
-            queryCollection.Add("sort", "0");
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
-            var results = response.Content;
-            try
-            {
-                CQ dom = results;
-                var globalFreeLeech = dom.Find("div.globalFreeLeech").Any();
-                var rows = dom[".torrentrow"];
-                foreach (var row in rows)
-                {
-                    var release = new ReleaseInfo();
-                    var qRow = row.Cq();
-                    var qTitleLink = qRow.Find(".torrenttable:eq(1) a").First();
-                    release.Title = qRow.Find(".torrenttable:eq(1) b").Text();
-
-                    if (query.ImdbID == null && !query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    release.Description = qRow.Find(".torrenttable:eq(1) > span > font.small").First().Text();
-
-                    var tooltip = qTitleLink.Attr("title");
-                    if (!string.IsNullOrEmpty(tooltip))
-                    {
-                        var ImgRegexp = new Regex("src='(.*?)'");
-                        var ImgRegexpMatch = ImgRegexp.Match(tooltip);
-                        if (ImgRegexpMatch.Success)
-                            release.BannerUrl = new Uri(ImgRegexpMatch.Groups[1].Value);
-                    }
-
-                    release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
-                    release.Comments = release.Guid;
-
-                    //22:05:3716/02/2013
-                    var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim()+" +0200";
-                    release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy zzz", CultureInfo.InvariantCulture);
-
-                    var qLink = qRow.Find("a[href^=\"download.php?id=\"]").First();
-                    release.Link = new Uri(SiteLink + qLink.Attr("href"));
-
-                    var sizeStr = qRow.Find(".torrenttable:eq(6)").Text().Trim();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
-                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;
-
-                    var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
-                    release.Category = MapTrackerCatToNewznab(catId);
-
-                    var grabs = qRow.Find(".torrenttable:eq(7)").First().Get(0).FirstChild;
-                    release.Grabs = ParseUtil.CoerceLong(catId);
-
-                    if (globalFreeLeech || row.Cq().Find("img[alt=\"FreeLeech\"]").Any())
-                        release.DownloadVolumeFactor = 0;
-                    else
-                        release.DownloadVolumeFactor = 1;
-
-                    release.UploadVolumeFactor = 1;
-
-                    // Skip Romanian releases
-                    if (release.Category.Contains(TorznabCatType.MoviesForeign.ID) && !configData.IncludeRomanianReleases.Value)
-                        continue;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+using Jackett.Models.IndexerConfig.Bespoke;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public class FileList : BaseIndexer, IIndexer
+    {
+        string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+        string BrowseUrl { get { return SiteLink + "browse.php"; } }
+
+        new ConfigurationDataFileList configData
+        {
+            get { return (ConfigurationDataFileList)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public FileList(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "FileList",
+                description: "The best Romanian site.",
+                link: "http://filelist.ro/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataFileList())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "ro-ro";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(24, TorznabCatType.TVAnime); //Anime
+            AddCategoryMapping(11, TorznabCatType.Audio); //Audio
+            AddCategoryMapping(18, TorznabCatType.Other); //Misc
+            AddCategoryMapping(16, TorznabCatType.Books); //Docs
+            AddCategoryMapping(25, TorznabCatType.Movies3D); //Movies 3D
+            AddCategoryMapping(20, TorznabCatType.MoviesBluRay); // Movies Blu-Ray
+            AddCategoryMapping(2, TorznabCatType.MoviesDVD); //Movies DVD
+            AddCategoryMapping(3, TorznabCatType.MoviesForeign); //Movies DVD-RO
+            AddCategoryMapping(4, TorznabCatType.MoviesHD); //Movies HD
+            AddCategoryMapping(19, TorznabCatType.MoviesForeign); //Movies HD-RO
+            AddCategoryMapping(1, TorznabCatType.MoviesSD); //Movies SD
+            AddCategoryMapping(10, TorznabCatType.Console); //Console Games
+            AddCategoryMapping(9, TorznabCatType.PCGames); //PC Games
+            AddCategoryMapping(17, TorznabCatType.PC); //Linux
+            AddCategoryMapping(22, TorznabCatType.PCPhoneOther); //Apps/mobile
+            AddCategoryMapping(8, TorznabCatType.PC); //Software
+            AddCategoryMapping(21, TorznabCatType.TVHD); //TV HD
+            AddCategoryMapping(23, TorznabCatType.TVSD); //TV SD
+            AddCategoryMapping(13, TorznabCatType.TVSport); //Sport
+            AddCategoryMapping(14, TorznabCatType.TV); //TV
+            AddCategoryMapping(12, TorznabCatType.AudioVideo); //Music Video
+            AddCategoryMapping(7, TorznabCatType.XXX); //XXX
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value }
+            };
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom[".main"].Text().Trim();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchUrl = BrowseUrl;
+            var searchString = query.GetQueryString();
+
+            var cats = MapTorznabCapsToTrackers(query);
+            string cat = "0";
+            if (cats.Count == 1)
+            {
+                cat = cats[0];
+            }
+
+            var queryCollection = new NameValueCollection();
+
+            if (query.ImdbID != null)
+            {
+                queryCollection.Add("search", query.ImdbID);
+            }
+            else if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            queryCollection.Add("cat", cat);
+            queryCollection.Add("searchin", "0");
+            queryCollection.Add("sort", "0");
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
+            var results = response.Content;
+            try
+            {
+                CQ dom = results;
+                var globalFreeLeech = dom.Find("div.globalFreeLeech").Any();
+                var rows = dom[".torrentrow"];
+                foreach (var row in rows)
+                {
+                    var release = new ReleaseInfo();
+                    var qRow = row.Cq();
+                    var qTitleLink = qRow.Find(".torrenttable:eq(1) a").First();
+                    release.Title = qRow.Find(".torrenttable:eq(1) b").Text();
+
+                    if (query.ImdbID == null && !query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    release.Description = qRow.Find(".torrenttable:eq(1) > span > font.small").First().Text();
+
+                    var tooltip = qTitleLink.Attr("title");
+                    if (!string.IsNullOrEmpty(tooltip))
+                    {
+                        var ImgRegexp = new Regex("src='(.*?)'");
+                        var ImgRegexpMatch = ImgRegexp.Match(tooltip);
+                        if (ImgRegexpMatch.Success)
+                            release.BannerUrl = new Uri(ImgRegexpMatch.Groups[1].Value);
+                    }
+
+                    release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
+                    release.Comments = release.Guid;
+
+                    //22:05:3716/02/2013
+                    var dateStr = qRow.Find(".torrenttable:eq(5)").Text().Trim()+" +0200";
+                    release.PublishDate = DateTime.ParseExact(dateStr, "H:mm:ssdd/MM/yyyy zzz", CultureInfo.InvariantCulture);
+
+                    var qLink = qRow.Find("a[href^=\"download.php?id=\"]").First();
+                    release.Link = new Uri(SiteLink + qLink.Attr("href"));
+
+                    var sizeStr = qRow.Find(".torrenttable:eq(6)").Text().Trim();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(8)").Text().Trim());
+                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".torrenttable:eq(9)").Text().Trim()) + release.Seeders;
+
+                    var catId = qRow.Find(".torrenttable:eq(0) a").First().Attr("href").Substring(15);
+                    release.Category = MapTrackerCatToNewznab(catId);
+
+                    var grabs = qRow.Find(".torrenttable:eq(7)").First().Get(0).FirstChild;
+                    release.Grabs = ParseUtil.CoerceLong(catId);
+
+                    if (globalFreeLeech || row.Cq().Find("img[alt=\"FreeLeech\"]").Any())
+                        release.DownloadVolumeFactor = 0;
+                    else
+                        release.DownloadVolumeFactor = 1;
+
+                    release.UploadVolumeFactor = 1;
+
+                    // Skip Romanian releases
+                    if (release.Category.Contains(TorznabCatType.MoviesForeign.ID) && !configData.IncludeRomanianReleases.Value)
+                        continue;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Freshon.cs b/src/Jackett/Indexers/Freshon.cs
index cfdb9e799d061360236a413ec27602416d6cecc8..976ef216feaf28ed1f9834dccacd6fe75613acd0 100644
--- a/src/Jackett/Indexers/Freshon.cs
+++ b/src/Jackett/Indexers/Freshon.cs
@@ -18,8 +18,8 @@ using System.Threading.Tasks;
 using System.Web;
 using System.Web.UI.WebControls;
 using Jackett.Models.IndexerConfig;
-using System.Text.RegularExpressions;
-
+using System.Text.RegularExpressions;
+
 namespace Jackett.Indexers
 {
     public class Freshon : BaseIndexer, IIndexer
@@ -108,7 +108,7 @@ namespace Jackett.Indexers
                     release.MinimumRatio = 1;
                     release.MinimumSeedTime = 172800;
                     release.Title = qLink.Attr("title");
-                    if (!query.MatchQueryStringAND(release.Title))
+                    if (!query.MatchQueryStringAND(release.Title))
                         continue;
 
                     release.Description = release.Title;
@@ -133,22 +133,22 @@ namespace Jackett.Indexers
                     {   pubDateRomania = DateTime.SpecifyKind(DateTime.ParseExact(dateString, "d-MMM-yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified); }
 
                     DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(pubDateRomania, romaniaTz);
-                    release.PublishDate = pubDateUtc.ToLocalTime();
-
-                    try
-                    {
-                        var grabs = Regex.Match(row.Cq().Find("td.table_snatch").Text().Trim(), @"(^\d*).*").Value[0].ToString();
-                        release.Grabs = ParseUtil.CoerceInt(grabs);
+                    release.PublishDate = pubDateUtc.ToLocalTime();
+
+                    try
+                    {
+                        var grabs = Regex.Match(row.Cq().Find("td.table_snatch").Text().Trim(), @"(^\d*).*").Value[0].ToString();
+                        release.Grabs = ParseUtil.CoerceInt(grabs);
                     }
                     catch
-                    {
-                        release.Grabs = 1;
+                    {
+                        release.Grabs = 1;
                     }
 
-                    if (row.Cq().Find("img[alt=\"100% Free\"]").Any())
-                        release.DownloadVolumeFactor = 0;
-                    else if (row.Cq().Find("img[alt=\"50% Free\"]").Any())
-                        release.DownloadVolumeFactor = 0.5;
+                    if (row.Cq().Find("img[alt=\"100% Free\"]").Any())
+                        release.DownloadVolumeFactor = 0;
+                    else if (row.Cq().Find("img[alt=\"50% Free\"]").Any())
+                        release.DownloadVolumeFactor = 0.5;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/FunFile.cs b/src/Jackett/Indexers/FunFile.cs
index 372adf66549b0fea67ec6aa2115d8b2c670fea80..fa791dd5ecc6e806f3744d9c6b4ded1ae0e795fa 100644
--- a/src/Jackett/Indexers/FunFile.cs
+++ b/src/Jackett/Indexers/FunFile.cs
@@ -1,147 +1,147 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
-namespace Jackett.Indexers
-{
-    public class FunFile : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public FunFile(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "FunFile",
-                description: "A general tracker",
-                link: "https://www.funfile.org/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("iso-8859-1");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(44, TorznabCatType.TVAnime); // Anime
-            AddCategoryMapping(22, TorznabCatType.PC); // Applications
-            AddCategoryMapping(43, TorznabCatType.AudioAudiobook); // Audio Books
-            AddCategoryMapping(27, TorznabCatType.Books); // Ebook
-            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games
-            AddCategoryMapping(40, TorznabCatType.OtherMisc); // Miscellaneous
-            AddCategoryMapping(19, TorznabCatType.Movies); // Movies
-            AddCategoryMapping(6,  TorznabCatType.Audio); // Music
-            AddCategoryMapping(31, TorznabCatType.PCPhoneOther); // Portable
-            AddCategoryMapping(7,  TorznabCatType.TV); // TV
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "login", "Login" },
-            };
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom["td.mf_content"].Html();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("showspam", "1");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            var cats = MapTorznabCapsToTrackers(query);
-            string cat = "0";
-            if (cats.Count == 1)
-            {
-                cat = cats[0];
-            }
-            queryCollection.Add("cat", cat);
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+
+namespace Jackett.Indexers
+{
+    public class FunFile : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public FunFile(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "FunFile",
+                description: "A general tracker",
+                link: "https://www.funfile.org/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("iso-8859-1");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(44, TorznabCatType.TVAnime); // Anime
+            AddCategoryMapping(22, TorznabCatType.PC); // Applications
+            AddCategoryMapping(43, TorznabCatType.AudioAudiobook); // Audio Books
+            AddCategoryMapping(27, TorznabCatType.Books); // Ebook
+            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games
+            AddCategoryMapping(40, TorznabCatType.OtherMisc); // Miscellaneous
+            AddCategoryMapping(19, TorznabCatType.Movies); // Movies
+            AddCategoryMapping(6,  TorznabCatType.Audio); // Music
+            AddCategoryMapping(31, TorznabCatType.PCPhoneOther); // Portable
+            AddCategoryMapping(7,  TorznabCatType.TV); // TV
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "login", "Login" },
+            };
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom["td.mf_content"].Html();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("showspam", "1");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            var cats = MapTorznabCapsToTrackers(query);
+            string cat = "0";
+            if (cats.Count == 1)
+            {
+                cat = cats[0];
+            }
+            queryCollection.Add("cat", cat);
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+
             // Occasionally the cookies become invalid, login again if that happens
-            if (results.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookiesAndRetry(searchUrl);
-            }
-
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom["table[cellpadding=2] > tbody > tr:has(td.row3)"];
-                foreach (var row in rows)
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 48 * 60 * 60;
-                    
-                    var qRow = row.Cq();
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    var qSeeders = qRow.Find("td:eq(9)");
-                    var qLeechers = qRow.Find("td:eq(10)");
-                    var qDownloadLink = qRow.Find("a[href^=download.php]").First();
-                    var qTimeAgo = qRow.Find("td:eq(5)");
-                    var qSize = qRow.Find("td:eq(7)");
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1].Split('&')[0];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
-                    release.Title = qDetailsLink.Attr("title").Trim();
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
-                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
-
-                    var dateStr = qTimeAgo.Text();
-                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);
-
+            if (results.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookiesAndRetry(searchUrl);
+            }
+
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom["table[cellpadding=2] > tbody > tr:has(td.row3)"];
+                foreach (var row in rows)
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 48 * 60 * 60;
+                    
+                    var qRow = row.Cq();
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    var qSeeders = qRow.Find("td:eq(9)");
+                    var qLeechers = qRow.Find("td:eq(10)");
+                    var qDownloadLink = qRow.Find("a[href^=download.php]").First();
+                    var qTimeAgo = qRow.Find("td:eq(5)");
+                    var qSize = qRow.Find("td:eq(7)");
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1].Split('&')[0];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
+                    release.Title = qDetailsLink.Attr("title").Trim();
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
+
+                    var dateStr = qTimeAgo.Text();
+                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);
+
                     var files = qRow.Find("td:nth-child(4)").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
@@ -151,18 +151,18 @@ namespace Jackett.Indexers
                     var ka = qRow.Next();
                     var DLFactor = ka.Find("table > tbody > tr:nth-child(3) > td:nth-child(2)").Text().Replace("X", "");
                     var ULFactor = ka.Find("table > tbody > tr:nth-child(3) > td:nth-child(1)").Text().Replace("X", "");
-                    release.DownloadVolumeFactor = ParseUtil.CoerceDouble(DLFactor);
-                    release.UploadVolumeFactor = ParseUtil.CoerceDouble(ULFactor);
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+                    release.DownloadVolumeFactor = ParseUtil.CoerceDouble(DLFactor);
+                    release.UploadVolumeFactor = ParseUtil.CoerceDouble(ULFactor);
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Fuzer.cs b/src/Jackett/Indexers/Fuzer.cs
index 5a75d8018318ffcd35c983a39dbfcfc7b1e290dd..4776fee1545d7bae1c27baa36b2d3ab9de4b7555 100644
--- a/src/Jackett/Indexers/Fuzer.cs
+++ b/src/Jackett/Indexers/Fuzer.cs
@@ -247,8 +247,8 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(6)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[src=\"/images/FL.png\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("img[src=\"/images/FL.png\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/GFTracker.cs b/src/Jackett/Indexers/GFTracker.cs
index 1ac2c2599f1fb291e83a9f0d002f839aa943026a..6d95725da5b8f7f0517e6b9d5069a3093c9faba8 100644
--- a/src/Jackett/Indexers/GFTracker.cs
+++ b/src/Jackett/Indexers/GFTracker.cs
@@ -49,36 +49,36 @@ namespace Jackett.Indexers
             Language = "en-us";
             Type = "private";
 
-            AddCategoryMapping(2, TorznabCatType.PC0day, "0DAY");
-            AddCategoryMapping(16, TorznabCatType.TVAnime, "Anime");
-            AddCategoryMapping(1, TorznabCatType.PC0day, "APPS");
-            AddCategoryMapping(9, TorznabCatType.Other, "E-Learning");
-            AddCategoryMapping(35, TorznabCatType.TVFOREIGN, "Foreign");
-            AddCategoryMapping(32, TorznabCatType.ConsoleNDS, "Games/NDS");
-            AddCategoryMapping(6, TorznabCatType.PCGames, "Games/PC");
-            AddCategoryMapping(36, TorznabCatType.ConsolePS4, "Games/Playstation");
-            AddCategoryMapping(29, TorznabCatType.ConsolePSP, "Games/PSP");
-            AddCategoryMapping(23, TorznabCatType.ConsoleWii, "Games/WII");
-            AddCategoryMapping(12, TorznabCatType.ConsoleXbox, "Games/XBOX");
-            AddCategoryMapping(11, TorznabCatType.Other, "Misc");
-            AddCategoryMapping(48, TorznabCatType.MoviesBluRay, "Movies/BLURAY");
-            AddCategoryMapping(8, TorznabCatType.MoviesDVD, "Movies/DVDR");
-            AddCategoryMapping(18, TorznabCatType.MoviesHD, "Movies/X264-HD");
-            AddCategoryMapping(49, TorznabCatType.MoviesSD, "Movies/X264-SD");
-            AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movies/XVID");
-            AddCategoryMapping(38, TorznabCatType.AudioOther, "Music/DVDR");
-            AddCategoryMapping(46, TorznabCatType.AudioLossless, "Music/FLAC");
-            AddCategoryMapping(5, TorznabCatType.AudioMP3, "Music/MP3");
-            AddCategoryMapping(13, TorznabCatType.AudioVideo, "Music/Vids");
-            AddCategoryMapping(26, TorznabCatType.TVHD, "TV/BLURAY");
-            AddCategoryMapping(37, TorznabCatType.TVSD, "TV/DVDR");
-            AddCategoryMapping(19, TorznabCatType.TVSD, "TV/DVDRIP");
-            AddCategoryMapping(47, TorznabCatType.TVSD, "TV/SD");
-            AddCategoryMapping(17, TorznabCatType.TVHD, "TV/X264");
-            AddCategoryMapping(4, TorznabCatType.TVSD, "TV/XVID");
-            AddCategoryMapping(22, TorznabCatType.XXX, "XXX/0DAY");
-            AddCategoryMapping(25, TorznabCatType.XXXDVD, "XXX/DVDR");
-            AddCategoryMapping(20, TorznabCatType.XXX, "XXX/HD");
+            AddCategoryMapping(2, TorznabCatType.PC0day, "0DAY");
+            AddCategoryMapping(16, TorznabCatType.TVAnime, "Anime");
+            AddCategoryMapping(1, TorznabCatType.PC0day, "APPS");
+            AddCategoryMapping(9, TorznabCatType.Other, "E-Learning");
+            AddCategoryMapping(35, TorznabCatType.TVFOREIGN, "Foreign");
+            AddCategoryMapping(32, TorznabCatType.ConsoleNDS, "Games/NDS");
+            AddCategoryMapping(6, TorznabCatType.PCGames, "Games/PC");
+            AddCategoryMapping(36, TorznabCatType.ConsolePS4, "Games/Playstation");
+            AddCategoryMapping(29, TorznabCatType.ConsolePSP, "Games/PSP");
+            AddCategoryMapping(23, TorznabCatType.ConsoleWii, "Games/WII");
+            AddCategoryMapping(12, TorznabCatType.ConsoleXbox, "Games/XBOX");
+            AddCategoryMapping(11, TorznabCatType.Other, "Misc");
+            AddCategoryMapping(48, TorznabCatType.MoviesBluRay, "Movies/BLURAY");
+            AddCategoryMapping(8, TorznabCatType.MoviesDVD, "Movies/DVDR");
+            AddCategoryMapping(18, TorznabCatType.MoviesHD, "Movies/X264-HD");
+            AddCategoryMapping(49, TorznabCatType.MoviesSD, "Movies/X264-SD");
+            AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movies/XVID");
+            AddCategoryMapping(38, TorznabCatType.AudioOther, "Music/DVDR");
+            AddCategoryMapping(46, TorznabCatType.AudioLossless, "Music/FLAC");
+            AddCategoryMapping(5, TorznabCatType.AudioMP3, "Music/MP3");
+            AddCategoryMapping(13, TorznabCatType.AudioVideo, "Music/Vids");
+            AddCategoryMapping(26, TorznabCatType.TVHD, "TV/BLURAY");
+            AddCategoryMapping(37, TorznabCatType.TVSD, "TV/DVDR");
+            AddCategoryMapping(19, TorznabCatType.TVSD, "TV/DVDRIP");
+            AddCategoryMapping(47, TorznabCatType.TVSD, "TV/SD");
+            AddCategoryMapping(17, TorznabCatType.TVHD, "TV/X264");
+            AddCategoryMapping(4, TorznabCatType.TVSD, "TV/XVID");
+            AddCategoryMapping(22, TorznabCatType.XXX, "XXX/0DAY");
+            AddCategoryMapping(25, TorznabCatType.XXXDVD, "XXX/DVDR");
+            AddCategoryMapping(20, TorznabCatType.XXX, "XXX/HD");
             AddCategoryMapping(3, TorznabCatType.XXXXviD, "XXX/XVID");
         }
 
@@ -138,8 +138,8 @@ namespace Jackett.Indexers
 
             var response = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SearchUrl, StartPageUrl);
             UpdateCookieHeader(response.Cookies);
-            UpdateCookieHeader("mybbuser=;"); // add dummy cookie, otherwise we get logged out after each request
-
+            UpdateCookieHeader("mybbuser=;"); // add dummy cookie, otherwise we get logged out after each request
+
             await ConfigureIfOK(configData.CookieHeader.Value, response.Content != null && response.Content.Contains("logout.php"), () =>
             {
                 CQ dom = response.Content;
@@ -159,7 +159,7 @@ namespace Jackett.Indexers
             var searchString = query.GetQueryString();
 
             // search in normal + gems view
-            foreach (var view in new string[] {"0", "1"})
+            foreach (var view in new string[] {"0", "1"})
             {
                 var queryCollection = new NameValueCollection();
 
@@ -178,12 +178,12 @@ namespace Jackett.Indexers
 
                 var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
 
-                var results = await RequestStringWithCookiesAndRetry(searchUrl);
-                if (results.IsRedirect)
-                {
-                    // re-login
-                    await ApplyConfiguration(null);
-                    results = await RequestStringWithCookiesAndRetry(searchUrl);
+                var results = await RequestStringWithCookiesAndRetry(searchUrl);
+                if (results.IsRedirect)
+                {
+                    // re-login
+                    await ApplyConfiguration(null);
+                    results = await RequestStringWithCookiesAndRetry(searchUrl);
                 }
 
                 try
@@ -238,7 +238,7 @@ namespace Jackett.Indexers
                 catch (Exception ex)
                 {
                     OnParseError(results.Content, ex);
-                }
+                }
             }
 
             return releases;
diff --git a/src/Jackett/Indexers/GhostCity.cs b/src/Jackett/Indexers/GhostCity.cs
index e0784e939e2c824685a05880b8c3de8ac41e2726..8d4af82d0987e48b4d58252d81cfe39da542a852 100644
--- a/src/Jackett/Indexers/GhostCity.cs
+++ b/src/Jackett/Indexers/GhostCity.cs
@@ -1,184 +1,184 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-
-namespace Jackett.Indexers
-{
-    public class GhostCity : BaseIndexer, IIndexer
-    {
-        string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        string BrowsePage { get { return SiteLink + "browse.php"; } }
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public GhostCity(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-                : base(name: "Ghost City",
-                description: "A German general tracker",
-                link: "http://ghostcity.dyndns.info/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "de-de";
-            Type = "private";
-
-            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
-            this.configData.DisplayText.Name = "Notice";
-            AddMultiCategoryMapping(TorznabCatType.TVAnime, 8, 34, 35, 36);
-            AddMultiCategoryMapping(TorznabCatType.TVDocumentary, 12, 44, 106, 45, 46, 47);
-            AddMultiCategoryMapping(TorznabCatType.Console, 92, 93, 95, 96, 97);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleNDS, 92);
-            AddMultiCategoryMapping(TorznabCatType.ConsolePS3, 95);
-            AddMultiCategoryMapping(TorznabCatType.ConsolePS4, 95);
-            AddMultiCategoryMapping(TorznabCatType.ConsolePS4, 95);
-            AddMultiCategoryMapping(TorznabCatType.ConsolePSP, 95);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleXbox, 97);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleXbox360, 97);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleXBOX360DLC, 97);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleXboxOne, 97);
-            AddMultiCategoryMapping(TorznabCatType.ConsoleWii, 96);
-            AddMultiCategoryMapping(TorznabCatType.PC, 20, 94, 40);
-            AddMultiCategoryMapping(TorznabCatType.PCGames, 94);
-            AddMultiCategoryMapping(TorznabCatType.PCMac, 39);
-            AddMultiCategoryMapping(TorznabCatType.PCPhoneOther, 37, 38);
-            AddMultiCategoryMapping(TorznabCatType.TVSport, 22, 98, 99, 100, 101);
-            AddMultiCategoryMapping(TorznabCatType.Movies, 68, 69, 70, 102, 104, 103, 72, 71, 73, 74, 75, 77, 78, 79);
-            AddMultiCategoryMapping(TorznabCatType.MoviesSD, 68, 69, 102, 104, 103, 72, 71, 73, 74);
-            AddMultiCategoryMapping(TorznabCatType.MoviesHD, 75, 76, 77, 78, 79);
-            AddMultiCategoryMapping(TorznabCatType.MoviesOther, 73);
-            AddMultiCategoryMapping(TorznabCatType.MoviesBluRay, 70);
-            AddMultiCategoryMapping(TorznabCatType.MoviesDVD, 102, 104, 103, 72, 71);
-            AddMultiCategoryMapping(TorznabCatType.Movies3D, 69);
-            AddMultiCategoryMapping(TorznabCatType.AudioVideo, 109);
-            AddMultiCategoryMapping(TorznabCatType.TV, 8, 34, 35, 36, 23, 90, 88, 107, 89);
-            AddMultiCategoryMapping(TorznabCatType.TVHD, 107);
-            AddMultiCategoryMapping(TorznabCatType.TVSD, 89);
-            AddMultiCategoryMapping(TorznabCatType.XXX, 25);
-            AddMultiCategoryMapping(TorznabCatType.TVDocumentary, 88);
-            AddMultiCategoryMapping(TorznabCatType.AudioAudiobook, 84);
-            AddMultiCategoryMapping(TorznabCatType.BooksEbook, 83);
-            AddMultiCategoryMapping(TorznabCatType.BooksMagazines, 85);
-            AddMultiCategoryMapping(TorznabCatType.BooksOther, 108);
-            AddMultiCategoryMapping(TorznabCatType.Other, 3, 93, 24);
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value }
-            };
-
-            var result1 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink);
-            CQ result1Dom = result1.Content;
-            var link = result1Dom[".trow2 a"].First();
-            var result2 = await RequestStringWithCookies(link.Attr("href"), result1.Cookies);
-            CQ result2Dom = result2.Content;
-
-            await ConfigureIfOK(result1.Cookies, result2.Content.Contains("/logout.php"), () =>
-            {
-                var errorMessage = "Login failed.";
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowsePage;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("do", "search");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("keywords", searchString);
-            }
-
-            queryCollection.Add("search_type", "t_name");
-
-            // FIXME: Tracker doesn't support multi category search
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("category", cat);
-            }
-
-            if (queryCollection.Count > 0)
-            {
-                searchUrl += "?" + queryCollection.GetQueryString();
-            }
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-
-            try
-            {
-                CQ dom = results.Content;
-
-                var rows = dom["#sortabletable tr"];
-                foreach (var row in rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-                    var qRow = row.Cq();
-                    release.Title = qRow.Find(".tooltip-content div").First().Text();
-                    if (string.IsNullOrWhiteSpace(release.Title))
-                        continue;
-                    release.Description = qRow.Find(".tooltip-content div").Get(1).InnerText.Trim();
-
-                    var qLink = row.Cq().Find("td:eq(2) a:eq(0)");
-                    release.Link = new Uri(qLink.Attr("href"));
-                    release.Guid = release.Link;
-                    release.Comments = new Uri(qRow.Find(".tooltip-target a").First().Attr("href"));
-
-                    var dateString = qRow.Find("td:eq(1) div").Last().Children().Remove().End().Text().Trim();
-                    release.PublishDate = DateTime.ParseExact(dateString, "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture);
-
-                    var sizeStr = qRow.Find("td:eq(4)").Text().Trim();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text().Trim());
-                    release.Peers = ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim()) + release.Seeders;
-
-                    var catLink = row.Cq().Find("td:eq(0) a").First().Attr("href");
-                    var catSplit = catLink.IndexOf("category=");
-                    if (catSplit > -1)
-                    {
-                        catLink = catLink.Substring(catSplit + 9);
-                    }
-
-                    release.Category = MapTrackerCatToNewznab(catLink);
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+
+namespace Jackett.Indexers
+{
+    public class GhostCity : BaseIndexer, IIndexer
+    {
+        string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+        string BrowsePage { get { return SiteLink + "browse.php"; } }
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public GhostCity(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+                : base(name: "Ghost City",
+                description: "A German general tracker",
+                link: "http://ghostcity.dyndns.info/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "de-de";
+            Type = "private";
+
+            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
+            this.configData.DisplayText.Name = "Notice";
+            AddMultiCategoryMapping(TorznabCatType.TVAnime, 8, 34, 35, 36);
+            AddMultiCategoryMapping(TorznabCatType.TVDocumentary, 12, 44, 106, 45, 46, 47);
+            AddMultiCategoryMapping(TorznabCatType.Console, 92, 93, 95, 96, 97);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleNDS, 92);
+            AddMultiCategoryMapping(TorznabCatType.ConsolePS3, 95);
+            AddMultiCategoryMapping(TorznabCatType.ConsolePS4, 95);
+            AddMultiCategoryMapping(TorznabCatType.ConsolePS4, 95);
+            AddMultiCategoryMapping(TorznabCatType.ConsolePSP, 95);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleXbox, 97);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleXbox360, 97);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleXBOX360DLC, 97);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleXboxOne, 97);
+            AddMultiCategoryMapping(TorznabCatType.ConsoleWii, 96);
+            AddMultiCategoryMapping(TorznabCatType.PC, 20, 94, 40);
+            AddMultiCategoryMapping(TorznabCatType.PCGames, 94);
+            AddMultiCategoryMapping(TorznabCatType.PCMac, 39);
+            AddMultiCategoryMapping(TorznabCatType.PCPhoneOther, 37, 38);
+            AddMultiCategoryMapping(TorznabCatType.TVSport, 22, 98, 99, 100, 101);
+            AddMultiCategoryMapping(TorznabCatType.Movies, 68, 69, 70, 102, 104, 103, 72, 71, 73, 74, 75, 77, 78, 79);
+            AddMultiCategoryMapping(TorznabCatType.MoviesSD, 68, 69, 102, 104, 103, 72, 71, 73, 74);
+            AddMultiCategoryMapping(TorznabCatType.MoviesHD, 75, 76, 77, 78, 79);
+            AddMultiCategoryMapping(TorznabCatType.MoviesOther, 73);
+            AddMultiCategoryMapping(TorznabCatType.MoviesBluRay, 70);
+            AddMultiCategoryMapping(TorznabCatType.MoviesDVD, 102, 104, 103, 72, 71);
+            AddMultiCategoryMapping(TorznabCatType.Movies3D, 69);
+            AddMultiCategoryMapping(TorznabCatType.AudioVideo, 109);
+            AddMultiCategoryMapping(TorznabCatType.TV, 8, 34, 35, 36, 23, 90, 88, 107, 89);
+            AddMultiCategoryMapping(TorznabCatType.TVHD, 107);
+            AddMultiCategoryMapping(TorznabCatType.TVSD, 89);
+            AddMultiCategoryMapping(TorznabCatType.XXX, 25);
+            AddMultiCategoryMapping(TorznabCatType.TVDocumentary, 88);
+            AddMultiCategoryMapping(TorznabCatType.AudioAudiobook, 84);
+            AddMultiCategoryMapping(TorznabCatType.BooksEbook, 83);
+            AddMultiCategoryMapping(TorznabCatType.BooksMagazines, 85);
+            AddMultiCategoryMapping(TorznabCatType.BooksOther, 108);
+            AddMultiCategoryMapping(TorznabCatType.Other, 3, 93, 24);
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value }
+            };
+
+            var result1 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink);
+            CQ result1Dom = result1.Content;
+            var link = result1Dom[".trow2 a"].First();
+            var result2 = await RequestStringWithCookies(link.Attr("href"), result1.Cookies);
+            CQ result2Dom = result2.Content;
+
+            await ConfigureIfOK(result1.Cookies, result2.Content.Contains("/logout.php"), () =>
+            {
+                var errorMessage = "Login failed.";
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowsePage;
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("do", "search");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("keywords", searchString);
+            }
+
+            queryCollection.Add("search_type", "t_name");
+
+            // FIXME: Tracker doesn't support multi category search
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("category", cat);
+            }
+
+            if (queryCollection.Count > 0)
+            {
+                searchUrl += "?" + queryCollection.GetQueryString();
+            }
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+
+            try
+            {
+                CQ dom = results.Content;
+
+                var rows = dom["#sortabletable tr"];
+                foreach (var row in rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+                    var qRow = row.Cq();
+                    release.Title = qRow.Find(".tooltip-content div").First().Text();
+                    if (string.IsNullOrWhiteSpace(release.Title))
+                        continue;
+                    release.Description = qRow.Find(".tooltip-content div").Get(1).InnerText.Trim();
+
+                    var qLink = row.Cq().Find("td:eq(2) a:eq(0)");
+                    release.Link = new Uri(qLink.Attr("href"));
+                    release.Guid = release.Link;
+                    release.Comments = new Uri(qRow.Find(".tooltip-target a").First().Attr("href"));
+
+                    var dateString = qRow.Find("td:eq(1) div").Last().Children().Remove().End().Text().Trim();
+                    release.PublishDate = DateTime.ParseExact(dateString, "dd-MM-yyyy HH:mm", CultureInfo.InvariantCulture);
+
+                    var sizeStr = qRow.Find("td:eq(4)").Text().Trim();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text().Trim());
+                    release.Peers = ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim()) + release.Seeders;
+
+                    var catLink = row.Cq().Find("td:eq(0) a").First().Attr("href");
+                    var catSplit = catLink.IndexOf("category=");
+                    if (catSplit > -1)
+                    {
+                        catLink = catLink.Substring(catSplit + 9);
+                    }
+
+                    release.Category = MapTrackerCatToNewznab(catLink);
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/HD4Free.cs b/src/Jackett/Indexers/HD4Free.cs
index 0ca5fa83e41dce135e134844347504b2e28197a4..027d8646fb0732a91df74ddeec457754bb4f9b02 100644
--- a/src/Jackett/Indexers/HD4Free.cs
+++ b/src/Jackett/Indexers/HD4Free.cs
@@ -1,367 +1,367 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-
-using AngleSharp.Parser.Html;
-
-namespace Jackett.Indexers
-{
-    public class HD4Free : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "ajax/initial_recall.php"; } }
-        private string LoginUrl { get { return SiteLink + "login.php"; } }
-        private string TakeLoginUrl { get { return SiteLink + "takelogin.php"; } }
-
-        new ConfigurationDataRecaptchaLogin configData
-        {
-            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public HD4Free(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "HD4Free",
-                description: "A HD trackers",
-                link: "https://hd4free.xyz/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataRecaptchaLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(42, TorznabCatType.MoviesSD); // LEGi0N 480p
-            AddCategoryMapping(17, TorznabCatType.MoviesHD); // LEGi0N  720p 
-            AddCategoryMapping(16, TorznabCatType.MoviesHD); // LEGi0N  1080p 
-            AddCategoryMapping(84, TorznabCatType.Movies3D); // LEGi0N 3D 1080p
-            AddCategoryMapping(31, TorznabCatType.MoviesOther); // LEGi0N  REMUX
-            AddCategoryMapping(70, TorznabCatType.MoviesBluRay); // LEGi0N BD BD25 & BD50
-            AddCategoryMapping(55, TorznabCatType.Movies); // LEGi0N  Movie/TV PACKS
-            AddCategoryMapping(60, TorznabCatType.Other); // shadz shack
-            AddCategoryMapping(85, TorznabCatType.MoviesHD); // MarGe 720p
-            AddCategoryMapping(86, TorznabCatType.MoviesHD); // MarGe 1080p
-            AddCategoryMapping(73, TorznabCatType.MoviesBluRay); // GF44 BD-50
-            AddCategoryMapping(74, TorznabCatType.MoviesBluRay); // GF44 BD-25
-            AddCategoryMapping(88, TorznabCatType.MoviesBluRay); // taterzero BD50
-            AddCategoryMapping(89, TorznabCatType.MoviesBluRay); // taterzero BD25
-            AddCategoryMapping(90, TorznabCatType.Movies3D); // taterzero 3D BD
-            AddCategoryMapping(39, TorznabCatType.MoviesBluRay); // Bluray REMUX
-            AddCategoryMapping(38, TorznabCatType.MoviesBluRay); // Bluray 
-            AddCategoryMapping(75, TorznabCatType.MoviesBluRay); // Bluray 25
-            AddCategoryMapping(36, TorznabCatType.MoviesHD); // Encodes 720p
-            AddCategoryMapping(35, TorznabCatType.MoviesHD); // Encodes 1080p
-            AddCategoryMapping(45, TorznabCatType.Movies3D); // 1080p 3D Encodes
-            AddCategoryMapping(77, TorznabCatType.MoviesHD); // WEB-DL 720p
-            AddCategoryMapping(78, TorznabCatType.MoviesHD); // WEB-DL 1080p
-            AddCategoryMapping(83, TorznabCatType.MoviesDVD); // DVD 5/9's
-            AddCategoryMapping(47, TorznabCatType.Movies); // General x264
-            AddCategoryMapping(58, TorznabCatType.Movies); // General XViD
-            AddCategoryMapping(66, TorznabCatType.Movies); // x265 HEVC
-            AddCategoryMapping(34, TorznabCatType.MoviesHD); // 4K
-            AddCategoryMapping(61, TorznabCatType.Movies); // MOViE PACKS
-            AddCategoryMapping(44, TorznabCatType.TVHD); // HDTV 720p
-            AddCategoryMapping(43, TorznabCatType.TVHD); // HDTV 1080p
-            AddCategoryMapping(41, TorznabCatType.TVHD); // WEB-DL 720p TV
-            AddCategoryMapping(40, TorznabCatType.TVHD); // WEB-DL 1080p TV
-            AddCategoryMapping(52, TorznabCatType.TVHD); // 720p TV BluRay
-            AddCategoryMapping(53, TorznabCatType.TVHD); // 1080p TV BluRay
-            AddCategoryMapping(62, TorznabCatType.TVHD); // HDTV Packs
-            AddCategoryMapping(82, TorznabCatType.TVSD); // SDTV TV PACKS
-            AddCategoryMapping(63, TorznabCatType.PC0day); // Apps Windows
-            AddCategoryMapping(57, TorznabCatType.PCMac); // Appz Mac
-            AddCategoryMapping(72, TorznabCatType.AudioAudiobook); // Audio Books
-            AddCategoryMapping(71, TorznabCatType.Books); // Ebooks
-            AddCategoryMapping(46, TorznabCatType.AudioLossless); // FLAC/Lossless
-            AddCategoryMapping(81, TorznabCatType.AudioMP3); // MP3 Music
-            AddCategoryMapping(87, TorznabCatType.AudioVideo); // HD MUSiC ViDEOS
-            AddCategoryMapping(32, TorznabCatType.Other); // Covers And Artwork
-            AddCategoryMapping(50, TorznabCatType.XXX); // Porn XXX
-        }
-
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, configData.CookieHeader.Value);
-            CQ cq = loginPage.Content;
-            string recaptchaSiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
-            var result = this.configData;
-            result.CookieHeader.Value = loginPage.Cookies;
-            result.Captcha.SiteKey = recaptchaSiteKey;
-            result.Captcha.Version = "2";
-            return result;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "returnto" , "/" },
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "g-recaptcha-response", configData.Captcha.Value },
-                { "submitme", "Login" }
-            };
-
-            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
-            {
-                // Cookie was manually supplied
-                CookieHeader = configData.Captcha.Cookie;
-                try
-                {
-                    var results = await PerformQuery(new TorznabQuery());
-                    if (!results.Any())
-                    {
-                        throw new Exception("Your cookie did not work");
-                    }
-
-                    SaveConfig();
-                    IsConfigured = true;
-                    return IndexerConfigurationStatus.Completed;
-                }
-                catch (Exception e)
-                {
-                    IsConfigured = false;
-                    throw new Exception("Your cookie did not work: " + e.Message);
-                }
-            }
-
-            var result = await RequestLoginAndFollowRedirect(TakeLoginUrl, pairs, null, true, SiteLink, LoginUrl);
-
-            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var messageEl = dom["table.main > tbody > tr > td > table > tbody > tr > td"];
-                var errorMessage = messageEl.Text().Trim();
-                if (string.IsNullOrWhiteSpace(errorMessage))
-                    errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var pairs = new Dictionary<string, string>();
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-
-            pairs.Add("draw", "1");
-            pairs.Add("columns[0][data]", "");
-            pairs.Add("columns[0][name]", "");
-            pairs.Add("columns[0][searchable]", "false");
-            pairs.Add("columns[0][orderable]", "false");
-            pairs.Add("columns[0][search][value]", "");
-            pairs.Add("columns[0][search][regex]", "false");
-            pairs.Add("columns[1][data]", "id");
-            pairs.Add("columns[1][name]", "");
-            pairs.Add("columns[1][searchable]", "false");
-            pairs.Add("columns[1][orderable]", "true");
-            pairs.Add("columns[1][search][value]", "");
-            pairs.Add("columns[1][search][regex]", "false");
-            pairs.Add("columns[2][data]", "cat");
-            pairs.Add("columns[2][name]", "");
-            pairs.Add("columns[2][searchable]", "false");
-            pairs.Add("columns[2][orderable]", "true");
-            pairs.Add("columns[2][search][value]", "");
-            pairs.Add("columns[2][search][regex]", "false");
-            pairs.Add("columns[3][data]", "name");
-            pairs.Add("columns[3][name]", "");
-            pairs.Add("columns[3][searchable]", "true");
-            pairs.Add("columns[3][orderable]", "true");
-            pairs.Add("columns[3][search][value]", "");
-            pairs.Add("columns[3][search][regex]", "false");
-            pairs.Add("columns[4][data]", "username");
-            pairs.Add("columns[4][name]", "");
-            pairs.Add("columns[4][searchable]", "true");
-            pairs.Add("columns[4][orderable]", "true");
-            pairs.Add("columns[4][search][value]", "");
-            pairs.Add("columns[4][search][regex]", "false");
-            pairs.Add("columns[5][data]", "cat-image");
-            pairs.Add("columns[5][name]", "");
-            pairs.Add("columns[5][searchable]", "false");
-            pairs.Add("columns[5][orderable]", "true");
-            pairs.Add("columns[5][search][value]", "");
-            pairs.Add("columns[5][search][regex]", "false");
-            pairs.Add("columns[6][data]", "cat-name");
-            pairs.Add("columns[6][name]", "");
-            pairs.Add("columns[6][searchable]", "false");
-            pairs.Add("columns[6][orderable]", "true");
-            pairs.Add("columns[6][search][value]", "");
-            pairs.Add("columns[6][search][regex]", "false");
-            pairs.Add("columns[7][data]", "imdbid");
-            pairs.Add("columns[7][name]", "");
-            pairs.Add("columns[7][searchable]", "true");
-            pairs.Add("columns[7][orderable]", "true");
-            pairs.Add("columns[7][search][value]", "");
-            pairs.Add("columns[7][search][regex]", "false");
-            pairs.Add("columns[8][data]", "genre");
-            pairs.Add("columns[8][name]", "");
-            pairs.Add("columns[8][searchable]", "false");
-            pairs.Add("columns[8][orderable]", "true");
-            pairs.Add("columns[8][search][value]", "");
-            pairs.Add("columns[8][search][regex]", "false");
-            pairs.Add("columns[9][data]", "added");
-            pairs.Add("columns[9][name]", "");
-            pairs.Add("columns[9][searchable]", "false");
-            pairs.Add("columns[9][orderable]", "true");
-            pairs.Add("columns[9][search][value]", "");
-            pairs.Add("columns[9][search][regex]", "false");
-            pairs.Add("columns[10][data]", "size");
-            pairs.Add("columns[10][name]", "");
-            pairs.Add("columns[10][searchable]", "false");
-            pairs.Add("columns[10][orderable]", "true");
-            pairs.Add("columns[10][search][value]", "");
-            pairs.Add("columns[10][search][regex]", "false");
-            pairs.Add("columns[11][data]", "rating");
-            pairs.Add("columns[11][name]", "");
-            pairs.Add("columns[11][searchable]", "false");
-            pairs.Add("columns[11][orderable]", "true");
-            pairs.Add("columns[11][search][value]", "");
-            pairs.Add("columns[11][search][regex]", "false");
-            pairs.Add("columns[12][data]", "comments");
-            pairs.Add("columns[12][name]", "");
-            pairs.Add("columns[12][searchable]", "false");
-            pairs.Add("columns[12][orderable]", "true");
-            pairs.Add("columns[12][search][value]", "");
-            pairs.Add("columns[12][search][regex]", "false");
-            pairs.Add("columns[13][data]", "numfiles");
-            pairs.Add("columns[13][name]", "");
-            pairs.Add("columns[13][searchable]", "false");
-            pairs.Add("columns[13][orderable]", "true");
-            pairs.Add("columns[13][search][value]", "");
-            pairs.Add("columns[13][search][regex]", "false");
-            pairs.Add("columns[14][data]", "seeders");
-            pairs.Add("columns[14][name]", "");
-            pairs.Add("columns[14][searchable]", "false");
-            pairs.Add("columns[14][orderable]", "true");
-            pairs.Add("columns[14][search][value]", "");
-            pairs.Add("columns[14][search][regex]", "false");
-            pairs.Add("columns[15][data]", "leechers");
-            pairs.Add("columns[15][name]", "");
-            pairs.Add("columns[15][searchable]", "false");
-            pairs.Add("columns[15][orderable]", "true");
-            pairs.Add("columns[15][search][value]", "");
-            pairs.Add("columns[15][search][regex]", "false");
-            pairs.Add("columns[16][data]", "to_go");
-            pairs.Add("columns[16][name]", "");
-            pairs.Add("columns[16][searchable]", "false");
-            pairs.Add("columns[16][orderable]", "true");
-            pairs.Add("columns[16][search][value]", "");
-            pairs.Add("columns[16][search][regex]", "false");
-            pairs.Add("columns[17][data]", "genre");
-            pairs.Add("columns[17][name]", "");
-            pairs.Add("columns[17][searchable]", "true");
-            pairs.Add("columns[17][orderable]", "true");
-            pairs.Add("columns[17][search][value]", "");
-            pairs.Add("columns[17][search][regex]", "false");
-            pairs.Add("order[0][column]", "9");
-            pairs.Add("order[0][dir]", "desc");
-            pairs.Add("start", "0");
-            pairs.Add("length", "100");
-            pairs.Add("visible", "1");
-            pairs.Add("uid", "-1");
-            pairs.Add("genre", "");
-            
-            pairs.Add("cats", string.Join(",+", MapTorznabCapsToTrackers(query)));
-
-            if (query.ImdbID != null)
-            {
-                pairs.Add("search[value]", query.ImdbID);
-                pairs.Add("search[regex]", "false");
-            }
-            else if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                pairs.Add("search[value]", searchString);
-                pairs.Add("search[regex]", "false");
-            }
-
-            var results = await PostDataWithCookiesAndRetry(searchUrl, pairs);
-
-            try
-            {
-                var json = JObject.Parse(results.Content);
-                foreach (var row in json["data"])
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 72 * 24 * 60 * 60;
-
-                    var hParser = new HtmlParser();
-                    var hName = hParser.Parse(row["name"].ToString());
-                    var hComments = hParser.Parse(row["comments"].ToString());
-                    var hNumfiles = hParser.Parse(row["numfiles"].ToString());
-                    var hSeeders = hParser.Parse(row["seeders"].ToString());
-                    var hLeechers = hParser.Parse(row["leechers"].ToString());
-
-                    var hDetailsLink = hName.QuerySelector("a[href^=\"details.php?id=\"]");
-                    var hCommentsLink = hComments.QuerySelector("a");
-                    var hDownloadLink = hName.QuerySelector("a[title=\"Download Torrent\"]");
-
-                    release.Title = hDetailsLink.TextContent;
-                    if (query.ImdbID == null && !query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    release.Comments = new Uri(SiteLink + hCommentsLink.GetAttribute("href"));
-                    release.Link = new Uri(SiteLink + hDownloadLink.GetAttribute("href"));
-                    release.Guid = release.Link;
-
-                    release.Description = row["genre"].ToString();
-
-                    var poster = row["poster"].ToString();
-                    if(!string.IsNullOrWhiteSpace(poster))
-                    {
-                        var posterurl = poster;
-                        if (!poster.StartsWith("http"))
-                            posterurl = SiteLink + poster;
-                        release.BannerUrl = new Uri(posterurl);
-                    }
-
-                    release.Size = ReleaseInfo.GetBytes(row["size"].ToString());
-                    var imdbId = row["imdbid"].ToString();
-                    if (imdbId.StartsWith("tt"))
-                        release.Imdb = ParseUtil.CoerceLong(imdbId.Substring(2));
-
-                    var added = row["added"].ToString().Replace("<br>", " ");
-                    release.PublishDate = DateTimeUtil.FromUnknown(added);
-
-                    var catid = row["catid"].ToString();
-                    release.Category = MapTrackerCatToNewznab(catid);
-
-                    release.Seeders = ParseUtil.CoerceInt(hSeeders.QuerySelector("a").TextContent);
-                    release.Peers = ParseUtil.CoerceInt(hLeechers.QuerySelector("a").TextContent) + release.Seeders;
-
-                    release.Files = ParseUtil.CoerceInt(hNumfiles.QuerySelector("a").TextContent);
-
-                    release.DownloadVolumeFactor = 1;
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                    
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+
+using AngleSharp.Parser.Html;
+
+namespace Jackett.Indexers
+{
+    public class HD4Free : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "ajax/initial_recall.php"; } }
+        private string LoginUrl { get { return SiteLink + "login.php"; } }
+        private string TakeLoginUrl { get { return SiteLink + "takelogin.php"; } }
+
+        new ConfigurationDataRecaptchaLogin configData
+        {
+            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public HD4Free(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "HD4Free",
+                description: "A HD trackers",
+                link: "https://hd4free.xyz/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataRecaptchaLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(42, TorznabCatType.MoviesSD); // LEGi0N 480p
+            AddCategoryMapping(17, TorznabCatType.MoviesHD); // LEGi0N  720p 
+            AddCategoryMapping(16, TorznabCatType.MoviesHD); // LEGi0N  1080p 
+            AddCategoryMapping(84, TorznabCatType.Movies3D); // LEGi0N 3D 1080p
+            AddCategoryMapping(31, TorznabCatType.MoviesOther); // LEGi0N  REMUX
+            AddCategoryMapping(70, TorznabCatType.MoviesBluRay); // LEGi0N BD BD25 & BD50
+            AddCategoryMapping(55, TorznabCatType.Movies); // LEGi0N  Movie/TV PACKS
+            AddCategoryMapping(60, TorznabCatType.Other); // shadz shack
+            AddCategoryMapping(85, TorznabCatType.MoviesHD); // MarGe 720p
+            AddCategoryMapping(86, TorznabCatType.MoviesHD); // MarGe 1080p
+            AddCategoryMapping(73, TorznabCatType.MoviesBluRay); // GF44 BD-50
+            AddCategoryMapping(74, TorznabCatType.MoviesBluRay); // GF44 BD-25
+            AddCategoryMapping(88, TorznabCatType.MoviesBluRay); // taterzero BD50
+            AddCategoryMapping(89, TorznabCatType.MoviesBluRay); // taterzero BD25
+            AddCategoryMapping(90, TorznabCatType.Movies3D); // taterzero 3D BD
+            AddCategoryMapping(39, TorznabCatType.MoviesBluRay); // Bluray REMUX
+            AddCategoryMapping(38, TorznabCatType.MoviesBluRay); // Bluray 
+            AddCategoryMapping(75, TorznabCatType.MoviesBluRay); // Bluray 25
+            AddCategoryMapping(36, TorznabCatType.MoviesHD); // Encodes 720p
+            AddCategoryMapping(35, TorznabCatType.MoviesHD); // Encodes 1080p
+            AddCategoryMapping(45, TorznabCatType.Movies3D); // 1080p 3D Encodes
+            AddCategoryMapping(77, TorznabCatType.MoviesHD); // WEB-DL 720p
+            AddCategoryMapping(78, TorznabCatType.MoviesHD); // WEB-DL 1080p
+            AddCategoryMapping(83, TorznabCatType.MoviesDVD); // DVD 5/9's
+            AddCategoryMapping(47, TorznabCatType.Movies); // General x264
+            AddCategoryMapping(58, TorznabCatType.Movies); // General XViD
+            AddCategoryMapping(66, TorznabCatType.Movies); // x265 HEVC
+            AddCategoryMapping(34, TorznabCatType.MoviesHD); // 4K
+            AddCategoryMapping(61, TorznabCatType.Movies); // MOViE PACKS
+            AddCategoryMapping(44, TorznabCatType.TVHD); // HDTV 720p
+            AddCategoryMapping(43, TorznabCatType.TVHD); // HDTV 1080p
+            AddCategoryMapping(41, TorznabCatType.TVHD); // WEB-DL 720p TV
+            AddCategoryMapping(40, TorznabCatType.TVHD); // WEB-DL 1080p TV
+            AddCategoryMapping(52, TorznabCatType.TVHD); // 720p TV BluRay
+            AddCategoryMapping(53, TorznabCatType.TVHD); // 1080p TV BluRay
+            AddCategoryMapping(62, TorznabCatType.TVHD); // HDTV Packs
+            AddCategoryMapping(82, TorznabCatType.TVSD); // SDTV TV PACKS
+            AddCategoryMapping(63, TorznabCatType.PC0day); // Apps Windows
+            AddCategoryMapping(57, TorznabCatType.PCMac); // Appz Mac
+            AddCategoryMapping(72, TorznabCatType.AudioAudiobook); // Audio Books
+            AddCategoryMapping(71, TorznabCatType.Books); // Ebooks
+            AddCategoryMapping(46, TorznabCatType.AudioLossless); // FLAC/Lossless
+            AddCategoryMapping(81, TorznabCatType.AudioMP3); // MP3 Music
+            AddCategoryMapping(87, TorznabCatType.AudioVideo); // HD MUSiC ViDEOS
+            AddCategoryMapping(32, TorznabCatType.Other); // Covers And Artwork
+            AddCategoryMapping(50, TorznabCatType.XXX); // Porn XXX
+        }
+
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, configData.CookieHeader.Value);
+            CQ cq = loginPage.Content;
+            string recaptchaSiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
+            var result = this.configData;
+            result.CookieHeader.Value = loginPage.Cookies;
+            result.Captcha.SiteKey = recaptchaSiteKey;
+            result.Captcha.Version = "2";
+            return result;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "returnto" , "/" },
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "g-recaptcha-response", configData.Captcha.Value },
+                { "submitme", "Login" }
+            };
+
+            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
+            {
+                // Cookie was manually supplied
+                CookieHeader = configData.Captcha.Cookie;
+                try
+                {
+                    var results = await PerformQuery(new TorznabQuery());
+                    if (!results.Any())
+                    {
+                        throw new Exception("Your cookie did not work");
+                    }
+
+                    SaveConfig();
+                    IsConfigured = true;
+                    return IndexerConfigurationStatus.Completed;
+                }
+                catch (Exception e)
+                {
+                    IsConfigured = false;
+                    throw new Exception("Your cookie did not work: " + e.Message);
+                }
+            }
+
+            var result = await RequestLoginAndFollowRedirect(TakeLoginUrl, pairs, null, true, SiteLink, LoginUrl);
+
+            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var messageEl = dom["table.main > tbody > tr > td > table > tbody > tr > td"];
+                var errorMessage = messageEl.Text().Trim();
+                if (string.IsNullOrWhiteSpace(errorMessage))
+                    errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var pairs = new Dictionary<string, string>();
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+
+            pairs.Add("draw", "1");
+            pairs.Add("columns[0][data]", "");
+            pairs.Add("columns[0][name]", "");
+            pairs.Add("columns[0][searchable]", "false");
+            pairs.Add("columns[0][orderable]", "false");
+            pairs.Add("columns[0][search][value]", "");
+            pairs.Add("columns[0][search][regex]", "false");
+            pairs.Add("columns[1][data]", "id");
+            pairs.Add("columns[1][name]", "");
+            pairs.Add("columns[1][searchable]", "false");
+            pairs.Add("columns[1][orderable]", "true");
+            pairs.Add("columns[1][search][value]", "");
+            pairs.Add("columns[1][search][regex]", "false");
+            pairs.Add("columns[2][data]", "cat");
+            pairs.Add("columns[2][name]", "");
+            pairs.Add("columns[2][searchable]", "false");
+            pairs.Add("columns[2][orderable]", "true");
+            pairs.Add("columns[2][search][value]", "");
+            pairs.Add("columns[2][search][regex]", "false");
+            pairs.Add("columns[3][data]", "name");
+            pairs.Add("columns[3][name]", "");
+            pairs.Add("columns[3][searchable]", "true");
+            pairs.Add("columns[3][orderable]", "true");
+            pairs.Add("columns[3][search][value]", "");
+            pairs.Add("columns[3][search][regex]", "false");
+            pairs.Add("columns[4][data]", "username");
+            pairs.Add("columns[4][name]", "");
+            pairs.Add("columns[4][searchable]", "true");
+            pairs.Add("columns[4][orderable]", "true");
+            pairs.Add("columns[4][search][value]", "");
+            pairs.Add("columns[4][search][regex]", "false");
+            pairs.Add("columns[5][data]", "cat-image");
+            pairs.Add("columns[5][name]", "");
+            pairs.Add("columns[5][searchable]", "false");
+            pairs.Add("columns[5][orderable]", "true");
+            pairs.Add("columns[5][search][value]", "");
+            pairs.Add("columns[5][search][regex]", "false");
+            pairs.Add("columns[6][data]", "cat-name");
+            pairs.Add("columns[6][name]", "");
+            pairs.Add("columns[6][searchable]", "false");
+            pairs.Add("columns[6][orderable]", "true");
+            pairs.Add("columns[6][search][value]", "");
+            pairs.Add("columns[6][search][regex]", "false");
+            pairs.Add("columns[7][data]", "imdbid");
+            pairs.Add("columns[7][name]", "");
+            pairs.Add("columns[7][searchable]", "true");
+            pairs.Add("columns[7][orderable]", "true");
+            pairs.Add("columns[7][search][value]", "");
+            pairs.Add("columns[7][search][regex]", "false");
+            pairs.Add("columns[8][data]", "genre");
+            pairs.Add("columns[8][name]", "");
+            pairs.Add("columns[8][searchable]", "false");
+            pairs.Add("columns[8][orderable]", "true");
+            pairs.Add("columns[8][search][value]", "");
+            pairs.Add("columns[8][search][regex]", "false");
+            pairs.Add("columns[9][data]", "added");
+            pairs.Add("columns[9][name]", "");
+            pairs.Add("columns[9][searchable]", "false");
+            pairs.Add("columns[9][orderable]", "true");
+            pairs.Add("columns[9][search][value]", "");
+            pairs.Add("columns[9][search][regex]", "false");
+            pairs.Add("columns[10][data]", "size");
+            pairs.Add("columns[10][name]", "");
+            pairs.Add("columns[10][searchable]", "false");
+            pairs.Add("columns[10][orderable]", "true");
+            pairs.Add("columns[10][search][value]", "");
+            pairs.Add("columns[10][search][regex]", "false");
+            pairs.Add("columns[11][data]", "rating");
+            pairs.Add("columns[11][name]", "");
+            pairs.Add("columns[11][searchable]", "false");
+            pairs.Add("columns[11][orderable]", "true");
+            pairs.Add("columns[11][search][value]", "");
+            pairs.Add("columns[11][search][regex]", "false");
+            pairs.Add("columns[12][data]", "comments");
+            pairs.Add("columns[12][name]", "");
+            pairs.Add("columns[12][searchable]", "false");
+            pairs.Add("columns[12][orderable]", "true");
+            pairs.Add("columns[12][search][value]", "");
+            pairs.Add("columns[12][search][regex]", "false");
+            pairs.Add("columns[13][data]", "numfiles");
+            pairs.Add("columns[13][name]", "");
+            pairs.Add("columns[13][searchable]", "false");
+            pairs.Add("columns[13][orderable]", "true");
+            pairs.Add("columns[13][search][value]", "");
+            pairs.Add("columns[13][search][regex]", "false");
+            pairs.Add("columns[14][data]", "seeders");
+            pairs.Add("columns[14][name]", "");
+            pairs.Add("columns[14][searchable]", "false");
+            pairs.Add("columns[14][orderable]", "true");
+            pairs.Add("columns[14][search][value]", "");
+            pairs.Add("columns[14][search][regex]", "false");
+            pairs.Add("columns[15][data]", "leechers");
+            pairs.Add("columns[15][name]", "");
+            pairs.Add("columns[15][searchable]", "false");
+            pairs.Add("columns[15][orderable]", "true");
+            pairs.Add("columns[15][search][value]", "");
+            pairs.Add("columns[15][search][regex]", "false");
+            pairs.Add("columns[16][data]", "to_go");
+            pairs.Add("columns[16][name]", "");
+            pairs.Add("columns[16][searchable]", "false");
+            pairs.Add("columns[16][orderable]", "true");
+            pairs.Add("columns[16][search][value]", "");
+            pairs.Add("columns[16][search][regex]", "false");
+            pairs.Add("columns[17][data]", "genre");
+            pairs.Add("columns[17][name]", "");
+            pairs.Add("columns[17][searchable]", "true");
+            pairs.Add("columns[17][orderable]", "true");
+            pairs.Add("columns[17][search][value]", "");
+            pairs.Add("columns[17][search][regex]", "false");
+            pairs.Add("order[0][column]", "9");
+            pairs.Add("order[0][dir]", "desc");
+            pairs.Add("start", "0");
+            pairs.Add("length", "100");
+            pairs.Add("visible", "1");
+            pairs.Add("uid", "-1");
+            pairs.Add("genre", "");
+            
+            pairs.Add("cats", string.Join(",+", MapTorznabCapsToTrackers(query)));
+
+            if (query.ImdbID != null)
+            {
+                pairs.Add("search[value]", query.ImdbID);
+                pairs.Add("search[regex]", "false");
+            }
+            else if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                pairs.Add("search[value]", searchString);
+                pairs.Add("search[regex]", "false");
+            }
+
+            var results = await PostDataWithCookiesAndRetry(searchUrl, pairs);
+
+            try
+            {
+                var json = JObject.Parse(results.Content);
+                foreach (var row in json["data"])
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 72 * 24 * 60 * 60;
+
+                    var hParser = new HtmlParser();
+                    var hName = hParser.Parse(row["name"].ToString());
+                    var hComments = hParser.Parse(row["comments"].ToString());
+                    var hNumfiles = hParser.Parse(row["numfiles"].ToString());
+                    var hSeeders = hParser.Parse(row["seeders"].ToString());
+                    var hLeechers = hParser.Parse(row["leechers"].ToString());
+
+                    var hDetailsLink = hName.QuerySelector("a[href^=\"details.php?id=\"]");
+                    var hCommentsLink = hComments.QuerySelector("a");
+                    var hDownloadLink = hName.QuerySelector("a[title=\"Download Torrent\"]");
+
+                    release.Title = hDetailsLink.TextContent;
+                    if (query.ImdbID == null && !query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    release.Comments = new Uri(SiteLink + hCommentsLink.GetAttribute("href"));
+                    release.Link = new Uri(SiteLink + hDownloadLink.GetAttribute("href"));
+                    release.Guid = release.Link;
+
+                    release.Description = row["genre"].ToString();
+
+                    var poster = row["poster"].ToString();
+                    if(!string.IsNullOrWhiteSpace(poster))
+                    {
+                        var posterurl = poster;
+                        if (!poster.StartsWith("http"))
+                            posterurl = SiteLink + poster;
+                        release.BannerUrl = new Uri(posterurl);
+                    }
+
+                    release.Size = ReleaseInfo.GetBytes(row["size"].ToString());
+                    var imdbId = row["imdbid"].ToString();
+                    if (imdbId.StartsWith("tt"))
+                        release.Imdb = ParseUtil.CoerceLong(imdbId.Substring(2));
+
+                    var added = row["added"].ToString().Replace("<br>", " ");
+                    release.PublishDate = DateTimeUtil.FromUnknown(added);
+
+                    var catid = row["catid"].ToString();
+                    release.Category = MapTrackerCatToNewznab(catid);
+
+                    release.Seeders = ParseUtil.CoerceInt(hSeeders.QuerySelector("a").TextContent);
+                    release.Peers = ParseUtil.CoerceInt(hLeechers.QuerySelector("a").TextContent) + release.Seeders;
+
+                    release.Files = ParseUtil.CoerceInt(hNumfiles.QuerySelector("a").TextContent);
+
+                    release.DownloadVolumeFactor = 1;
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                    
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/HDOnly.cs b/src/Jackett/Indexers/HDOnly.cs
index 93b2d98c8e5b62a4c2ca290731425cc88ba51be2..8277a8065b8e2d9884ee8d2ec6259a196bf96699 100644
--- a/src/Jackett/Indexers/HDOnly.cs
+++ b/src/Jackett/Indexers/HDOnly.cs
@@ -2,11 +2,11 @@
 using NLog;
 using Jackett.Services;
 using Jackett.Utils.Clients;
-using Jackett.Indexers.Abstract;
-using Newtonsoft.Json.Linq;
-using System.Collections.Generic;
-using System.Web;
-
+using Jackett.Indexers.Abstract;
+using Newtonsoft.Json.Linq;
+using System.Collections.Generic;
+using System.Web;
+
 namespace Jackett.Indexers
 {
     public class HDOnly : GazelleTracker, IIndexer
@@ -28,36 +28,36 @@ namespace Jackett.Indexers
             AddCategoryMapping(null, TorznabCatType.TV, "Séries");
 
             // releaseType mappings
-            AddCategoryMapping(1, TorznabCatType.Movies, "Film");
-            AddCategoryMapping(3, TorznabCatType.TVAnime, "Dessin animé");
-            AddCategoryMapping(5, TorznabCatType.TV, "Série");
-            AddCategoryMapping(6, TorznabCatType.TVAnime, "Série Animée");
-            AddCategoryMapping(7, TorznabCatType.MoviesOther, "Film d'animation");
-            AddCategoryMapping(9, TorznabCatType.AudioVideo, "Concert");
-            AddCategoryMapping(11, TorznabCatType.TVDocumentary, "Documentaire");
-            AddCategoryMapping(13, TorznabCatType.MoviesOther, "Court-métrage");
-            AddCategoryMapping(14, TorznabCatType.MoviesOther, "Clip");
-            AddCategoryMapping(15, TorznabCatType.MoviesOther, "Démonstration");
-            AddCategoryMapping(16, TorznabCatType.MoviesOther, "Bonus de BD");
-            AddCategoryMapping(21, TorznabCatType.Other, "Autre");
+            AddCategoryMapping(1, TorznabCatType.Movies, "Film");
+            AddCategoryMapping(3, TorznabCatType.TVAnime, "Dessin animé");
+            AddCategoryMapping(5, TorznabCatType.TV, "Série");
+            AddCategoryMapping(6, TorznabCatType.TVAnime, "Série Animée");
+            AddCategoryMapping(7, TorznabCatType.MoviesOther, "Film d'animation");
+            AddCategoryMapping(9, TorznabCatType.AudioVideo, "Concert");
+            AddCategoryMapping(11, TorznabCatType.TVDocumentary, "Documentaire");
+            AddCategoryMapping(13, TorznabCatType.MoviesOther, "Court-métrage");
+            AddCategoryMapping(14, TorznabCatType.MoviesOther, "Clip");
+            AddCategoryMapping(15, TorznabCatType.MoviesOther, "Démonstration");
+            AddCategoryMapping(16, TorznabCatType.MoviesOther, "Bonus de BD");
+            AddCategoryMapping(21, TorznabCatType.Other, "Autre");
         }
 
-        protected override bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result)
-        {
-            // releaseType is used for categories
-            var category = (string)result["category"];
-            if (category == null)
-            {
-                var releaseType = (string)result["releaseType"];
-                release.Category = MapTrackerCatDescToNewznab(releaseType);
-            }
-            return true;
+        protected override bool ReleaseInfoPostParse(ReleaseInfo release, JObject torrent, JObject result)
+        {
+            // releaseType is used for categories
+            var category = (string)result["category"];
+            if (category == null)
+            {
+                var releaseType = (string)result["releaseType"];
+                release.Category = MapTrackerCatDescToNewznab(releaseType);
+            }
+            return true;
         }
 
-        protected override List<string> MapTorznabCapsToTrackers(TorznabQuery query, bool mapChildrenCatsToParent = false)
-        {
-            // don't use category filtering
-            return new List<string>();
+        protected override List<string> MapTorznabCapsToTrackers(TorznabQuery query, bool mapChildrenCatsToParent = false)
+        {
+            // don't use category filtering
+            return new List<string>();
         }
     }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/HDSpace.cs b/src/Jackett/Indexers/HDSpace.cs
index 274dd60a0d1826efacf5adf7268a399c61abbda2..dc04d3185a5d90df3d330e10dbb23f5df67eb20d 100644
--- a/src/Jackett/Indexers/HDSpace.cs
+++ b/src/Jackett/Indexers/HDSpace.cs
@@ -14,8 +14,8 @@ using System.Web;
 using System.Text.RegularExpressions;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
+using System.Collections.Specialized;
+
 namespace Jackett.Indexers
 {
     public class HDSpace : BaseIndexer, IIndexer
@@ -106,18 +106,18 @@ namespace Jackett.Indexers
 
             var searchString = query.GetQueryString();
             var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("active", "0");
-            queryCollection.Add("options", "0");
-            queryCollection.Add("category", string.Join(";", MapTorznabCapsToTrackers(query)));
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            searchUrl += queryCollection.GetQueryString();
-
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("active", "0");
+            queryCollection.Add("options", "0");
+            queryCollection.Add("category", string.Join(";", MapTorznabCapsToTrackers(query)));
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            searchUrl += queryCollection.GetQueryString();
+
             var response = await RequestStringWithCookiesAndRetry(searchUrl);
             var results = response.Content;
 
@@ -164,12 +164,12 @@ namespace Jackett.Indexers
                     grabs = grabs.Replace("---", "0");
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[title=\"FreeLeech\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[src=\"images/sf.png\"]").Length >= 1) // side freeleech
-                        release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[title=\"Half FreeLeech\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
+                    if (qRow.Find("img[title=\"FreeLeech\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("img[src=\"images/sf.png\"]").Length >= 1) // side freeleech
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("img[title=\"Half FreeLeech\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/HDTorrents.cs b/src/Jackett/Indexers/HDTorrents.cs
index 9d91bf68da9822987977fe2f9351f1ed515125ec..a270839fb93d1edafd1ccebb97aff69c4942d368 100644
--- a/src/Jackett/Indexers/HDTorrents.cs
+++ b/src/Jackett/Indexers/HDTorrents.cs
@@ -48,34 +48,34 @@ namespace Jackett.Indexers
 
             TorznabCaps.SupportsImdbSearch = true;
 
-            TorznabCaps.Categories.Clear();
-
-            // Movie
-            AddCategoryMapping("1", TorznabCatType.MoviesHD, "Movie/Blu-Ray");
-            AddCategoryMapping("2", TorznabCatType.MoviesHD, "Movie/Remux");
-            AddCategoryMapping("5", TorznabCatType.MoviesHD, "Movie/1080p/i");
-            AddCategoryMapping("3", TorznabCatType.MoviesHD, "Movie/720p");
-            AddCategoryMapping("64", TorznabCatType.MoviesHD, "Movie/2160p");
-            AddCategoryMapping("63", TorznabCatType.Audio, "Movie/Audio Track");
-            // TV Show
-            AddCategoryMapping("59", TorznabCatType.TVHD, "TV Show/Blu-ray");
-            AddCategoryMapping("60", TorznabCatType.TVHD, "TV Show/Remux");
-            AddCategoryMapping("30", TorznabCatType.TVHD, "TV Show/1080p/i");
-            AddCategoryMapping("38", TorznabCatType.TVHD, "TV Show/720p");
-            AddCategoryMapping("65", TorznabCatType.TVHD, "TV Show/2160p");
-            // Music
-            AddCategoryMapping("44", TorznabCatType.Audio, "Music/Album");
-            AddCategoryMapping("61", TorznabCatType.AudioVideo, "Music/Blu-Ray");
-            AddCategoryMapping("62", TorznabCatType.AudioVideo, "Music/Remux");
-            AddCategoryMapping("57", TorznabCatType.AudioVideo, "Music/1080p/i");
-            AddCategoryMapping("45", TorznabCatType.AudioVideo, "Music/720p");
-            AddCategoryMapping("66", TorznabCatType.AudioVideo, "Music/2160p");
-            // XXX
-            AddCategoryMapping("58", TorznabCatType.XXX, "XXX/Blu-ray");
-            AddCategoryMapping("48", TorznabCatType.XXX, "XXX/1080p/i");
-            AddCategoryMapping("47", TorznabCatType.XXX, "XXX/720p");
-            AddCategoryMapping("67", TorznabCatType.XXX, "XXX/2160p");
-            // 3D
+            TorznabCaps.Categories.Clear();
+
+            // Movie
+            AddCategoryMapping("1", TorznabCatType.MoviesHD, "Movie/Blu-Ray");
+            AddCategoryMapping("2", TorznabCatType.MoviesHD, "Movie/Remux");
+            AddCategoryMapping("5", TorznabCatType.MoviesHD, "Movie/1080p/i");
+            AddCategoryMapping("3", TorznabCatType.MoviesHD, "Movie/720p");
+            AddCategoryMapping("64", TorznabCatType.MoviesHD, "Movie/2160p");
+            AddCategoryMapping("63", TorznabCatType.Audio, "Movie/Audio Track");
+            // TV Show
+            AddCategoryMapping("59", TorznabCatType.TVHD, "TV Show/Blu-ray");
+            AddCategoryMapping("60", TorznabCatType.TVHD, "TV Show/Remux");
+            AddCategoryMapping("30", TorznabCatType.TVHD, "TV Show/1080p/i");
+            AddCategoryMapping("38", TorznabCatType.TVHD, "TV Show/720p");
+            AddCategoryMapping("65", TorznabCatType.TVHD, "TV Show/2160p");
+            // Music
+            AddCategoryMapping("44", TorznabCatType.Audio, "Music/Album");
+            AddCategoryMapping("61", TorznabCatType.AudioVideo, "Music/Blu-Ray");
+            AddCategoryMapping("62", TorznabCatType.AudioVideo, "Music/Remux");
+            AddCategoryMapping("57", TorznabCatType.AudioVideo, "Music/1080p/i");
+            AddCategoryMapping("45", TorznabCatType.AudioVideo, "Music/720p");
+            AddCategoryMapping("66", TorznabCatType.AudioVideo, "Music/2160p");
+            // XXX
+            AddCategoryMapping("58", TorznabCatType.XXX, "XXX/Blu-ray");
+            AddCategoryMapping("48", TorznabCatType.XXX, "XXX/1080p/i");
+            AddCategoryMapping("47", TorznabCatType.XXX, "XXX/720p");
+            AddCategoryMapping("67", TorznabCatType.XXX, "XXX/2160p");
+            // 3D
             AddCategoryMapping("67", TorznabCatType.Movies3D, "3D");
         }
 
@@ -191,17 +191,17 @@ namespace Jackett.Indexers
 
                     release.UploadVolumeFactor = 1;
 
-                    if (qRow.Find("img[alt=\"Free Torrent\"]").Length >= 1)
-                    { 
-                        release.DownloadVolumeFactor = 0;
-                        release.UploadVolumeFactor = 0;
+                    if (qRow.Find("img[alt=\"Free Torrent\"]").Length >= 1)
+                    { 
+                        release.DownloadVolumeFactor = 0;
+                        release.UploadVolumeFactor = 0;
                     }
-                    else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
-                    else if (qRow.Find("img[alt=\"Bronze Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.75;
-                    else if (qRow.Find("img[alt=\"Blue Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.25;
+                    else if (qRow.Find("img[alt=\"Silver Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
+                    else if (qRow.Find("img[alt=\"Bronze Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.75;
+                    else if (qRow.Find("img[alt=\"Blue Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.25;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/Hardbay.cs b/src/Jackett/Indexers/Hardbay.cs
index ea84d49f7323d4e337fc2af19f2fe48afe79b8d8..2ceabe7d7d5724444663aed0ae90782b0ce9ce6c 100644
--- a/src/Jackett/Indexers/Hardbay.cs
+++ b/src/Jackett/Indexers/Hardbay.cs
@@ -1,147 +1,147 @@
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using Newtonsoft.Json;
-using System.Globalization;
-
-namespace Jackett.Indexers
-{
-    public class Hardbay : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
-        private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public Hardbay(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "Hardbay",
-                description: null,
-                link: "https://hardbay.club/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(1, TorznabCatType.Audio);
-            AddCategoryMapping(2, TorznabCatType.AudioLossless);
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var queryCollection = new NameValueCollection();
-
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using Newtonsoft.Json;
+using System.Globalization;
+
+namespace Jackett.Indexers
+{
+    public class Hardbay : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
+        private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public Hardbay(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "Hardbay",
+                description: null,
+                link: "https://hardbay.club/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(1, TorznabCatType.Audio);
+            AddCategoryMapping(2, TorznabCatType.AudioLossless);
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var queryCollection = new NameValueCollection();
+
             queryCollection.Add("username", configData.Username.Value);
-            queryCollection.Add("password", configData.Password.Value);
-
-            var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
-            var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
-
-            await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
-            {
-                throw new ExceptionWithConfigData(loginResult.Content, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-            var queryCollection = new NameValueCollection();
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-
-            queryCollection.Add("extendedSearch", "false");
-            queryCollection.Add("hideOld", "false");
-            queryCollection.Add("index", "0");
-            queryCollection.Add("limit", "100");
-            queryCollection.Add("order", "desc");
-            queryCollection.Add("page", "search");
-            queryCollection.Add("searchText", searchString);
-            queryCollection.Add("sort", "d");
-
-            /*foreach (var cat in MapTorznabCapsToTrackers(query))
-                queryCollection.Add("categories[]", cat);
-            */
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-            var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
-
-            try
-            {
-                //var json = JArray.Parse(results.Content);
-                dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
-                foreach (var row in json)
-                {
-                    var release = new ReleaseInfo();
-                    var descriptions = new List<string>();
-                    var tags = new List<string>();
-
-                    release.MinimumRatio = 0.5;
-                    release.MinimumSeedTime = 0;
-                    release.Title = row.name;
-                    release.Category = new List<int> { TorznabCatType.Audio.ID };
-                    release.Size = row.size;
-                    release.Seeders = row.seeders;
-                    release.Peers = row.leechers + release.Seeders;
-                    release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
-                    release.Files = row.numfiles;
-                    release.Grabs = row.times_completed;
-
-                    release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
-                    release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
-
-                    if (row.frileech == 1)
-                        release.DownloadVolumeFactor = 0;
-                    else
-                        release.DownloadVolumeFactor = 0.33;
-                    release.UploadVolumeFactor = 1;
-
-                    if ((int)row.p2p == 1)
-                        tags.Add("P2P");
-                    if ((int)row.pack == 1)
-                        tags.Add("Pack");
-                    if ((int)row.reqid != 0)
-                        tags.Add("Archive");
-                    if ((int)row.flac != 0)
-                    {
-                        tags.Add("FLAC");
-                        release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
-                    }
-
-                    if (tags.Count > 0)
-                        descriptions.Add("Tags: " + string.Join(", ", tags));
-
-                    release.Description = string.Join("<br>\n", descriptions);
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
+            queryCollection.Add("password", configData.Password.Value);
+
+            var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
+            var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
+
+            await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
+            {
+                throw new ExceptionWithConfigData(loginResult.Content, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+            var queryCollection = new NameValueCollection();
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+
+            queryCollection.Add("extendedSearch", "false");
+            queryCollection.Add("hideOld", "false");
+            queryCollection.Add("index", "0");
+            queryCollection.Add("limit", "100");
+            queryCollection.Add("order", "desc");
+            queryCollection.Add("page", "search");
+            queryCollection.Add("searchText", searchString);
+            queryCollection.Add("sort", "d");
+
+            /*foreach (var cat in MapTorznabCapsToTrackers(query))
+                queryCollection.Add("categories[]", cat);
+            */
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+            var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
+
+            try
+            {
+                //var json = JArray.Parse(results.Content);
+                dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
+                foreach (var row in json)
+                {
+                    var release = new ReleaseInfo();
+                    var descriptions = new List<string>();
+                    var tags = new List<string>();
+
+                    release.MinimumRatio = 0.5;
+                    release.MinimumSeedTime = 0;
+                    release.Title = row.name;
+                    release.Category = new List<int> { TorznabCatType.Audio.ID };
+                    release.Size = row.size;
+                    release.Seeders = row.seeders;
+                    release.Peers = row.leechers + release.Seeders;
+                    release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
+                    release.Files = row.numfiles;
+                    release.Grabs = row.times_completed;
+
+                    release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
+                    release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
+
+                    if (row.frileech == 1)
+                        release.DownloadVolumeFactor = 0;
+                    else
+                        release.DownloadVolumeFactor = 0.33;
+                    release.UploadVolumeFactor = 1;
+
+                    if ((int)row.p2p == 1)
+                        tags.Add("P2P");
+                    if ((int)row.pack == 1)
+                        tags.Add("Pack");
+                    if ((int)row.reqid != 0)
+                        tags.Add("Archive");
+                    if ((int)row.flac != 0)
+                    {
+                        tags.Add("FLAC");
+                        release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
+                    }
+
+                    if (tags.Count > 0)
+                        descriptions.Add("Tags: " + string.Join(", ", tags));
+
+                    release.Description = string.Join("<br>\n", descriptions);
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/Hebits.cs b/src/Jackett/Indexers/Hebits.cs
index 6c4348245e3b39505d974e53a3454883ef362333..9716728e33fffc35d090d791cd4047f4bf90859d 100644
--- a/src/Jackett/Indexers/Hebits.cs
+++ b/src/Jackett/Indexers/Hebits.cs
@@ -12,8 +12,8 @@ using System.Threading.Tasks;
 using System.Web;
 using Jackett.Models.IndexerConfig;
 using System.Text.RegularExpressions;
-using System.Text;
-
+using System.Text;
+
 namespace Jackett.Indexers
 {
     public class Hebits : BaseIndexer, IIndexer
@@ -146,15 +146,15 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("div.bFinish").Get(0).LastChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[src=\"/pic/free.jpg\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("img[src=\"/pic/free.jpg\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
-                    if (qRow.Find("img[src=\"/pic/triple.jpg\"]").Length >= 1)
+                    if (qRow.Find("img[src=\"/pic/triple.jpg\"]").Length >= 1)
                         release.UploadVolumeFactor = 3;
-                    else if (qRow.Find("img[src=\"/pic/double.jpg\"]").Length >= 1)
-                        release.UploadVolumeFactor = 2;
+                    else if (qRow.Find("img[src=\"/pic/double.jpg\"]").Length >= 1)
+                        release.UploadVolumeFactor = 2;
                     else
                         release.UploadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/Hounddawgs.cs b/src/Jackett/Indexers/Hounddawgs.cs
index 5b77aeaf54b8ee49449f4d7fc2435967cf95de8c..0c1d947b5ed598d872eed092967fd995796cb419 100644
--- a/src/Jackett/Indexers/Hounddawgs.cs
+++ b/src/Jackett/Indexers/Hounddawgs.cs
@@ -18,9 +18,9 @@ using System.Threading.Tasks;
 using System.Web;
 using System.Web.UI.WebControls;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text.RegularExpressions;
-
+using System.Collections.Specialized;
+using System.Text.RegularExpressions;
+
 namespace Jackett.Indexers
 {
 	public class Hounddawgs : BaseIndexer, IIndexer
@@ -45,43 +45,43 @@ namespace Jackett.Indexers
 				p: ps,
 				configData: new NxtGnConfigurationData())
 		{
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "da-dk";
-            Type = "private";
-
-            AddCategoryMapping(68, TorznabCatType.Movies3D, "3D");
-            AddCategoryMapping(80, TorznabCatType.PCPhoneAndroid, "Appz / Android");
-            AddCategoryMapping(86, TorznabCatType.PC0day, "Appz / Div");
-            AddCategoryMapping(71, TorznabCatType.PCPhoneIOS, "Appz / iOS");
-            AddCategoryMapping(70, TorznabCatType.PCMac, "Appz / Mac");
-            AddCategoryMapping(69, TorznabCatType.PC0day, "Appz / PC");
-            AddCategoryMapping(72, TorznabCatType.AudioAudiobook, "Audio Books");
-            AddCategoryMapping(82, TorznabCatType.MoviesBluRay, "BluRay/REMUX");
-            AddCategoryMapping(78, TorznabCatType.Books, "Books");
-            AddCategoryMapping(87, TorznabCatType.Other, "Cover");
-            AddCategoryMapping(90, TorznabCatType.MoviesDVD, "DK DVDr");
-            AddCategoryMapping(89, TorznabCatType.TVHD, "DK HD");
-            AddCategoryMapping(91, TorznabCatType.TVSD, "DK SD");
-            AddCategoryMapping(92, TorznabCatType.TVHD, "DK TV HD");
-            AddCategoryMapping(93, TorznabCatType.TVSD, "DK TV SD");
-            AddCategoryMapping(83, TorznabCatType.Other, "ELearning");
-            AddCategoryMapping(84, TorznabCatType.Movies, "Film Boxset");
-            AddCategoryMapping(81, TorznabCatType.MoviesSD, "Film CAM/TS");
-            AddCategoryMapping(60, TorznabCatType.MoviesDVD, "Film DVDr");
-            AddCategoryMapping(59, TorznabCatType.MoviesHD, "Film HD");
-            AddCategoryMapping(73, TorznabCatType.MoviesSD, "Film SD");
-            AddCategoryMapping(77, TorznabCatType.MoviesOther, "Film Tablet");
-            AddCategoryMapping(61, TorznabCatType.Audio, "Musik");
-            AddCategoryMapping(76, TorznabCatType.AudioVideo, "MusikVideo/Koncert");
-            AddCategoryMapping(75, TorznabCatType.Console, "Spil / Konsol");
-            AddCategoryMapping(79, TorznabCatType.PCMac, "Spil / Mac");
-            AddCategoryMapping(64, TorznabCatType.PCGames, "Spil / PC");
-            AddCategoryMapping(85, TorznabCatType.TV, "TV Boxset");
-            AddCategoryMapping(58, TorznabCatType.TVSD, "TV DVDr");
-            AddCategoryMapping(57, TorznabCatType.TVHD, "TV HD");
-            AddCategoryMapping(74, TorznabCatType.TVSD, "TV SD");
-            AddCategoryMapping(94, TorznabCatType.TVOTHER, "TV Tablet");
-            AddCategoryMapping(67, TorznabCatType.XXX, "XXX");
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "da-dk";
+            Type = "private";
+
+            AddCategoryMapping(68, TorznabCatType.Movies3D, "3D");
+            AddCategoryMapping(80, TorznabCatType.PCPhoneAndroid, "Appz / Android");
+            AddCategoryMapping(86, TorznabCatType.PC0day, "Appz / Div");
+            AddCategoryMapping(71, TorznabCatType.PCPhoneIOS, "Appz / iOS");
+            AddCategoryMapping(70, TorznabCatType.PCMac, "Appz / Mac");
+            AddCategoryMapping(69, TorznabCatType.PC0day, "Appz / PC");
+            AddCategoryMapping(72, TorznabCatType.AudioAudiobook, "Audio Books");
+            AddCategoryMapping(82, TorznabCatType.MoviesBluRay, "BluRay/REMUX");
+            AddCategoryMapping(78, TorznabCatType.Books, "Books");
+            AddCategoryMapping(87, TorznabCatType.Other, "Cover");
+            AddCategoryMapping(90, TorznabCatType.MoviesDVD, "DK DVDr");
+            AddCategoryMapping(89, TorznabCatType.TVHD, "DK HD");
+            AddCategoryMapping(91, TorznabCatType.TVSD, "DK SD");
+            AddCategoryMapping(92, TorznabCatType.TVHD, "DK TV HD");
+            AddCategoryMapping(93, TorznabCatType.TVSD, "DK TV SD");
+            AddCategoryMapping(83, TorznabCatType.Other, "ELearning");
+            AddCategoryMapping(84, TorznabCatType.Movies, "Film Boxset");
+            AddCategoryMapping(81, TorznabCatType.MoviesSD, "Film CAM/TS");
+            AddCategoryMapping(60, TorznabCatType.MoviesDVD, "Film DVDr");
+            AddCategoryMapping(59, TorznabCatType.MoviesHD, "Film HD");
+            AddCategoryMapping(73, TorznabCatType.MoviesSD, "Film SD");
+            AddCategoryMapping(77, TorznabCatType.MoviesOther, "Film Tablet");
+            AddCategoryMapping(61, TorznabCatType.Audio, "Musik");
+            AddCategoryMapping(76, TorznabCatType.AudioVideo, "MusikVideo/Koncert");
+            AddCategoryMapping(75, TorznabCatType.Console, "Spil / Konsol");
+            AddCategoryMapping(79, TorznabCatType.PCMac, "Spil / Mac");
+            AddCategoryMapping(64, TorznabCatType.PCGames, "Spil / PC");
+            AddCategoryMapping(85, TorznabCatType.TV, "TV Boxset");
+            AddCategoryMapping(58, TorznabCatType.TVSD, "TV DVDr");
+            AddCategoryMapping(57, TorznabCatType.TVHD, "TV HD");
+            AddCategoryMapping(74, TorznabCatType.TVSD, "TV SD");
+            AddCategoryMapping(94, TorznabCatType.TVOTHER, "TV Tablet");
+            AddCategoryMapping(67, TorznabCatType.XXX, "XXX");
         }
 
 		public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
@@ -110,24 +110,24 @@ namespace Jackett.Indexers
 		public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
 		{
 			var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
+            var searchString = query.GetQueryString();
             var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("order_by", "time");
-            queryCollection.Add("order_way", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("searchstr", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("filter_cat[" + cat + "]", "1");
-            }
-
-            searchUrl += "?" + queryCollection.GetQueryString();
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("order_by", "time");
+            queryCollection.Add("order_way", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("searchstr", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("filter_cat[" + cat + "]", "1");
+            }
+
+            searchUrl += "?" + queryCollection.GetQueryString();
             var results = await RequestStringWithCookiesAndRetry(searchUrl);
 			if (results.Content.Contains("Din søgning gav intet resultat."))
 			{
@@ -141,16 +141,16 @@ namespace Jackett.Indexers
 
 				foreach (var row in rows.Skip(1))
 				{
-                    var qRow = row.Cq();
+                    var qRow = row.Cq();
                     var release = new ReleaseInfo();
 					release.MinimumRatio = 1;
 					release.MinimumSeedTime = 172800;
 
 					var qCat = row.ChildElements.ElementAt(0).ChildElements.ElementAt(0).Cq();
 					var catUrl = qCat.Attr("href");
-					var cat = catUrl.Substring(catUrl.LastIndexOf('[') + 1).Trim(']');
-                    release.Category = MapTrackerCatToNewznab(cat);
-
+					var cat = catUrl.Substring(catUrl.LastIndexOf('[') + 1).Trim(']');
+                    release.Category = MapTrackerCatToNewznab(cat);
+
                     var qAdded = row.ChildElements.ElementAt(4).ChildElements.ElementAt(0).Cq();
 					var addedStr = qAdded.Attr("title");
 					release.PublishDate = DateTime.ParseExact(addedStr, "MMM dd yyyy, HH:mm", CultureInfo.InvariantCulture);
@@ -160,22 +160,22 @@ namespace Jackett.Indexers
                     var overlayHtml = Regex.Unescape(overlayHtmlEscaped);
                     CQ qOverlay = overlayHtml;
                     var title = qOverlay.Find("td.overlay > strong");
-                    var banner = qOverlay.Find("td.leftOverlay > img").Attr("src");
-                    var description = qOverlay.Find("td.rightOverlay");
-
-                    foreach (var img in description.Find("img")) // convert relativ flag paths to full uri
-                        img.SetAttribute("src", SiteLink + img.GetAttribute("src"));
-
-                    var descriptionDom = description.Get(0);
-                    for (var i = 14; i > 0; i--) // remove size/seeders/leechers
-                        descriptionDom.ChildNodes.RemoveAt(0);
-
-                    release.Description = descriptionDom.OuterHTML;
+                    var banner = qOverlay.Find("td.leftOverlay > img").Attr("src");
+                    var description = qOverlay.Find("td.rightOverlay");
+
+                    foreach (var img in description.Find("img")) // convert relativ flag paths to full uri
+                        img.SetAttribute("src", SiteLink + img.GetAttribute("src"));
+
+                    var descriptionDom = description.Get(0);
+                    for (var i = 14; i > 0; i--) // remove size/seeders/leechers
+                        descriptionDom.ChildNodes.RemoveAt(0);
+
+                    release.Description = descriptionDom.OuterHTML;
                     release.Title = title.Text();
                     if (!string.IsNullOrEmpty(banner) && banner != "/static/common/noartwork/noimage.png")
                         release.BannerUrl = new Uri(banner);
 
-                    var qLink = row.Cq().Find("a[href^=\"torrents.php?id=\"][onmouseover]");
+                    var qLink = row.Cq().Find("a[href^=\"torrents.php?id=\"][onmouseover]");
                     release.Comments = new Uri(SiteLink + qLink.Attr("href"));
 					release.Guid = release.Comments;
 
@@ -186,18 +186,18 @@ namespace Jackett.Indexers
 					release.Size = ReleaseInfo.GetBytes(sizeStr);
 
 					release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(6).Cq().Text());
-					release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()) + release.Seeders;
-
+					release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text()) + release.Seeders;
+
                     var files = row.Cq().Find("td:nth-child(4)").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
-                    if (row.Cq().Find("img[src=\"/static//common/browse/freeleech.png\"]").Any())
-                         release.DownloadVolumeFactor = 0;
+                    if (row.Cq().Find("img[src=\"/static//common/browse/freeleech.png\"]").Any())
+                         release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
-                    release.UploadVolumeFactor = 1;
-
+                    release.UploadVolumeFactor = 1;
+
                     releases.Add(release);
 				}
 			}
diff --git a/src/Jackett/Indexers/HouseOfTorrents.cs b/src/Jackett/Indexers/HouseOfTorrents.cs
index 8744163fa365958e14622e656f2fcf9e6c3e3902..9c48d84b368c70f6edc166aa2e34e9bd069c561e 100644
--- a/src/Jackett/Indexers/HouseOfTorrents.cs
+++ b/src/Jackett/Indexers/HouseOfTorrents.cs
@@ -1,237 +1,237 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public class HouseOfTorrents : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public HouseOfTorrents(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "House-of-Torrents",
-                description: "A general tracker",
-                link: "https://houseoftorrents.club/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(42, TorznabCatType.PCMac); // Applications/Mac
-            AddCategoryMapping(34, TorznabCatType.PC); // Applications/PC
-            AddCategoryMapping(66, TorznabCatType.MoviesForeign); // Foreign
-            AddCategoryMapping(38, TorznabCatType.MoviesForeign); // Foreign/French
-            AddCategoryMapping(39, TorznabCatType.MoviesForeign); // Foreign/German
-            AddCategoryMapping(40, TorznabCatType.MoviesForeign); // Foreign/Spanish
-            AddCategoryMapping(41, TorznabCatType.MoviesForeign); // Foreign/Swedish
-            AddCategoryMapping(67, TorznabCatType.ConsoleNDS); // Games/Nintendo
-            AddCategoryMapping(9 , TorznabCatType.PCGames); // Games/PC 
-            AddCategoryMapping(8,  TorznabCatType.ConsolePS3); // Games/PS3
-            AddCategoryMapping(30, TorznabCatType.ConsolePS4); // Games/PS4
-            AddCategoryMapping(7,  TorznabCatType.ConsolePSP); // Games/PSP
-            AddCategoryMapping(29, TorznabCatType.ConsoleWii); // Games/Wii
-            AddCategoryMapping(31, TorznabCatType.ConsoleXbox360); // Games/XBOX360
-            AddCategoryMapping(32, TorznabCatType.ConsoleXboxOne); // Games/XBOXONE
-            AddCategoryMapping(71, TorznabCatType.PCPhoneAndroid); // Mobile/Android
-            AddCategoryMapping(72, TorznabCatType.PCPhoneIOS); // Mobile/iOS
-            AddCategoryMapping(47, TorznabCatType.Movies3D); // Movies/3D
-            AddCategoryMapping(43, TorznabCatType.MoviesBluRay); // Movies/Bluray
-            AddCategoryMapping(84, TorznabCatType.MoviesSD); // Movies/Cam
-            AddCategoryMapping(44, TorznabCatType.MoviesDVD); // Movies/DVD-R
-            AddCategoryMapping(45, TorznabCatType.Movies); // Movies/MP4
-            AddCategoryMapping(69, TorznabCatType.Movies); // Movies/Packs
-            AddCategoryMapping(46, TorznabCatType.MoviesSD); // Movies/SD
-            AddCategoryMapping(11, TorznabCatType.MoviesHD); // Movies/x264
-            AddCategoryMapping(83, TorznabCatType.MoviesHD); // Movies/x265
-            AddCategoryMapping(10, TorznabCatType.MoviesOther); // Movies/XviD
-            AddCategoryMapping(36, TorznabCatType.AudioLossless); // Music/FLAC
-            AddCategoryMapping(12, TorznabCatType.AudioMP3); // Music/MP3
-            AddCategoryMapping(79, TorznabCatType.Audio); // Music/Pack
-            AddCategoryMapping(28, TorznabCatType.AudioVideo); // Music/Video
-            AddCategoryMapping(49, TorznabCatType.TVAnime); // Others/Anime
-            AddCategoryMapping(80, TorznabCatType.AudioAudiobook); // Others/AudioBook
-            AddCategoryMapping(60, TorznabCatType.Other); // Others/Boxsets
-            AddCategoryMapping(65, TorznabCatType.TVDocumentary); // Others/Documentary
-            AddCategoryMapping(61, TorznabCatType.Books); // Others/E-Book
-            AddCategoryMapping(51, TorznabCatType.Other); // Others/RARFIX
-            AddCategoryMapping(74, TorznabCatType.TVSport); // Sports
-            AddCategoryMapping(75, TorznabCatType.TVSport); // Sports/Boxing
-            AddCategoryMapping(76, TorznabCatType.TVSport); // Sports/Racing
-            AddCategoryMapping(77, TorznabCatType.TVSport); // Sports/UFC
-            AddCategoryMapping(78, TorznabCatType.TVSport); // Sports/WWE
-            AddCategoryMapping(68, TorznabCatType.TV); // TV/Packs
-            AddCategoryMapping(53, TorznabCatType.TVSD); // TV/SD
-            AddCategoryMapping(54, TorznabCatType.TVHD); // TV/x264
-            AddCategoryMapping(82, TorznabCatType.TVHD); // TV/x265
-            AddCategoryMapping(55, TorznabCatType.TVOTHER); // Tv/XviD
-            AddCategoryMapping(63, TorznabCatType.XXX); // XXX
-            AddCategoryMapping(57, TorznabCatType.XXX); // XXX/0-DAY
-            AddCategoryMapping(58, TorznabCatType.XXXImageset); // XXX/IMAGESET
-            AddCategoryMapping(81, TorznabCatType.XXXPacks); // XXX/Pack
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            // reset cookies, if we send expired cookies for a new session their code seems to get confused
-            // Due to the session not getting initiated correctly it will result in errors like this:
-            // Notice: Undefined index: simpleCaptchaAnswer in /var/www/html/takelogin.php on line 17
-            CookieHeader = null;
-
-            var result1 = await RequestStringWithCookies(CaptchaUrl);
-            var json1 = JObject.Parse(result1.Content);
-            var captchaSelection = json1["images"][0]["hash"];
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "captchaSelection", (string)captchaSelection },
-                { "submitme", "X" }
-            };
-
-            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
-
-            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = result2.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("searchin", "title");
-            queryCollection.Add("incldead", "1");
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                // use AND+wildcard operator to avoid getting to many useless results
-                var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList();
-                searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList(); //  remove words with less than 3 characters
-                searchStringArray = searchStringArray.Select(x => "+" + x).ToList(); // add AND operators+wildcards
-                var searchStringFinal = String.Join("", searchStringArray);
-                queryCollection.Add("search", searchStringFinal);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-
-            if (results.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookiesAndRetry(searchUrl);
-            }
-
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom["table.tt > tbody > tr"];
-                foreach (var row in rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 72 * 60 * 60;
-
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    release.Title = qDetailsLink.Text().Trim();
-
-                    // HoT search returns should support AND search but it simply doesn't work, so we AND filter it manualy
-                    if (!query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-                    var qSeeders = qRow.Find("td:eq(8)");
-                    var qLeechers = qRow.Find("td:eq(9)");
-                    var qDownloadLink = qRow.Find("a[href^=download.php]").First();
-                    var qTimeAgo = qRow.Find("td:eq(5)");
-                    var qSize = qRow.Find("td:eq(6)");
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
-                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
-
-                    var dateStr = qTimeAgo.Text();
-                    DateTime pubDateUtc;
-                    var Timeparts = dateStr.Split(new char[] { ' ' }, 2)[1];
-                    if (dateStr.StartsWith("Today "))
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay;
-                    else if (dateStr.StartsWith("Yesterday "))
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) +
-                            DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay - TimeSpan.FromDays(1);
-                    else
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy hh:mm tt", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    release.PublishDate = pubDateUtc.ToLocalTime();
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public class HouseOfTorrents : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public HouseOfTorrents(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "House-of-Torrents",
+                description: "A general tracker",
+                link: "https://houseoftorrents.club/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(42, TorznabCatType.PCMac); // Applications/Mac
+            AddCategoryMapping(34, TorznabCatType.PC); // Applications/PC
+            AddCategoryMapping(66, TorznabCatType.MoviesForeign); // Foreign
+            AddCategoryMapping(38, TorznabCatType.MoviesForeign); // Foreign/French
+            AddCategoryMapping(39, TorznabCatType.MoviesForeign); // Foreign/German
+            AddCategoryMapping(40, TorznabCatType.MoviesForeign); // Foreign/Spanish
+            AddCategoryMapping(41, TorznabCatType.MoviesForeign); // Foreign/Swedish
+            AddCategoryMapping(67, TorznabCatType.ConsoleNDS); // Games/Nintendo
+            AddCategoryMapping(9 , TorznabCatType.PCGames); // Games/PC 
+            AddCategoryMapping(8,  TorznabCatType.ConsolePS3); // Games/PS3
+            AddCategoryMapping(30, TorznabCatType.ConsolePS4); // Games/PS4
+            AddCategoryMapping(7,  TorznabCatType.ConsolePSP); // Games/PSP
+            AddCategoryMapping(29, TorznabCatType.ConsoleWii); // Games/Wii
+            AddCategoryMapping(31, TorznabCatType.ConsoleXbox360); // Games/XBOX360
+            AddCategoryMapping(32, TorznabCatType.ConsoleXboxOne); // Games/XBOXONE
+            AddCategoryMapping(71, TorznabCatType.PCPhoneAndroid); // Mobile/Android
+            AddCategoryMapping(72, TorznabCatType.PCPhoneIOS); // Mobile/iOS
+            AddCategoryMapping(47, TorznabCatType.Movies3D); // Movies/3D
+            AddCategoryMapping(43, TorznabCatType.MoviesBluRay); // Movies/Bluray
+            AddCategoryMapping(84, TorznabCatType.MoviesSD); // Movies/Cam
+            AddCategoryMapping(44, TorznabCatType.MoviesDVD); // Movies/DVD-R
+            AddCategoryMapping(45, TorznabCatType.Movies); // Movies/MP4
+            AddCategoryMapping(69, TorznabCatType.Movies); // Movies/Packs
+            AddCategoryMapping(46, TorznabCatType.MoviesSD); // Movies/SD
+            AddCategoryMapping(11, TorznabCatType.MoviesHD); // Movies/x264
+            AddCategoryMapping(83, TorznabCatType.MoviesHD); // Movies/x265
+            AddCategoryMapping(10, TorznabCatType.MoviesOther); // Movies/XviD
+            AddCategoryMapping(36, TorznabCatType.AudioLossless); // Music/FLAC
+            AddCategoryMapping(12, TorznabCatType.AudioMP3); // Music/MP3
+            AddCategoryMapping(79, TorznabCatType.Audio); // Music/Pack
+            AddCategoryMapping(28, TorznabCatType.AudioVideo); // Music/Video
+            AddCategoryMapping(49, TorznabCatType.TVAnime); // Others/Anime
+            AddCategoryMapping(80, TorznabCatType.AudioAudiobook); // Others/AudioBook
+            AddCategoryMapping(60, TorznabCatType.Other); // Others/Boxsets
+            AddCategoryMapping(65, TorznabCatType.TVDocumentary); // Others/Documentary
+            AddCategoryMapping(61, TorznabCatType.Books); // Others/E-Book
+            AddCategoryMapping(51, TorznabCatType.Other); // Others/RARFIX
+            AddCategoryMapping(74, TorznabCatType.TVSport); // Sports
+            AddCategoryMapping(75, TorznabCatType.TVSport); // Sports/Boxing
+            AddCategoryMapping(76, TorznabCatType.TVSport); // Sports/Racing
+            AddCategoryMapping(77, TorznabCatType.TVSport); // Sports/UFC
+            AddCategoryMapping(78, TorznabCatType.TVSport); // Sports/WWE
+            AddCategoryMapping(68, TorznabCatType.TV); // TV/Packs
+            AddCategoryMapping(53, TorznabCatType.TVSD); // TV/SD
+            AddCategoryMapping(54, TorznabCatType.TVHD); // TV/x264
+            AddCategoryMapping(82, TorznabCatType.TVHD); // TV/x265
+            AddCategoryMapping(55, TorznabCatType.TVOTHER); // Tv/XviD
+            AddCategoryMapping(63, TorznabCatType.XXX); // XXX
+            AddCategoryMapping(57, TorznabCatType.XXX); // XXX/0-DAY
+            AddCategoryMapping(58, TorznabCatType.XXXImageset); // XXX/IMAGESET
+            AddCategoryMapping(81, TorznabCatType.XXXPacks); // XXX/Pack
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            // reset cookies, if we send expired cookies for a new session their code seems to get confused
+            // Due to the session not getting initiated correctly it will result in errors like this:
+            // Notice: Undefined index: simpleCaptchaAnswer in /var/www/html/takelogin.php on line 17
+            CookieHeader = null;
+
+            var result1 = await RequestStringWithCookies(CaptchaUrl);
+            var json1 = JObject.Parse(result1.Content);
+            var captchaSelection = json1["images"][0]["hash"];
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "captchaSelection", (string)captchaSelection },
+                { "submitme", "X" }
+            };
+
+            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
+
+            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = result2.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("searchin", "title");
+            queryCollection.Add("incldead", "1");
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                // use AND+wildcard operator to avoid getting to many useless results
+                var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList();
+                searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList(); //  remove words with less than 3 characters
+                searchStringArray = searchStringArray.Select(x => "+" + x).ToList(); // add AND operators+wildcards
+                var searchStringFinal = String.Join("", searchStringArray);
+                queryCollection.Add("search", searchStringFinal);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+
+            if (results.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookiesAndRetry(searchUrl);
+            }
+
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom["table.tt > tbody > tr"];
+                foreach (var row in rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 72 * 60 * 60;
+
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    release.Title = qDetailsLink.Text().Trim();
+
+                    // HoT search returns should support AND search but it simply doesn't work, so we AND filter it manualy
+                    if (!query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+                    var qSeeders = qRow.Find("td:eq(8)");
+                    var qLeechers = qRow.Find("td:eq(9)");
+                    var qDownloadLink = qRow.Find("a[href^=download.php]").First();
+                    var qTimeAgo = qRow.Find("td:eq(5)");
+                    var qSize = qRow.Find("td:eq(6)");
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
+
+                    var dateStr = qTimeAgo.Text();
+                    DateTime pubDateUtc;
+                    var Timeparts = dateStr.Split(new char[] { ' ' }, 2)[1];
+                    if (dateStr.StartsWith("Today "))
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay;
+                    else if (dateStr.StartsWith("Yesterday "))
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) +
+                            DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay - TimeSpan.FromDays(1);
+                    else
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy hh:mm tt", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    release.PublishDate = pubDateUtc.ToLocalTime();
+
                     var files = qRow.Find("td:nth-child(4)").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
                     var grabs = qRow.Find("td:nth-child(8) > a").Html();
                     release.Grabs = ParseUtil.CoerceInt(grabs.Split('<')[0]);
 
-                    release.DownloadVolumeFactor = 0; // ratioless
+                    release.DownloadVolumeFactor = 0; // ratioless
                     
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/IIndexer.cs b/src/Jackett/Indexers/IIndexer.cs
index 11ccf608c23490feb3d77172b3b8a2c22187e05e..a9f97681a7cd4594e8fde314ce0663b7b1ca12a7 100644
--- a/src/Jackett/Indexers/IIndexer.cs
+++ b/src/Jackett/Indexers/IIndexer.cs
@@ -25,9 +25,9 @@ namespace Jackett.Indexers
         TorznabCapabilities TorznabCaps { get; }
 
         // Whether this indexer has been configured, verified and saved in the past and has the settings required for functioning
-        bool IsConfigured { get; }
-
-        // Retrieved for starting setup for the indexer via web API
+        bool IsConfigured { get; }
+
+        // Retrieved for starting setup for the indexer via web API
         Task<ConfigurationData> GetConfigurationForSetup();
 
         // Called when web API wants to apply setup configuration via web API, usually this is where login and storing cookie happens
diff --git a/src/Jackett/Indexers/IPTorrents.cs b/src/Jackett/Indexers/IPTorrents.cs
index c132c2b5f3b9434ea0d4b62fa32156ab7af19fa3..0be5f89468035dd91c0162a78548598f2dd075ae 100644
--- a/src/Jackett/Indexers/IPTorrents.cs
+++ b/src/Jackett/Indexers/IPTorrents.cs
@@ -21,8 +21,8 @@ namespace Jackett.Indexers
 {
     public class IPTorrents : BaseIndexer, IIndexer
     {
-        string LoginUrl { get { return SiteLink + "login.php"; } }
-        string TakeLoginUrl { get { return SiteLink + "take_login.php"; } }
+        string LoginUrl { get { return SiteLink + "login.php"; } }
+        string TakeLoginUrl { get { return SiteLink + "take_login.php"; } }
         private string BrowseUrl { get { return SiteLink + "t"; } }
         public new string[] AlternativeSiteLinks { get; protected set; } = new string[] { "https://ipt-update.com/", "https://iptorrents.com/", "https://iptorrents.eu/", "https://nemo.iptorrents.com/", "https://ipt.rocks/" };
 
@@ -47,94 +47,94 @@ namespace Jackett.Indexers
             Language = "en-us";
             Type = "private";
 
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(72, TorznabCatType.Movies, "Movies");
-            AddCategoryMapping(87, TorznabCatType.Movies3D, "Movie/3D");
-            AddCategoryMapping(77, TorznabCatType.MoviesSD, "Movie/480p");
-            AddCategoryMapping(89, TorznabCatType.MoviesSD, "Movie/BD-R");
-            AddCategoryMapping(90, TorznabCatType.MoviesSD, "Movie/BD-Rip");
-            AddCategoryMapping(96, TorznabCatType.MoviesSD, "Movie/Cam");
-            AddCategoryMapping(6, TorznabCatType.MoviesDVD, "Movie/DVD-R");
-            AddCategoryMapping(48, TorznabCatType.MoviesBluRay, "Movie/HD/Bluray");
-            AddCategoryMapping(54, TorznabCatType.Movies, "Movie/Kids");
-            AddCategoryMapping(62, TorznabCatType.MoviesSD, "Movie/MP4");
-            AddCategoryMapping(38, TorznabCatType.MoviesForeign, "Movie/Non-English");
-            AddCategoryMapping(68, TorznabCatType.Movies, "Movie/Packs");
-            AddCategoryMapping(20, TorznabCatType.MoviesHD, "Movie/Web-DL");
-            AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movie/Xvid");
-            AddCategoryMapping(100, TorznabCatType.Movies, "Movie/x265");
-
-            AddCategoryMapping(73, TorznabCatType.TV, "TV");
-            AddCategoryMapping(26, TorznabCatType.TVDocumentary, "Documentaries");
-            AddCategoryMapping(55, TorznabCatType.TVSport, "Sports");
-            AddCategoryMapping(78, TorznabCatType.TVSD, "TV/480p");
-            AddCategoryMapping(23, TorznabCatType.TVHD, "TV/BD");
-            AddCategoryMapping(24, TorznabCatType.TVSD, "TV/DVD-R");
-            AddCategoryMapping(25, TorznabCatType.TVSD, "TV/DVD-Rip");
-            AddCategoryMapping(66, TorznabCatType.TVSD, "TV/Mobile");
-            AddCategoryMapping(82, TorznabCatType.TVFOREIGN, "TV/Non-English");
-            AddCategoryMapping(65, TorznabCatType.TV, "TV/Packs");
-            AddCategoryMapping(83, TorznabCatType.TVFOREIGN, "TV/Packs/Non-English");
-            AddCategoryMapping(79, TorznabCatType.TVSD, "TV/SD/x264");
-            AddCategoryMapping(22, TorznabCatType.TVWEBDL, "TV/Web-DL");
-            AddCategoryMapping(5, TorznabCatType.TVHD, "TV/x264");
-            AddCategoryMapping(99, TorznabCatType.TVHD, "TV/x265");
-            AddCategoryMapping(4, TorznabCatType.TVSD, "TV/Xvid");
-
-            AddCategoryMapping(74, TorznabCatType.Console, "Games");
-            AddCategoryMapping(2, TorznabCatType.ConsoleOther, "Games/Mixed");
-            AddCategoryMapping(47, TorznabCatType.ConsoleNDS, "Games/Nintendo DS");
-            AddCategoryMapping(43, TorznabCatType.PCISO, "Games/PC-ISO");
-            AddCategoryMapping(45, TorznabCatType.PCGames, "Games/PC-Rip");
-            AddCategoryMapping(39, TorznabCatType.ConsolePS3, "Games/PS2");
-            AddCategoryMapping(71, TorznabCatType.ConsolePS3, "Games/PS3");
-            AddCategoryMapping(40, TorznabCatType.ConsolePSP, "Games/PSP");
-            AddCategoryMapping(50, TorznabCatType.ConsoleWii, "Games/Wii");
-            AddCategoryMapping(44, TorznabCatType.ConsoleXbox360, "Games/Xbox-360");
-
-            AddCategoryMapping(75, TorznabCatType.Audio, "Music");
-            AddCategoryMapping(3, TorznabCatType.AudioMP3, "Music/Audio");
-            AddCategoryMapping(80, TorznabCatType.AudioLossless, "Music/Flac");
-            AddCategoryMapping(93, TorznabCatType.Audio, "Music/Packs");
-            AddCategoryMapping(37, TorznabCatType.AudioVideo, "Music/Video");
-            AddCategoryMapping(21, TorznabCatType.AudioVideo, "Podcast");
-
-            AddCategoryMapping(76, TorznabCatType.Other, "Miscellaneous");
-            AddCategoryMapping(60, TorznabCatType.TVAnime, "Anime");
-            AddCategoryMapping(1, TorznabCatType.PC0day, "Appz");
-            AddCategoryMapping(86, TorznabCatType.PC0day, "Appz/Non-English");
-            AddCategoryMapping(64, TorznabCatType.AudioAudiobook, "AudioBook");
-            AddCategoryMapping(35, TorznabCatType.Books, "Books");
-            AddCategoryMapping(94, TorznabCatType.BooksComics, "Comics");
-            AddCategoryMapping(95, TorznabCatType.BooksOther, "Educational");
-            AddCategoryMapping(98, TorznabCatType.Other, "Fonts");
-            AddCategoryMapping(69, TorznabCatType.PCMac, "Mac");
-            AddCategoryMapping(92, TorznabCatType.BooksMagazines, "Magazines / Newspapers");
-            AddCategoryMapping(58, TorznabCatType.PCPhoneOther, "Mobile");
-            AddCategoryMapping(36, TorznabCatType.Other, "Pics/Wallpapers");
-
-            AddCategoryMapping(88, TorznabCatType.XXX, "XXX");
-            AddCategoryMapping(85, TorznabCatType.XXXOther, "XXX/Magazines");
-            AddCategoryMapping(8, TorznabCatType.XXX, "XXX/Movie");
-            AddCategoryMapping(81, TorznabCatType.XXX, "XXX/Movie/0Day");
-            AddCategoryMapping(91, TorznabCatType.XXXPacks, "XXX/Packs");
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(72, TorznabCatType.Movies, "Movies");
+            AddCategoryMapping(87, TorznabCatType.Movies3D, "Movie/3D");
+            AddCategoryMapping(77, TorznabCatType.MoviesSD, "Movie/480p");
+            AddCategoryMapping(89, TorznabCatType.MoviesSD, "Movie/BD-R");
+            AddCategoryMapping(90, TorznabCatType.MoviesSD, "Movie/BD-Rip");
+            AddCategoryMapping(96, TorznabCatType.MoviesSD, "Movie/Cam");
+            AddCategoryMapping(6, TorznabCatType.MoviesDVD, "Movie/DVD-R");
+            AddCategoryMapping(48, TorznabCatType.MoviesBluRay, "Movie/HD/Bluray");
+            AddCategoryMapping(54, TorznabCatType.Movies, "Movie/Kids");
+            AddCategoryMapping(62, TorznabCatType.MoviesSD, "Movie/MP4");
+            AddCategoryMapping(38, TorznabCatType.MoviesForeign, "Movie/Non-English");
+            AddCategoryMapping(68, TorznabCatType.Movies, "Movie/Packs");
+            AddCategoryMapping(20, TorznabCatType.MoviesHD, "Movie/Web-DL");
+            AddCategoryMapping(7, TorznabCatType.MoviesSD, "Movie/Xvid");
+            AddCategoryMapping(100, TorznabCatType.Movies, "Movie/x265");
+
+            AddCategoryMapping(73, TorznabCatType.TV, "TV");
+            AddCategoryMapping(26, TorznabCatType.TVDocumentary, "Documentaries");
+            AddCategoryMapping(55, TorznabCatType.TVSport, "Sports");
+            AddCategoryMapping(78, TorznabCatType.TVSD, "TV/480p");
+            AddCategoryMapping(23, TorznabCatType.TVHD, "TV/BD");
+            AddCategoryMapping(24, TorznabCatType.TVSD, "TV/DVD-R");
+            AddCategoryMapping(25, TorznabCatType.TVSD, "TV/DVD-Rip");
+            AddCategoryMapping(66, TorznabCatType.TVSD, "TV/Mobile");
+            AddCategoryMapping(82, TorznabCatType.TVFOREIGN, "TV/Non-English");
+            AddCategoryMapping(65, TorznabCatType.TV, "TV/Packs");
+            AddCategoryMapping(83, TorznabCatType.TVFOREIGN, "TV/Packs/Non-English");
+            AddCategoryMapping(79, TorznabCatType.TVSD, "TV/SD/x264");
+            AddCategoryMapping(22, TorznabCatType.TVWEBDL, "TV/Web-DL");
+            AddCategoryMapping(5, TorznabCatType.TVHD, "TV/x264");
+            AddCategoryMapping(99, TorznabCatType.TVHD, "TV/x265");
+            AddCategoryMapping(4, TorznabCatType.TVSD, "TV/Xvid");
+
+            AddCategoryMapping(74, TorznabCatType.Console, "Games");
+            AddCategoryMapping(2, TorznabCatType.ConsoleOther, "Games/Mixed");
+            AddCategoryMapping(47, TorznabCatType.ConsoleNDS, "Games/Nintendo DS");
+            AddCategoryMapping(43, TorznabCatType.PCISO, "Games/PC-ISO");
+            AddCategoryMapping(45, TorznabCatType.PCGames, "Games/PC-Rip");
+            AddCategoryMapping(39, TorznabCatType.ConsolePS3, "Games/PS2");
+            AddCategoryMapping(71, TorznabCatType.ConsolePS3, "Games/PS3");
+            AddCategoryMapping(40, TorznabCatType.ConsolePSP, "Games/PSP");
+            AddCategoryMapping(50, TorznabCatType.ConsoleWii, "Games/Wii");
+            AddCategoryMapping(44, TorznabCatType.ConsoleXbox360, "Games/Xbox-360");
+
+            AddCategoryMapping(75, TorznabCatType.Audio, "Music");
+            AddCategoryMapping(3, TorznabCatType.AudioMP3, "Music/Audio");
+            AddCategoryMapping(80, TorznabCatType.AudioLossless, "Music/Flac");
+            AddCategoryMapping(93, TorznabCatType.Audio, "Music/Packs");
+            AddCategoryMapping(37, TorznabCatType.AudioVideo, "Music/Video");
+            AddCategoryMapping(21, TorznabCatType.AudioVideo, "Podcast");
+
+            AddCategoryMapping(76, TorznabCatType.Other, "Miscellaneous");
+            AddCategoryMapping(60, TorznabCatType.TVAnime, "Anime");
+            AddCategoryMapping(1, TorznabCatType.PC0day, "Appz");
+            AddCategoryMapping(86, TorznabCatType.PC0day, "Appz/Non-English");
+            AddCategoryMapping(64, TorznabCatType.AudioAudiobook, "AudioBook");
+            AddCategoryMapping(35, TorznabCatType.Books, "Books");
+            AddCategoryMapping(94, TorznabCatType.BooksComics, "Comics");
+            AddCategoryMapping(95, TorznabCatType.BooksOther, "Educational");
+            AddCategoryMapping(98, TorznabCatType.Other, "Fonts");
+            AddCategoryMapping(69, TorznabCatType.PCMac, "Mac");
+            AddCategoryMapping(92, TorznabCatType.BooksMagazines, "Magazines / Newspapers");
+            AddCategoryMapping(58, TorznabCatType.PCPhoneOther, "Mobile");
+            AddCategoryMapping(36, TorznabCatType.Other, "Pics/Wallpapers");
+
+            AddCategoryMapping(88, TorznabCatType.XXX, "XXX");
+            AddCategoryMapping(85, TorznabCatType.XXXOther, "XXX/Magazines");
+            AddCategoryMapping(8, TorznabCatType.XXX, "XXX/Movie");
+            AddCategoryMapping(81, TorznabCatType.XXX, "XXX/Movie/0Day");
+            AddCategoryMapping(91, TorznabCatType.XXXPacks, "XXX/Packs");
             AddCategoryMapping(84, TorznabCatType.XXXImageset, "XXX/Pics/Wallpapers");
         }
 
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
-            CQ cq = loginPage.Content;
-            var captcha = cq.Find(".g-recaptcha");
-            if(captcha.Any())
-            {
-                var result = this.configData;
-                result.CookieHeader.Value = loginPage.Cookies;
-                result.Captcha.SiteKey = captcha.Attr("data-sitekey");
-                result.Captcha.Version = "2";
-                return result;
-            }
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
+            CQ cq = loginPage.Content;
+            var captcha = cq.Find(".g-recaptcha");
+            if(captcha.Any())
+            {
+                var result = this.configData;
+                result.CookieHeader.Value = loginPage.Cookies;
+                result.Captcha.SiteKey = captcha.Attr("data-sitekey");
+                result.Captcha.Version = "2";
+                return result;
+            }
             else
             {
                 var result = new ConfigurationDataBasicLogin();
@@ -144,7 +144,7 @@ namespace Jackett.Indexers
                 result.Password.Value = configData.Password.Value;
                 result.CookieHeader.Value = loginPage.Cookies;
                 return result;
-            }
+            }
         }
 
 
@@ -280,8 +280,8 @@ namespace Jackett.Indexers
                     var grabs = row.Cq().Find("td:nth-last-child(3)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if(row.Cq().Find("span.t_tag_free_leech").Any())
-                        release.DownloadVolumeFactor = 0;
+                    if(row.Cq().Find("span.t_tag_free_leech").Any())
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/ImmortalSeed.cs b/src/Jackett/Indexers/ImmortalSeed.cs
index cadd69d514a4f045ba9375d321738a70f508c416..02c5825c79b70f5b67a61813e08a24c0ec91a8bb 100644
--- a/src/Jackett/Indexers/ImmortalSeed.cs
+++ b/src/Jackett/Indexers/ImmortalSeed.cs
@@ -85,7 +85,7 @@ namespace Jackett.Indexers
 
             await ConfigureIfOK(response.Cookies, response.Content.Contains("/logout.php"), () =>
             {
-                var errorMessage = response.Content;
+                var errorMessage = response.Content;
                 throw new ExceptionWithConfigData(errorMessage, configData);
             });
 
@@ -105,10 +105,10 @@ namespace Jackett.Indexers
             var results = await RequestStringWithCookiesAndRetry(searchUrl);
 
             // Occasionally the cookies become invalid, login again if that happens
-            if (results.Content.Contains("You do not have permission to access this page."))
-            {
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookiesAndRetry(searchUrl);
+            if (results.Content.Contains("You do not have permission to access this page."))
+            {
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookiesAndRetry(searchUrl);
             }
 
             try
@@ -121,12 +121,12 @@ namespace Jackett.Indexers
                     var release = new ReleaseInfo();
                     var qRow = row.Cq();
 
-                    var qDetails = qRow.Find("div > a[href*=\"details.php?id=\"]"); // details link, release name get's shortened if it's to long
-                    var qTitle = qRow.Find("td:eq(1) .tooltip-content div:eq(0)"); // use Title from tooltip
-                    if (!qTitle.Any()) // fallback to Details link if there's no tooltip
-                    {
-                        qTitle = qDetails;
-                    }
+                    var qDetails = qRow.Find("div > a[href*=\"details.php?id=\"]"); // details link, release name get's shortened if it's to long
+                    var qTitle = qRow.Find("td:eq(1) .tooltip-content div:eq(0)"); // use Title from tooltip
+                    if (!qTitle.Any()) // fallback to Details link if there's no tooltip
+                    {
+                        qTitle = qDetails;
+                    }
                     release.Title = qTitle.Text();
 
                     var qDesciption = qRow.Find(".tooltip-content > div");
@@ -160,10 +160,10 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(6)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[title^=\"Free Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[title^=\"Silver Torrent\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
+                    if (qRow.Find("img[title^=\"Free Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("img[title^=\"Silver Torrent\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/MoreThanTV.cs b/src/Jackett/Indexers/MoreThanTV.cs
index 41895de753da557fb336373f5b49efdf445671df..1e62c00a1010d4683bd35d6dc1b699d7f825e9af 100644
--- a/src/Jackett/Indexers/MoreThanTV.cs
+++ b/src/Jackett/Indexers/MoreThanTV.cs
@@ -15,8 +15,8 @@ using AngleSharp.Dom;
 using AngleSharp.Parser.Html;
 using CsQuery;
 using Jackett.Models.IndexerConfig;
-using Jackett.Utils;
-
+using Jackett.Utils;
+
 namespace Jackett.Indexers
 {
     public class MoreThanTV : BaseIndexer, IIndexer
@@ -109,11 +109,11 @@ namespace Jackett.Indexers
         {
             var searchUrl = GetTorrentSearchUrl(query.Categories, searchQuery);
             var response = await RequestStringWithCookiesAndRetry(searchUrl);
-            if (response.IsRedirect)
-            {
-                // re login
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(searchUrl);
+            if (response.IsRedirect)
+            {
+                // re login
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(searchUrl);
             }
 
             try
@@ -165,8 +165,8 @@ namespace Jackett.Indexers
                                 qualityData[1].Trim(),
                                 qualityEdition, // Audio quality should be after this one. Unobtainable at the moment.
                                 $"{qualityData[0].Trim()}-MTV"
-                            });
-
+                            });
+
                             releases.Add(GetReleaseInfo(groupItem, downloadAnchor, title, TorznabCatType.TV.ID));
                         }
                         else
diff --git a/src/Jackett/Indexers/MyAnonamouse.cs b/src/Jackett/Indexers/MyAnonamouse.cs
index 53a3dd44693d3b2d43e1387ac55ae68df27be218..46387efab4d3df00554292e388e7e0b16c53687b 100644
--- a/src/Jackett/Indexers/MyAnonamouse.cs
+++ b/src/Jackett/Indexers/MyAnonamouse.cs
@@ -196,8 +196,8 @@ namespace Jackett.Indexers
                 foreach (IDomObject row in rows)
                 {
                     CQ torrentData = row.OuterHTML;
-                    CQ cells = row.Cq().Find("td");
-
+                    CQ cells = row.Cq().Find("td");
+
                     string tid = torrentData.Attr("id").Substring(4);
                     var qTitle = torrentData.Find("a[class='title']").First();
                     string title = qTitle.Text().Trim();
@@ -234,14 +234,14 @@ namespace Jackett.Indexers
                     release.MinimumRatio = 1;
                     release.MinimumSeedTime = 172800;
                     release.Category = MapTrackerCatToNewznab(category.ToString());
-                    release.Comments = details;
-
-                    if (freeleech)
-                        release.DownloadVolumeFactor = 0;
+                    release.Comments = details;
+
+                    if (freeleech)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
-                    release.UploadVolumeFactor = 1;
+                        release.DownloadVolumeFactor = 1;
+
+                    release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
                 }
diff --git a/src/Jackett/Indexers/NCore.cs b/src/Jackett/Indexers/NCore.cs
index af39a5b52815e121f65dc6f89826728b1c961bbd..705f91084a9401e9e53a1df7d2d37dc8937f7371 100644
--- a/src/Jackett/Indexers/NCore.cs
+++ b/src/Jackett/Indexers/NCore.cs
@@ -1,122 +1,122 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig.Bespoke;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public class NCore : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "login.php"; } }
-        private string SearchUrl { get { return SiteLink + "torrents.php"; } }
-        private string[] LanguageCats = new string[] { "xvidser", "dvdser", "hdser", "xvid", "dvd", "dvd9", "hd", "mp3", "lossless", "ebook" };
-
-        new ConfigurationDataNCore configData
-        {
-            get { return (ConfigurationDataNCore)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public NCore(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "nCore",
-                description: "A Hungarian private torrent site.",
-                link: "https://ncore.cc/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataNCore())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "hu-hu";
-            Type = "private";
-
-            AddCategoryMapping("xvid_hun", TorznabCatType.MoviesSD, "Film SD/HU");
-            AddCategoryMapping("xvid", TorznabCatType.MoviesSD , "Film SD/EN");
-            AddCategoryMapping("dvd_hun", TorznabCatType.MoviesDVD, "Film DVDR/HU");
-            AddCategoryMapping("dvd", TorznabCatType.MoviesDVD, "Film DVDR/EN");
-            AddCategoryMapping("dvd9_hun", TorznabCatType.MoviesDVD, "Film DVD9/HU");
-            AddCategoryMapping("dvd9", TorznabCatType.MoviesDVD, "Film DVD9/EN");
-            AddCategoryMapping("hd_hun", TorznabCatType.MoviesHD, "Film HD/HU");
-            AddCategoryMapping("hd", TorznabCatType.MoviesHD, "Film HD/EN");
-
-            AddCategoryMapping("xvidser_hun", TorznabCatType.TVSD , "Sorozat SD/HU");
-            AddCategoryMapping("xvidser", TorznabCatType.TVSD , "Sorozat SD/EN");
-            AddCategoryMapping("dvdser_hun", TorznabCatType.TVSD , "Sorozat DVDR/HU");
-            AddCategoryMapping("dvdser", TorznabCatType.TVSD, "Sorozat DVDR/EN");
-            AddCategoryMapping("hdser_hun", TorznabCatType.TVHD, "Sorozat HD/HU");
-            AddCategoryMapping("hdser", TorznabCatType.TVHD , "Sorozat HD/EN");
-
-            AddCategoryMapping("mp3_hun", TorznabCatType.AudioMP3 , "Zene MP3/HU");
-            AddCategoryMapping("mp3", TorznabCatType.AudioMP3, "Zene MP3/EN");
-            AddCategoryMapping("lossless_hun", TorznabCatType.AudioLossless, "Zene Lossless/HU");
-            AddCategoryMapping("lossless", TorznabCatType.AudioLossless, "Zene Lossless/EN");
-            AddCategoryMapping("clip", TorznabCatType.AudioVideo , "Zene Klip");
-
-            AddCategoryMapping("xxx_xvid", TorznabCatType.XXXXviD , "XXX SD");
-            AddCategoryMapping("xxx_dvd", TorznabCatType.XXXDVD, "XXX DVDR");
-            AddCategoryMapping("xxx_imageset", TorznabCatType.XXXImageset , "XXX Imageset");
-            AddCategoryMapping("xxx_hd", TorznabCatType.XXX , "XXX HD");
-
-            AddCategoryMapping("game_iso", TorznabCatType.PCGames , "Játék PC/ISO");
-            AddCategoryMapping("game_rip", TorznabCatType.PCGames , "Játék PC/RIP");
-            AddCategoryMapping("console", TorznabCatType.Console , "Játék Konzol");
-
-            AddCategoryMapping("iso", TorznabCatType.PCISO , "Program Prog/ISO");
-            AddCategoryMapping("misc", TorznabCatType.PC0day , "Program Prog/RIP");
-            AddCategoryMapping("mobil", TorznabCatType.PCPhoneOther , "Program Prog/Mobil");
-
-            AddCategoryMapping("ebook_hun", TorznabCatType.Books , "Könyv eBook/HU");
-            AddCategoryMapping("ebook", TorznabCatType.Books , "Könyv eBook/EN");
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            if (configData.Hungarian.Value == false && configData.English.Value == false)
-                throw new ExceptionWithConfigData("Please select atleast one language.", configData);
-
-            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
-            var pairs = new Dictionary<string, string> {
-                { "nev", configData.Username.Value },
-                { "pass", configData.Password.Value },
-                { "ne_leptessen_ki", "1"},
-                { "set_lang", "en" },
-                { "submitted", "1" },
-                { "submit", "Access!" }
-            };
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("profile.php"), () =>
-            {
-                CQ dom = result.Content;
-                var messageEl = dom["#hibauzenet table tbody tr"];
-                var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
-                var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig.Bespoke;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public class NCore : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "login.php"; } }
+        private string SearchUrl { get { return SiteLink + "torrents.php"; } }
+        private string[] LanguageCats = new string[] { "xvidser", "dvdser", "hdser", "xvid", "dvd", "dvd9", "hd", "mp3", "lossless", "ebook" };
+
+        new ConfigurationDataNCore configData
+        {
+            get { return (ConfigurationDataNCore)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public NCore(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "nCore",
+                description: "A Hungarian private torrent site.",
+                link: "https://ncore.cc/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataNCore())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "hu-hu";
+            Type = "private";
+
+            AddCategoryMapping("xvid_hun", TorznabCatType.MoviesSD, "Film SD/HU");
+            AddCategoryMapping("xvid", TorznabCatType.MoviesSD , "Film SD/EN");
+            AddCategoryMapping("dvd_hun", TorznabCatType.MoviesDVD, "Film DVDR/HU");
+            AddCategoryMapping("dvd", TorznabCatType.MoviesDVD, "Film DVDR/EN");
+            AddCategoryMapping("dvd9_hun", TorznabCatType.MoviesDVD, "Film DVD9/HU");
+            AddCategoryMapping("dvd9", TorznabCatType.MoviesDVD, "Film DVD9/EN");
+            AddCategoryMapping("hd_hun", TorznabCatType.MoviesHD, "Film HD/HU");
+            AddCategoryMapping("hd", TorznabCatType.MoviesHD, "Film HD/EN");
+
+            AddCategoryMapping("xvidser_hun", TorznabCatType.TVSD , "Sorozat SD/HU");
+            AddCategoryMapping("xvidser", TorznabCatType.TVSD , "Sorozat SD/EN");
+            AddCategoryMapping("dvdser_hun", TorznabCatType.TVSD , "Sorozat DVDR/HU");
+            AddCategoryMapping("dvdser", TorznabCatType.TVSD, "Sorozat DVDR/EN");
+            AddCategoryMapping("hdser_hun", TorznabCatType.TVHD, "Sorozat HD/HU");
+            AddCategoryMapping("hdser", TorznabCatType.TVHD , "Sorozat HD/EN");
+
+            AddCategoryMapping("mp3_hun", TorznabCatType.AudioMP3 , "Zene MP3/HU");
+            AddCategoryMapping("mp3", TorznabCatType.AudioMP3, "Zene MP3/EN");
+            AddCategoryMapping("lossless_hun", TorznabCatType.AudioLossless, "Zene Lossless/HU");
+            AddCategoryMapping("lossless", TorznabCatType.AudioLossless, "Zene Lossless/EN");
+            AddCategoryMapping("clip", TorznabCatType.AudioVideo , "Zene Klip");
+
+            AddCategoryMapping("xxx_xvid", TorznabCatType.XXXXviD , "XXX SD");
+            AddCategoryMapping("xxx_dvd", TorznabCatType.XXXDVD, "XXX DVDR");
+            AddCategoryMapping("xxx_imageset", TorznabCatType.XXXImageset , "XXX Imageset");
+            AddCategoryMapping("xxx_hd", TorznabCatType.XXX , "XXX HD");
+
+            AddCategoryMapping("game_iso", TorznabCatType.PCGames , "Játék PC/ISO");
+            AddCategoryMapping("game_rip", TorznabCatType.PCGames , "Játék PC/RIP");
+            AddCategoryMapping("console", TorznabCatType.Console , "Játék Konzol");
+
+            AddCategoryMapping("iso", TorznabCatType.PCISO , "Program Prog/ISO");
+            AddCategoryMapping("misc", TorznabCatType.PC0day , "Program Prog/RIP");
+            AddCategoryMapping("mobil", TorznabCatType.PCPhoneOther , "Program Prog/Mobil");
+
+            AddCategoryMapping("ebook_hun", TorznabCatType.Books , "Könyv eBook/HU");
+            AddCategoryMapping("ebook", TorznabCatType.Books , "Könyv eBook/EN");
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            if (configData.Hungarian.Value == false && configData.English.Value == false)
+                throw new ExceptionWithConfigData("Please select atleast one language.", configData);
+
+            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
+            var pairs = new Dictionary<string, string> {
+                { "nev", configData.Username.Value },
+                { "pass", configData.Password.Value },
+                { "ne_leptessen_ki", "1"},
+                { "set_lang", "en" },
+                { "submitted", "1" },
+                { "submit", "Access!" }
+            };
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, loginPage.Cookies, true, referer: SiteLink);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("profile.php"), () =>
+            {
+                CQ dom = result.Content;
+                var messageEl = dom["#hibauzenet table tbody tr"];
+                var msgContainer = messageEl.Get(0).ChildElements.ElementAt(1);
+                var errorMessage = msgContainer != null ? msgContainer.InnerText : "Error while trying to login.";
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
             var searchString = query.GetQueryString();
-            var pairs = new List<KeyValuePair<string, string>>();
+            var pairs = new List<KeyValuePair<string, string>>();
 
             pairs.Add(new KeyValuePair<string, string>("nyit_sorozat_resz", "true"));
             pairs.Add(new KeyValuePair<string, string>("miben", "name"));
@@ -125,83 +125,83 @@ namespace Jackett.Indexers
             pairs.Add(new KeyValuePair<string, string>("submit.y", "1"));
             pairs.Add(new KeyValuePair<string, string>("submit", "Ok"));
             pairs.Add(new KeyValuePair<string, string>("mire", searchString));
-
-            var cats = MapTorznabCapsToTrackers(query);
-
-            if (cats.Count == 0)
-                cats = GetAllTrackerCategories();
-
-            foreach (var lcat in LanguageCats)
-            {
-                if (!configData.Hungarian.Value)
-                    cats.Remove(lcat + "_hun");
-                if (!configData.English.Value)
-                    cats.Remove(lcat);
-            }
-            
-            foreach (var cat in cats)
-            {
-                pairs.Add(new KeyValuePair<string, string>("kivalasztott_tipus[]", cat));
-            }
-
-            var results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);
-
-            try
-            {
-                CQ dom = results.Content;
-
-                ReleaseInfo release;
-                var rows = dom[".box_torrent_all"].Find(".box_torrent");
-
-                foreach (var row in rows)
-                {
-                    CQ qRow = row.Cq();
-
-                    release = new ReleaseInfo();
-                    var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
-                    //if (torrentTxt == null) continue;
-                    release.Title = torrentTxt.GetAttribute("title");
-                    release.Description = qRow.Find("div.siterank").Text();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-                    release.DownloadVolumeFactor = 0;
-                    release.UploadVolumeFactor = 1;
-
-                    string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
-                    string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
-
-                    release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId);
-                    release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
-                    release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
-                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
-                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
-                    var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
-                    release.Imdb = ParseUtil.GetLongFromString(imdblink);
-                    var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
-                    if (banner != null)
-                    {
-                        Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
-                        var BannerMatch = BannerRegEx.Match(banner);
-                        var bannerurl = BannerMatch.Groups[1].Value;
-                        release.BannerUrl = new Uri(bannerurl);
-                    }
-                    release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
-                    string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
-                    release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
-                    string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
-                    string cat = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
-                    release.Category = MapTrackerCatToNewznab(cat);
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-
-    }
-}
+
+            var cats = MapTorznabCapsToTrackers(query);
+
+            if (cats.Count == 0)
+                cats = GetAllTrackerCategories();
+
+            foreach (var lcat in LanguageCats)
+            {
+                if (!configData.Hungarian.Value)
+                    cats.Remove(lcat + "_hun");
+                if (!configData.English.Value)
+                    cats.Remove(lcat);
+            }
+            
+            foreach (var cat in cats)
+            {
+                pairs.Add(new KeyValuePair<string, string>("kivalasztott_tipus[]", cat));
+            }
+
+            var results = await PostDataWithCookiesAndRetry(SearchUrl, pairs);
+
+            try
+            {
+                CQ dom = results.Content;
+
+                ReleaseInfo release;
+                var rows = dom[".box_torrent_all"].Find(".box_torrent");
+
+                foreach (var row in rows)
+                {
+                    CQ qRow = row.Cq();
+
+                    release = new ReleaseInfo();
+                    var torrentTxt = qRow.Find(".torrent_txt, .torrent_txt2").Find("a").Get(0);
+                    //if (torrentTxt == null) continue;
+                    release.Title = torrentTxt.GetAttribute("title");
+                    release.Description = qRow.Find("div.siterank").Text();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+                    release.DownloadVolumeFactor = 0;
+                    release.UploadVolumeFactor = 1;
+
+                    string downloadLink = SiteLink + torrentTxt.GetAttribute("href");
+                    string downloadId = downloadLink.Substring(downloadLink.IndexOf("&id=") + 4);
+
+                    release.Link = new Uri(SiteLink.ToString() + "torrents.php?action=download&id=" + downloadId);
+                    release.Comments = new Uri(SiteLink.ToString() + "torrents.php?action=details&id=" + downloadId);
+                    release.Guid = new Uri(release.Comments.ToString() + "#comments"); ;
+                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".box_s2").Find("a").First().Text());
+                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".box_l2").Find("a").First().Text()) + release.Seeders;
+                    var imdblink = qRow.Find("a[href*=\".imdb.com/title\"]").Attr("href");
+                    release.Imdb = ParseUtil.GetLongFromString(imdblink);
+                    var banner = qRow.Find("img.infobar_ico").Attr("onmouseover");
+                    if (banner != null)
+                    {
+                        Regex BannerRegEx = new Regex(@"mutat\('(.*?)', '", RegexOptions.Compiled);
+                        var BannerMatch = BannerRegEx.Match(banner);
+                        var bannerurl = BannerMatch.Groups[1].Value;
+                        release.BannerUrl = new Uri(bannerurl);
+                    }
+                    release.PublishDate = DateTime.Parse(qRow.Find(".box_feltoltve2").Get(0).InnerHTML.Replace("<br />", " "), CultureInfo.InvariantCulture);
+                    string[] sizeSplit = qRow.Find(".box_meret2").Get(0).InnerText.Split(' ');
+                    release.Size = ReleaseInfo.GetBytes(sizeSplit[1].ToLower(), ParseUtil.CoerceFloat(sizeSplit[0]));
+                    string catlink = qRow.Find("a:has(img[class='categ_link'])").First().Attr("href");
+                    string cat = ParseUtil.GetArgumentFromQueryString(catlink, "tipus");
+                    release.Category = MapTrackerCatToNewznab(cat);
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+
+    }
+}
diff --git a/src/Jackett/Indexers/NewRealWorld.cs b/src/Jackett/Indexers/NewRealWorld.cs
index 77283b290f4c5dc85d43cf8b279d3bc3f0cc305f..b8d03ac38ef80e696d534395de750ade80df1c67 100644
--- a/src/Jackett/Indexers/NewRealWorld.cs
+++ b/src/Jackett/Indexers/NewRealWorld.cs
@@ -10,9 +10,9 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-
+using System.Collections.Specialized;
+using System.Text;
+
 namespace Jackett.Indexers
 {
     public class NewRealWorld : BaseIndexer, IIndexer
@@ -41,57 +41,57 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(39, TorznabCatType.TVAnime); // Anime: HD|1080p
-            AddCategoryMapping(38, TorznabCatType.TVAnime); // Anime: HD|720p
-            AddCategoryMapping(1,  TorznabCatType.TVAnime); // Anime: SD
-            AddCategoryMapping(7,  TorznabCatType.PCPhoneOther); // Appz: Handy-PDA
-            AddCategoryMapping(36, TorznabCatType.PCMac); // Appz: Mac
-            AddCategoryMapping(18, TorznabCatType.PC); // Appz: Sonstiges
-            AddCategoryMapping(17, TorznabCatType.PC); // Appz: Win
-            AddCategoryMapping(15, TorznabCatType.Audio); // Audio: DVD-R
-            AddCategoryMapping(49, TorznabCatType.AudioLossless); // Audio: Flac
-            AddCategoryMapping(30, TorznabCatType.AudioAudiobook); // Audio: Hörspiele
-            AddCategoryMapping(14, TorznabCatType.AudioMP3); // Audio: MP3
-            AddCategoryMapping(22, TorznabCatType.AudioVideo); // Audio: Videoclip
-            AddCategoryMapping(19, TorznabCatType.Other); // Diverses: Sonstiges
-            AddCategoryMapping(43, TorznabCatType.TVDocumentary); // Dokus: HD
-            AddCategoryMapping(2,  TorznabCatType.TVDocumentary); // Dokus: SD
-            AddCategoryMapping(3,  TorznabCatType.Books); // Ebooks: Bücher
-            AddCategoryMapping(52, TorznabCatType.BooksComics); // Ebooks: Comics
-            AddCategoryMapping(53, TorznabCatType.BooksMagazines); // Ebooks: Magazine
-            AddCategoryMapping(55, TorznabCatType.BooksOther); // Ebooks: XXX
-            AddCategoryMapping(54, TorznabCatType.BooksOther); // Ebooks: Zeitungen
-            AddCategoryMapping(47, TorznabCatType.PCPhoneOther); // Games: Andere
-            AddCategoryMapping(32, TorznabCatType.PCMac); // Games: Mac
-            AddCategoryMapping(41, TorznabCatType.ConsoleNDS); // Games: NDS/3DS
-            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games: PC
-            AddCategoryMapping(5,  TorznabCatType.ConsolePS3); // Games: PS2
-            AddCategoryMapping(9,  TorznabCatType.ConsolePS3); // Games: PS3
-            AddCategoryMapping(6,  TorznabCatType.ConsolePSP); // Games: PSP
-            AddCategoryMapping(28, TorznabCatType.ConsoleWii); // Games: Wii
-            AddCategoryMapping(31, TorznabCatType.ConsoleXbox); // Games: XboX
-            AddCategoryMapping(51, TorznabCatType.Movies3D); // Movies: 3D
-            AddCategoryMapping(37, TorznabCatType.MoviesBluRay); // Movies: BluRay
-            AddCategoryMapping(25, TorznabCatType.MoviesHD); // Movies: HD|1080p
-            AddCategoryMapping(29, TorznabCatType.MoviesHD); // Movies: HD|720p
-            AddCategoryMapping(11, TorznabCatType.MoviesDVD); // Movies: SD|DVD-R
-            AddCategoryMapping(8,  TorznabCatType.MoviesSD); // Movies: SD|x264
-            AddCategoryMapping(13, TorznabCatType.MoviesSD); // Movies: SD|XviD
-            AddCategoryMapping(40, TorznabCatType.MoviesForeign); // Movies: US Movies
-            AddCategoryMapping(33, TorznabCatType.TV); // Serien: DVD-R
-            AddCategoryMapping(34, TorznabCatType.TVHD); // Serien: HD
-            AddCategoryMapping(56, TorznabCatType.TVHD); // Serien: Packs|HD
-            AddCategoryMapping(44, TorznabCatType.TVSD); // Serien: Packs|SD
-            AddCategoryMapping(16, TorznabCatType.TVSD); // Serien: SD
-            AddCategoryMapping(10, TorznabCatType.TVOTHER); // Serien: TV/Shows
-            AddCategoryMapping(21, TorznabCatType.TVFOREIGN); // Serien: US TV
-            AddCategoryMapping(24, TorznabCatType.TVSport); // Sport: Diverses
-            AddCategoryMapping(23, TorznabCatType.TVSport); // Sport: Wrestling
-            AddCategoryMapping(57, TorznabCatType.Movies); // Tracker - Crew: pmHD
-            AddCategoryMapping(58, TorznabCatType.MoviesHD); // Ultra-HD: 4K
-            AddCategoryMapping(46, TorznabCatType.XXXOther); // XXX: Diverses
-            AddCategoryMapping(50, TorznabCatType.XXX); // XXX: HD
-            AddCategoryMapping(45, TorznabCatType.XXXPacks); // XXX: Packs
+            AddCategoryMapping(39, TorznabCatType.TVAnime); // Anime: HD|1080p
+            AddCategoryMapping(38, TorznabCatType.TVAnime); // Anime: HD|720p
+            AddCategoryMapping(1,  TorznabCatType.TVAnime); // Anime: SD
+            AddCategoryMapping(7,  TorznabCatType.PCPhoneOther); // Appz: Handy-PDA
+            AddCategoryMapping(36, TorznabCatType.PCMac); // Appz: Mac
+            AddCategoryMapping(18, TorznabCatType.PC); // Appz: Sonstiges
+            AddCategoryMapping(17, TorznabCatType.PC); // Appz: Win
+            AddCategoryMapping(15, TorznabCatType.Audio); // Audio: DVD-R
+            AddCategoryMapping(49, TorznabCatType.AudioLossless); // Audio: Flac
+            AddCategoryMapping(30, TorznabCatType.AudioAudiobook); // Audio: Hörspiele
+            AddCategoryMapping(14, TorznabCatType.AudioMP3); // Audio: MP3
+            AddCategoryMapping(22, TorznabCatType.AudioVideo); // Audio: Videoclip
+            AddCategoryMapping(19, TorznabCatType.Other); // Diverses: Sonstiges
+            AddCategoryMapping(43, TorznabCatType.TVDocumentary); // Dokus: HD
+            AddCategoryMapping(2,  TorznabCatType.TVDocumentary); // Dokus: SD
+            AddCategoryMapping(3,  TorznabCatType.Books); // Ebooks: Bücher
+            AddCategoryMapping(52, TorznabCatType.BooksComics); // Ebooks: Comics
+            AddCategoryMapping(53, TorznabCatType.BooksMagazines); // Ebooks: Magazine
+            AddCategoryMapping(55, TorznabCatType.BooksOther); // Ebooks: XXX
+            AddCategoryMapping(54, TorznabCatType.BooksOther); // Ebooks: Zeitungen
+            AddCategoryMapping(47, TorznabCatType.PCPhoneOther); // Games: Andere
+            AddCategoryMapping(32, TorznabCatType.PCMac); // Games: Mac
+            AddCategoryMapping(41, TorznabCatType.ConsoleNDS); // Games: NDS/3DS
+            AddCategoryMapping(4,  TorznabCatType.PCGames); // Games: PC
+            AddCategoryMapping(5,  TorznabCatType.ConsolePS3); // Games: PS2
+            AddCategoryMapping(9,  TorznabCatType.ConsolePS3); // Games: PS3
+            AddCategoryMapping(6,  TorznabCatType.ConsolePSP); // Games: PSP
+            AddCategoryMapping(28, TorznabCatType.ConsoleWii); // Games: Wii
+            AddCategoryMapping(31, TorznabCatType.ConsoleXbox); // Games: XboX
+            AddCategoryMapping(51, TorznabCatType.Movies3D); // Movies: 3D
+            AddCategoryMapping(37, TorznabCatType.MoviesBluRay); // Movies: BluRay
+            AddCategoryMapping(25, TorznabCatType.MoviesHD); // Movies: HD|1080p
+            AddCategoryMapping(29, TorznabCatType.MoviesHD); // Movies: HD|720p
+            AddCategoryMapping(11, TorznabCatType.MoviesDVD); // Movies: SD|DVD-R
+            AddCategoryMapping(8,  TorznabCatType.MoviesSD); // Movies: SD|x264
+            AddCategoryMapping(13, TorznabCatType.MoviesSD); // Movies: SD|XviD
+            AddCategoryMapping(40, TorznabCatType.MoviesForeign); // Movies: US Movies
+            AddCategoryMapping(33, TorznabCatType.TV); // Serien: DVD-R
+            AddCategoryMapping(34, TorznabCatType.TVHD); // Serien: HD
+            AddCategoryMapping(56, TorznabCatType.TVHD); // Serien: Packs|HD
+            AddCategoryMapping(44, TorznabCatType.TVSD); // Serien: Packs|SD
+            AddCategoryMapping(16, TorznabCatType.TVSD); // Serien: SD
+            AddCategoryMapping(10, TorznabCatType.TVOTHER); // Serien: TV/Shows
+            AddCategoryMapping(21, TorznabCatType.TVFOREIGN); // Serien: US TV
+            AddCategoryMapping(24, TorznabCatType.TVSport); // Sport: Diverses
+            AddCategoryMapping(23, TorznabCatType.TVSport); // Sport: Wrestling
+            AddCategoryMapping(57, TorznabCatType.Movies); // Tracker - Crew: pmHD
+            AddCategoryMapping(58, TorznabCatType.MoviesHD); // Ultra-HD: 4K
+            AddCategoryMapping(46, TorznabCatType.XXXOther); // XXX: Diverses
+            AddCategoryMapping(50, TorznabCatType.XXX); // XXX: HD
+            AddCategoryMapping(45, TorznabCatType.XXXPacks); // XXX: Packs
             AddCategoryMapping(27, TorznabCatType.XXX); // XXX: SD
         }
 
@@ -118,36 +118,36 @@ namespace Jackett.Indexers
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("showsearch", "1");
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("orderby", "added");
-            queryCollection.Add("sort", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            var cats = MapTorznabCapsToTrackers(query);
-            string cat = "0";
-            if (cats.Count == 1)
-            {
-                cat = cats[0];
-            }
-            queryCollection.Add("cat", cat);
-
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("showsearch", "1");
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("orderby", "added");
+            queryCollection.Add("sort", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            var cats = MapTorznabCapsToTrackers(query);
+            string cat = "0";
+            if (cats.Count == 1)
+            {
+                cat = cats[0];
+            }
+            queryCollection.Add("cat", cat);
+
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookies(searchUrl);
@@ -160,52 +160,52 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 0.75;
+                    release.MinimumRatio = 0.75;
                     release.MinimumSeedTime = 0;
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    release.Title = qDetailsLink.Text();
-
-                    if (!query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-                    var qSeeders = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(3)");
-                    var qLeechers = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(4)");
-                    var qDateStr = qRow.Find("td > table.testtable > tbody > tr > td:eq(6)");
-                    var qSize = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(1)");
-                    var qDownloadLink = qRow.Find("a[href*=download]").First();
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    var dlLink = qDownloadLink.Attr("href");
-                    if(dlLink.Contains("javascript")) // depending on the user agent the DL link is a javascript call
-                    {
-                        var dlLinkParts = dlLink.Split(new char[] { '\'', ',' });
-                        dlLink = SiteLink + "download/" + dlLinkParts[3] + "/" + dlLinkParts[5];
-                    }
-                    release.Link = new Uri(dlLink);
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(".", "").Replace(",", "."));
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    release.Title = qDetailsLink.Text();
+
+                    if (!query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+                    var qSeeders = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(3)");
+                    var qLeechers = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(4)");
+                    var qDateStr = qRow.Find("td > table.testtable > tbody > tr > td:eq(6)");
+                    var qSize = qRow.Find("td > table.testtable > tbody > tr > td > strong:eq(1)");
+                    var qDownloadLink = qRow.Find("a[href*=download]").First();
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    var dlLink = qDownloadLink.Attr("href");
+                    if(dlLink.Contains("javascript")) // depending on the user agent the DL link is a javascript call
+                    {
+                        var dlLinkParts = dlLink.Split(new char[] { '\'', ',' });
+                        dlLink = SiteLink + "download/" + dlLinkParts[3] + "/" + dlLinkParts[5];
+                    }
+                    release.Link = new Uri(dlLink);
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr.Replace(".", "").Replace(",", "."));
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text().Replace('\xA0', ' ');
                     var dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc;
 
                     var files = qRow.Find("td:contains(Datei) > strong ~ strong").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
-                    if (qRow.Find("img[title=\"OnlyUpload\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("img[title=\"OnlyUpload\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/Norbits.cs b/src/Jackett/Indexers/Norbits.cs
index bc9fbcf2c4a1d912784b9a3a230a8dad71eb3b8b..662920507962d8b55a43c9da0534f621c632fe7b 100644
--- a/src/Jackett/Indexers/Norbits.cs
+++ b/src/Jackett/Indexers/Norbits.cs
@@ -1,875 +1,875 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Linq;
-using System.Reflection;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-using CsQuery;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig.Bespoke;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System.Text;
-
-namespace Jackett.Indexers
-{
-    /// <summary>s
-    /// Provider for Norbits Private Tracker
-    /// </summary>
-    public class Norbits : BaseIndexer, IIndexer
-    {
-        private string LoginUrl => SiteLink + "login.php";
-        private string LoginCheckUrl => SiteLink + "takelogin.php";
-        private string SearchUrl => SiteLink + "browse.php";
-        private string TorrentCommentUrl => SiteLink + "details.php?id={id}&comonly=1#page1";
-        private string TorrentDescriptionUrl => SiteLink + "details.php?id={id}";
-        private string TorrentDownloadUrl => SiteLink + "download.php?id={id}&passkey={passkey}";
-        private bool Latency => ConfigData.Latency.Value;
-        private bool DevMode => ConfigData.DevMode.Value;
-        private bool CacheMode => ConfigData.HardDriveCache.Value;
-        private static string Directory => System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType?.Name + "\\";
-
-        private readonly Dictionary<string, string> _emulatedBrowserHeaders = new Dictionary<string, string>();
-        private CQ _fDom;
-        private ConfigurationDataNorbits ConfigData => (ConfigurationDataNorbits)configData;
-
-        public Norbits(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
-            : base(
-                name: "Norbits",
-                description: "Norbits",
-                link: "https://norbits.net/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                downloadBase: "https://norbits.net/download.php?id=",
-                configData: new ConfigurationDataNorbits())
-        {
-            Encoding = Encoding.GetEncoding("iso-8859-1");
-            Language = "nb-no";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping("main_cat[]=1&sub2_cat[]=19", TorznabCatType.MoviesHD, "Filmer - HD-1080p/i");
-            AddCategoryMapping("main_cat[]=1&sub2_cat[]=20", TorznabCatType.MoviesHD, "Filmer - HD-720p");
-            AddCategoryMapping("main_cat[]=1&sub2_cat[]=22", TorznabCatType.MoviesSD, "Filmer - SD");
-            AddCategoryMapping("main_cat[]=2&sub2_cat[]=19", TorznabCatType.TVHD, "TV - HD-1080p/i");
-            AddCategoryMapping("main_cat[]=2&sub2_cat[]=20", TorznabCatType.TVHD, "TV - HD-720p");
-            AddCategoryMapping("main_cat[]=2&sub2_cat[]=22", TorznabCatType.TVSD, "TV - SD");
-            AddCategoryMapping("main_cat[]=3", TorznabCatType.PC, "Programmer");
-            AddCategoryMapping("main_cat[]=4", TorznabCatType.Console, "Spill");
-            AddCategoryMapping("main_cat[]=5&sub2_cat[]=42", TorznabCatType.AudioMP3, "Musikk - 192");
-            AddCategoryMapping("main_cat[]=5&sub2_cat[]=43", TorznabCatType.AudioMP3, "Musikk - 256");
-            AddCategoryMapping("main_cat[]=5&sub2_cat[]=44", TorznabCatType.AudioMP3, "Musikk - 320");
-            AddCategoryMapping("main_cat[]=5&sub2_cat[]=45", TorznabCatType.AudioMP3, "Musikk - VBR");
-            AddCategoryMapping("main_cat[]=5&sub2_cat[]=46", TorznabCatType.AudioLossless, "Musikk - Lossless");
-            AddCategoryMapping("main_cat[]=6", TorznabCatType.Books, "Tidsskrift");
-            AddCategoryMapping("main_cat[]=7", TorznabCatType.AudioAudiobook, "Lydbøker");
-            AddCategoryMapping("main_cat[]=8&sub2_cat[]=19", TorznabCatType.AudioVideo, "Musikkvideoer - HD-1080p/i");
-            AddCategoryMapping("main_cat[]=8&sub2_cat[]=20", TorznabCatType.AudioVideo, "Musikkvideoer - HD-720p");
-            AddCategoryMapping("main_cat[]=8&sub2_cat[]=22", TorznabCatType.AudioVideo, "Musikkvideoer - SD");
-            AddCategoryMapping("main_cat[]=40", TorznabCatType.AudioOther, "Podcasts");
-        }
-
-        /// <summary>
-        /// Configure our FADN Provider
-        /// </summary>
-        /// <param name="configJson">Our params in Json</param>
-        /// <returns>Configuration state</returns>
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            // Retrieve config values set by Jackett's user
-            LoadValuesFromJson(configJson);
-
-            // Check & Validate Config
-            ValidateConfig();
-
-            // Setting our data for a better emulated browser (maximum security)
-            // TODO: Encoded Content not supported by Jackett at this time
-            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
-
-            // If we want to simulate a browser
-            if (ConfigData.Browser.Value)
-            {
-
-                // Clean headers
-                _emulatedBrowserHeaders.Clear();
-
-                // Inject headers
-                _emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
-                _emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
-                _emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDnt.Value).ToString());
-                _emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
-                _emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
-                _emulatedBrowserHeaders.Add("Referer", LoginUrl);
-            }
-
-            await DoLogin();
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        /// <summary>
-        /// Perform login to racker
-        /// </summary>
-        /// <returns></returns>
-        private async Task DoLogin()
-        {
-            // Build WebRequest for index
-            var myIndexRequest = new WebRequest()
-            {
-                Type = RequestType.GET,
-                Url = SiteLink,
-                Headers = _emulatedBrowserHeaders,
-                Encoding = Encoding
-            };
-
-            // Get index page for cookies
-            Output("\nGetting index page (for cookies).. with " + SiteLink);
-            var indexPage = await webclient.GetString(myIndexRequest);
-
-            // Building login form data
-            var pairs = new Dictionary<string, string> {
-                { "username", ConfigData.Username.Value },
-                { "password", ConfigData.Password.Value }
-            };
-
-            // Build WebRequest for login
-            var myRequestLogin = new WebRequest()
-            {
-                Type = RequestType.GET,
-                Url = LoginUrl,
-                Headers = _emulatedBrowserHeaders,
-                Cookies = indexPage.Cookies,
-                Referer = SiteLink,
-                Encoding = Encoding
-            };
-
-            // Get login page -- (not used, but simulation needed by tracker security's checks)
-            LatencyNow();
-            Output("\nGetting login page (user simulation).. with " + LoginUrl);
-            await webclient.GetString(myRequestLogin);
-
-            // Build WebRequest for submitting authentification
-            var request = new WebRequest()
-            {
-                PostData = pairs,
-                Referer = LoginUrl,
-                Type = RequestType.POST,
-                Url = LoginCheckUrl,
-                Headers = _emulatedBrowserHeaders,
-                Cookies = indexPage.Cookies,
-                Encoding = Encoding
-            };
-
-            // Perform loggin
-            LatencyNow();
-            Output("\nPerform loggin.. with " + LoginCheckUrl);
-            var response = await webclient.GetString(request);
-
-            // Test if we are logged in
-            await ConfigureIfOK(response.Cookies, response.Content != null && response.Cookies.Contains("uid="), () =>
-            {
-                // Default error message
-                var message = "Error during attempt !";
-                // Parse redirect header
-                var redirectTo = response.RedirectingTo;
-                
-                // Oops, unable to login
-                Output("-> Login failed: " + message, "error");
-                throw new ExceptionWithConfigData("Login failed: " + message, configData);
-            });
-
-            Output("\nCookies saved for future uses...");
-            ConfigData.CookieHeader.Value = indexPage.Cookies + " " + response.Cookies + " ts_username=" + ConfigData.Username.Value;
-
-            Output("\n-> Login Success\n");
-        }
-
-        /// <summary>
-        /// Check logged-in state for provider
-        /// </summary>
-        /// <returns></returns>
-        private async Task CheckLogin()
-        {
-            // Checking ...
-            Output("\n-> Checking logged-in state....");
-            var loggedInCheck = await RequestStringWithCookies(SearchUrl);
-            if (!loggedInCheck.Content.Contains("logout.php"))
-            {
-                // Cookie expired, renew session on provider
-                Output("-> Not logged, login now...\n");
-
-                await DoLogin();
-            }
-            else
-            {
-                // Already logged, session active
-                Output("-> Already logged, continue...\n");
-            }
-        }
-
-        /// <summary>
-        /// Execute our search query
-        /// </summary>
-        /// <param name="query">Query</param>
-        /// <returns>Releases</returns>
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var torrentRowList = new List<CQ>();
-            var exactSearchTerm = query.GetQueryString();
-            var searchUrl = SearchUrl;
-
-            // Check login before performing a query
-           await CheckLogin();
-
-            // Check cache first so we don't query the server (if search term used or not in dev mode)
-            if (!DevMode && !string.IsNullOrEmpty(exactSearchTerm))
-            {
-                lock (cache)
-                {
-                    // Remove old cache items
-                    CleanCache();
-
-                    // Search in cache
-                    var cachedResult = cache.FirstOrDefault(i => i.Query == exactSearchTerm);
-                    if (cachedResult != null)
-                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
-                }
-            }
-
-            var SearchTerms = new List<string> { exactSearchTerm };
-
-            // duplicate search without diacritics
-            var baseSearchTerm = StringUtil.RemoveDiacritics(exactSearchTerm);
-            if (baseSearchTerm != exactSearchTerm)
-                SearchTerms.Add(baseSearchTerm);
-
-            foreach (var searchTerm in SearchTerms)
-            {
-                // Build our query
-                var request = BuildQuery(searchTerm, query, searchUrl);
-
-                // Getting results & Store content
-                var response = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value);
-                _fDom = response.Content;
-
-                try
-                {
-                    var firstPageRows = FindTorrentRows();
-
-                    // Add them to torrents list
-                    torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
-
-                    // If pagination available
-                    int nbResults;
-                    int pageLinkCount;
-                    nbResults = 1;
-                    pageLinkCount = 1;
-
-                    // Check if we have a minimum of one result
-                    if (firstPageRows.Length > 1)
-                    {
-                        // Retrieve total count on our alone page
-                        nbResults = firstPageRows.Count();
-                    }
-                    else
-                    {
-                        // Check if no result
-                        if(torrentRowList.Count == 0)
-                        {
-                            // No results found
-                            Output("\nNo result found for your query, please try another search term ...\n", "info");
-
-                            // No result found for this query
-                            break;
-                        }
-                    }
-
-                    Output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
-                    Output("\nThere are " + firstPageRows.Length + " results on the first page !");
-
-                    // Loop on results
-
-                    foreach (var tRow in torrentRowList)
-                    {
-                        Output("Torrent #" + (releases.Count + 1));
-
-                        // ID               
-                        var id = tRow.Find("td:eq(1) > a:eq(0)").Attr("href").Split('=').Last();
-                        Output("ID: " + id);
-
-                        // Release Name
-                        var name = tRow.Find("td:eq(1) > a:eq(0)").Attr("title");
-
-                        // Category
-                        var categoryId = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last();
-                        var categoryName = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("title");
-          
-                        var MainCat = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last();
-                        var SubCat1 = "none";
-                        var SubCat2 = "none";
-
-                        var testcat = MainCat;
-
-                        if (tRow.Find("td:eq(0) > div > a:eq(1)").Length == 1)
-                        {
-                            SubCat1 = tRow.Find("td:eq(0) > div > a:eq(1)").Attr("href").Split('?').Last();
-                        }
-                        if (tRow.Find("td:eq(0) > div > a[href^=\"/browse.php?sub2_cat[]=\"]").Length == 1)
-                        {
-                            SubCat2 = tRow.Find("td:eq(0) > div > a[href^=\"/browse.php?sub2_cat[]=\"]").Attr("href").Split('?').Last();
-                            testcat = MainCat + '&' + SubCat2;
-                        }
-
-                        Output("Category: " + testcat + " - " + categoryName);
-
-                        // Seeders
-                        var seeders = ParseUtil.CoerceInt(tRow.Find("td:eq(9)").Text());
-                        Output("Seeders: " + seeders);
-                    
-                        // Leechers
-                        var leechers = ParseUtil.CoerceInt(tRow.Find("td:eq(10)").Text());
-                        Output("Leechers: " + leechers);
-
-                        // Completed
-                        Regex regexObj = new Regex(@"[^\d]");
-                        var completed2 = tRow.Find("td:eq(7)").Text();
-                        var completed = ParseUtil.CoerceLong(regexObj.Replace(completed2, ""));
-                        Output("Completed: " + completed);
-
-                        // Files
-                        var files = 1;
-                        if (tRow.Find("td:eq(2) > a").Length == 1)
-                        {
-                            files = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(2) > a").Text(), @"\d+").Value);
-                        }
-                        Output("Files: " + files);
-
-                        // Health
-                        var percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8)").Text(), @"\d+").Value.Trim());
-                        Output("Health: " + percent + "%");
-
-                        // Size
-                        var humanSize = tRow.Find("td:eq(6)").Text().ToLowerInvariant();
-                        var size = ReleaseInfo.GetBytes(humanSize);
-                        Output("Size: " + humanSize + " (" + size + " bytes)");
-
-                        // --> Date
-                        var dateTimeOrig = tRow.Find("td:eq(4)").Text();
-                        var dateTime = Regex.Replace(dateTimeOrig, @"<[^>]+>|&nbsp;", "").Trim();
-                        var date = DateTime.ParseExact(dateTime, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
-                        Output("Released on: " + date);
-
-                        // Torrent Details URL
-                        var detailsLink = new Uri(TorrentDescriptionUrl.Replace("{id}", id.ToString()));
-                        Output("Details: " + detailsLink.AbsoluteUri);
-
-                        // Torrent Comments URL
-                        var commentsLink = new Uri(TorrentCommentUrl.Replace("{id}", id.ToString()));
-                        Output("Comments Link: " + commentsLink.AbsoluteUri);
-
-                        // Torrent Download URL
-                        var passkey = tRow.Find("td:eq(1) > a:eq(1)").Attr("href");
-                        var key = Regex.Match(passkey, "(?<=passkey\\=)([a-zA-z0-9]*)");
-                        Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{passkey}", key.ToString()));
-                        Output("Download Link: " + downloadLink.AbsoluteUri);
-
-                        // Building release infos
-                        var release = new ReleaseInfo
-                        {
-                            Category = MapTrackerCatToNewznab(testcat.ToString()),
-                            Title = name,
-                            Seeders = seeders,
-                            Peers = seeders + leechers,
-                            MinimumRatio = 1,
-                            MinimumSeedTime = 172800,
-                            PublishDate = date,
-                            Size = size,
-                            Files = files,
-                            Grabs = completed,
-                            Guid = detailsLink,
-                            Comments = commentsLink,
-                            Link = downloadLink
-                        };
-
-                        var genres = tRow.Find("span.genres").Text();
-                        if (!string.IsNullOrEmpty(genres))
-                            release.Description = genres;
-
-                        // IMDB
-                        var imdbLink = tRow.Find("a[href*=\"http://imdb.com/title/\"]").First().Attr("href");
-                        release.Imdb = ParseUtil.GetLongFromString(imdbLink);
-
-                        if (tRow.Find("img[title=\"100% freeleech\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0;
-                        else if (tRow.Find("img[title=\"Halfleech\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0.5;
-                        else if (tRow.Find("img[title=\"90% Freeleech\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0.1;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Linq;
+using System.Reflection;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+using CsQuery;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig.Bespoke;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System.Text;
+
+namespace Jackett.Indexers
+{
+    /// <summary>s
+    /// Provider for Norbits Private Tracker
+    /// </summary>
+    public class Norbits : BaseIndexer, IIndexer
+    {
+        private string LoginUrl => SiteLink + "login.php";
+        private string LoginCheckUrl => SiteLink + "takelogin.php";
+        private string SearchUrl => SiteLink + "browse.php";
+        private string TorrentCommentUrl => SiteLink + "details.php?id={id}&comonly=1#page1";
+        private string TorrentDescriptionUrl => SiteLink + "details.php?id={id}";
+        private string TorrentDownloadUrl => SiteLink + "download.php?id={id}&passkey={passkey}";
+        private bool Latency => ConfigData.Latency.Value;
+        private bool DevMode => ConfigData.DevMode.Value;
+        private bool CacheMode => ConfigData.HardDriveCache.Value;
+        private static string Directory => System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType?.Name + "\\";
+
+        private readonly Dictionary<string, string> _emulatedBrowserHeaders = new Dictionary<string, string>();
+        private CQ _fDom;
+        private ConfigurationDataNorbits ConfigData => (ConfigurationDataNorbits)configData;
+
+        public Norbits(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
+            : base(
+                name: "Norbits",
+                description: "Norbits",
+                link: "https://norbits.net/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                downloadBase: "https://norbits.net/download.php?id=",
+                configData: new ConfigurationDataNorbits())
+        {
+            Encoding = Encoding.GetEncoding("iso-8859-1");
+            Language = "nb-no";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping("main_cat[]=1&sub2_cat[]=19", TorznabCatType.MoviesHD, "Filmer - HD-1080p/i");
+            AddCategoryMapping("main_cat[]=1&sub2_cat[]=20", TorznabCatType.MoviesHD, "Filmer - HD-720p");
+            AddCategoryMapping("main_cat[]=1&sub2_cat[]=22", TorznabCatType.MoviesSD, "Filmer - SD");
+            AddCategoryMapping("main_cat[]=2&sub2_cat[]=19", TorznabCatType.TVHD, "TV - HD-1080p/i");
+            AddCategoryMapping("main_cat[]=2&sub2_cat[]=20", TorznabCatType.TVHD, "TV - HD-720p");
+            AddCategoryMapping("main_cat[]=2&sub2_cat[]=22", TorznabCatType.TVSD, "TV - SD");
+            AddCategoryMapping("main_cat[]=3", TorznabCatType.PC, "Programmer");
+            AddCategoryMapping("main_cat[]=4", TorznabCatType.Console, "Spill");
+            AddCategoryMapping("main_cat[]=5&sub2_cat[]=42", TorznabCatType.AudioMP3, "Musikk - 192");
+            AddCategoryMapping("main_cat[]=5&sub2_cat[]=43", TorznabCatType.AudioMP3, "Musikk - 256");
+            AddCategoryMapping("main_cat[]=5&sub2_cat[]=44", TorznabCatType.AudioMP3, "Musikk - 320");
+            AddCategoryMapping("main_cat[]=5&sub2_cat[]=45", TorznabCatType.AudioMP3, "Musikk - VBR");
+            AddCategoryMapping("main_cat[]=5&sub2_cat[]=46", TorznabCatType.AudioLossless, "Musikk - Lossless");
+            AddCategoryMapping("main_cat[]=6", TorznabCatType.Books, "Tidsskrift");
+            AddCategoryMapping("main_cat[]=7", TorznabCatType.AudioAudiobook, "Lydbøker");
+            AddCategoryMapping("main_cat[]=8&sub2_cat[]=19", TorznabCatType.AudioVideo, "Musikkvideoer - HD-1080p/i");
+            AddCategoryMapping("main_cat[]=8&sub2_cat[]=20", TorznabCatType.AudioVideo, "Musikkvideoer - HD-720p");
+            AddCategoryMapping("main_cat[]=8&sub2_cat[]=22", TorznabCatType.AudioVideo, "Musikkvideoer - SD");
+            AddCategoryMapping("main_cat[]=40", TorznabCatType.AudioOther, "Podcasts");
+        }
+
+        /// <summary>
+        /// Configure our FADN Provider
+        /// </summary>
+        /// <param name="configJson">Our params in Json</param>
+        /// <returns>Configuration state</returns>
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            // Retrieve config values set by Jackett's user
+            LoadValuesFromJson(configJson);
+
+            // Check & Validate Config
+            ValidateConfig();
+
+            // Setting our data for a better emulated browser (maximum security)
+            // TODO: Encoded Content not supported by Jackett at this time
+            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
+
+            // If we want to simulate a browser
+            if (ConfigData.Browser.Value)
+            {
+
+                // Clean headers
+                _emulatedBrowserHeaders.Clear();
+
+                // Inject headers
+                _emulatedBrowserHeaders.Add("Accept", ConfigData.HeaderAccept.Value);
+                _emulatedBrowserHeaders.Add("Accept-Language", ConfigData.HeaderAcceptLang.Value);
+                _emulatedBrowserHeaders.Add("DNT", Convert.ToInt32(ConfigData.HeaderDnt.Value).ToString());
+                _emulatedBrowserHeaders.Add("Upgrade-Insecure-Requests", Convert.ToInt32(ConfigData.HeaderUpgradeInsecure.Value).ToString());
+                _emulatedBrowserHeaders.Add("User-Agent", ConfigData.HeaderUserAgent.Value);
+                _emulatedBrowserHeaders.Add("Referer", LoginUrl);
+            }
+
+            await DoLogin();
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        /// <summary>
+        /// Perform login to racker
+        /// </summary>
+        /// <returns></returns>
+        private async Task DoLogin()
+        {
+            // Build WebRequest for index
+            var myIndexRequest = new WebRequest()
+            {
+                Type = RequestType.GET,
+                Url = SiteLink,
+                Headers = _emulatedBrowserHeaders,
+                Encoding = Encoding
+            };
+
+            // Get index page for cookies
+            Output("\nGetting index page (for cookies).. with " + SiteLink);
+            var indexPage = await webclient.GetString(myIndexRequest);
+
+            // Building login form data
+            var pairs = new Dictionary<string, string> {
+                { "username", ConfigData.Username.Value },
+                { "password", ConfigData.Password.Value }
+            };
+
+            // Build WebRequest for login
+            var myRequestLogin = new WebRequest()
+            {
+                Type = RequestType.GET,
+                Url = LoginUrl,
+                Headers = _emulatedBrowserHeaders,
+                Cookies = indexPage.Cookies,
+                Referer = SiteLink,
+                Encoding = Encoding
+            };
+
+            // Get login page -- (not used, but simulation needed by tracker security's checks)
+            LatencyNow();
+            Output("\nGetting login page (user simulation).. with " + LoginUrl);
+            await webclient.GetString(myRequestLogin);
+
+            // Build WebRequest for submitting authentification
+            var request = new WebRequest()
+            {
+                PostData = pairs,
+                Referer = LoginUrl,
+                Type = RequestType.POST,
+                Url = LoginCheckUrl,
+                Headers = _emulatedBrowserHeaders,
+                Cookies = indexPage.Cookies,
+                Encoding = Encoding
+            };
+
+            // Perform loggin
+            LatencyNow();
+            Output("\nPerform loggin.. with " + LoginCheckUrl);
+            var response = await webclient.GetString(request);
+
+            // Test if we are logged in
+            await ConfigureIfOK(response.Cookies, response.Content != null && response.Cookies.Contains("uid="), () =>
+            {
+                // Default error message
+                var message = "Error during attempt !";
+                // Parse redirect header
+                var redirectTo = response.RedirectingTo;
+                
+                // Oops, unable to login
+                Output("-> Login failed: " + message, "error");
+                throw new ExceptionWithConfigData("Login failed: " + message, configData);
+            });
+
+            Output("\nCookies saved for future uses...");
+            ConfigData.CookieHeader.Value = indexPage.Cookies + " " + response.Cookies + " ts_username=" + ConfigData.Username.Value;
+
+            Output("\n-> Login Success\n");
+        }
+
+        /// <summary>
+        /// Check logged-in state for provider
+        /// </summary>
+        /// <returns></returns>
+        private async Task CheckLogin()
+        {
+            // Checking ...
+            Output("\n-> Checking logged-in state....");
+            var loggedInCheck = await RequestStringWithCookies(SearchUrl);
+            if (!loggedInCheck.Content.Contains("logout.php"))
+            {
+                // Cookie expired, renew session on provider
+                Output("-> Not logged, login now...\n");
+
+                await DoLogin();
+            }
+            else
+            {
+                // Already logged, session active
+                Output("-> Already logged, continue...\n");
+            }
+        }
+
+        /// <summary>
+        /// Execute our search query
+        /// </summary>
+        /// <param name="query">Query</param>
+        /// <returns>Releases</returns>
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var torrentRowList = new List<CQ>();
+            var exactSearchTerm = query.GetQueryString();
+            var searchUrl = SearchUrl;
+
+            // Check login before performing a query
+           await CheckLogin();
+
+            // Check cache first so we don't query the server (if search term used or not in dev mode)
+            if (!DevMode && !string.IsNullOrEmpty(exactSearchTerm))
+            {
+                lock (cache)
+                {
+                    // Remove old cache items
+                    CleanCache();
+
+                    // Search in cache
+                    var cachedResult = cache.FirstOrDefault(i => i.Query == exactSearchTerm);
+                    if (cachedResult != null)
+                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
+                }
+            }
+
+            var SearchTerms = new List<string> { exactSearchTerm };
+
+            // duplicate search without diacritics
+            var baseSearchTerm = StringUtil.RemoveDiacritics(exactSearchTerm);
+            if (baseSearchTerm != exactSearchTerm)
+                SearchTerms.Add(baseSearchTerm);
+
+            foreach (var searchTerm in SearchTerms)
+            {
+                // Build our query
+                var request = BuildQuery(searchTerm, query, searchUrl);
+
+                // Getting results & Store content
+                var response = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value);
+                _fDom = response.Content;
+
+                try
+                {
+                    var firstPageRows = FindTorrentRows();
+
+                    // Add them to torrents list
+                    torrentRowList.AddRange(firstPageRows.Select(fRow => fRow.Cq()));
+
+                    // If pagination available
+                    int nbResults;
+                    int pageLinkCount;
+                    nbResults = 1;
+                    pageLinkCount = 1;
+
+                    // Check if we have a minimum of one result
+                    if (firstPageRows.Length > 1)
+                    {
+                        // Retrieve total count on our alone page
+                        nbResults = firstPageRows.Count();
+                    }
+                    else
+                    {
+                        // Check if no result
+                        if(torrentRowList.Count == 0)
+                        {
+                            // No results found
+                            Output("\nNo result found for your query, please try another search term ...\n", "info");
+
+                            // No result found for this query
+                            break;
+                        }
+                    }
+
+                    Output("\nFound " + nbResults + " result(s) (+/- " + firstPageRows.Length + ") in " + pageLinkCount + " page(s) for this query !");
+                    Output("\nThere are " + firstPageRows.Length + " results on the first page !");
+
+                    // Loop on results
+
+                    foreach (var tRow in torrentRowList)
+                    {
+                        Output("Torrent #" + (releases.Count + 1));
+
+                        // ID               
+                        var id = tRow.Find("td:eq(1) > a:eq(0)").Attr("href").Split('=').Last();
+                        Output("ID: " + id);
+
+                        // Release Name
+                        var name = tRow.Find("td:eq(1) > a:eq(0)").Attr("title");
+
+                        // Category
+                        var categoryId = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last();
+                        var categoryName = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("title");
+          
+                        var MainCat = tRow.Find("td:eq(0) > div > a:eq(0)").Attr("href").Split('?').Last();
+                        var SubCat1 = "none";
+                        var SubCat2 = "none";
+
+                        var testcat = MainCat;
+
+                        if (tRow.Find("td:eq(0) > div > a:eq(1)").Length == 1)
+                        {
+                            SubCat1 = tRow.Find("td:eq(0) > div > a:eq(1)").Attr("href").Split('?').Last();
+                        }
+                        if (tRow.Find("td:eq(0) > div > a[href^=\"/browse.php?sub2_cat[]=\"]").Length == 1)
+                        {
+                            SubCat2 = tRow.Find("td:eq(0) > div > a[href^=\"/browse.php?sub2_cat[]=\"]").Attr("href").Split('?').Last();
+                            testcat = MainCat + '&' + SubCat2;
+                        }
+
+                        Output("Category: " + testcat + " - " + categoryName);
+
+                        // Seeders
+                        var seeders = ParseUtil.CoerceInt(tRow.Find("td:eq(9)").Text());
+                        Output("Seeders: " + seeders);
+                    
+                        // Leechers
+                        var leechers = ParseUtil.CoerceInt(tRow.Find("td:eq(10)").Text());
+                        Output("Leechers: " + leechers);
+
+                        // Completed
+                        Regex regexObj = new Regex(@"[^\d]");
+                        var completed2 = tRow.Find("td:eq(7)").Text();
+                        var completed = ParseUtil.CoerceLong(regexObj.Replace(completed2, ""));
+                        Output("Completed: " + completed);
+
+                        // Files
+                        var files = 1;
+                        if (tRow.Find("td:eq(2) > a").Length == 1)
+                        {
+                            files = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(2) > a").Text(), @"\d+").Value);
+                        }
+                        Output("Files: " + files);
+
+                        // Health
+                        var percent = ParseUtil.CoerceInt(Regex.Match(tRow.Find("td:eq(8)").Text(), @"\d+").Value.Trim());
+                        Output("Health: " + percent + "%");
+
+                        // Size
+                        var humanSize = tRow.Find("td:eq(6)").Text().ToLowerInvariant();
+                        var size = ReleaseInfo.GetBytes(humanSize);
+                        Output("Size: " + humanSize + " (" + size + " bytes)");
+
+                        // --> Date
+                        var dateTimeOrig = tRow.Find("td:eq(4)").Text();
+                        var dateTime = Regex.Replace(dateTimeOrig, @"<[^>]+>|&nbsp;", "").Trim();
+                        var date = DateTime.ParseExact(dateTime, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();
+                        Output("Released on: " + date);
+
+                        // Torrent Details URL
+                        var detailsLink = new Uri(TorrentDescriptionUrl.Replace("{id}", id.ToString()));
+                        Output("Details: " + detailsLink.AbsoluteUri);
+
+                        // Torrent Comments URL
+                        var commentsLink = new Uri(TorrentCommentUrl.Replace("{id}", id.ToString()));
+                        Output("Comments Link: " + commentsLink.AbsoluteUri);
+
+                        // Torrent Download URL
+                        var passkey = tRow.Find("td:eq(1) > a:eq(1)").Attr("href");
+                        var key = Regex.Match(passkey, "(?<=passkey\\=)([a-zA-z0-9]*)");
+                        Uri downloadLink = new Uri(TorrentDownloadUrl.Replace("{id}", id.ToString()).Replace("{passkey}", key.ToString()));
+                        Output("Download Link: " + downloadLink.AbsoluteUri);
+
+                        // Building release infos
+                        var release = new ReleaseInfo
+                        {
+                            Category = MapTrackerCatToNewznab(testcat.ToString()),
+                            Title = name,
+                            Seeders = seeders,
+                            Peers = seeders + leechers,
+                            MinimumRatio = 1,
+                            MinimumSeedTime = 172800,
+                            PublishDate = date,
+                            Size = size,
+                            Files = files,
+                            Grabs = completed,
+                            Guid = detailsLink,
+                            Comments = commentsLink,
+                            Link = downloadLink
+                        };
+
+                        var genres = tRow.Find("span.genres").Text();
+                        if (!string.IsNullOrEmpty(genres))
+                            release.Description = genres;
+
+                        // IMDB
+                        var imdbLink = tRow.Find("a[href*=\"http://imdb.com/title/\"]").First().Attr("href");
+                        release.Imdb = ParseUtil.GetLongFromString(imdbLink);
+
+                        if (tRow.Find("img[title=\"100% freeleech\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0;
+                        else if (tRow.Find("img[title=\"Halfleech\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0.5;
+                        else if (tRow.Find("img[title=\"90% Freeleech\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0.1;
                         else
-                            release.DownloadVolumeFactor = 1;
-
-                        release.UploadVolumeFactor = 1;
-
-                        releases.Add(release);
-                    }
-
-                }
-                catch (Exception ex)
-                {
-                    OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
-                }
-            }
-            // Return found releases
-            return releases;
-        }
-
-        /// <summary>
-        /// Build query to process
-        /// </summary>
-        /// <param name="term">Term to search</param>
-        /// <param name="query">Torznab Query for categories mapping</param>
-        /// <param name="url">Search url for provider</param>
-        /// <param name="page">Page number to request</param>
-        /// <returns>URL to query for parsing and processing results</returns>
-        private string BuildQuery(string term, TorznabQuery query, string url, int page = 0)
-        {
-            var parameters = new NameValueCollection();
-            var categoriesList = MapTorznabCapsToTrackers(query);
-            string searchterm = term;
-
-            // Building our tracker query
-            parameters.Add("incldead", "1");
-            parameters.Add("fullsearch", "0");
-            parameters.Add("scenerelease", "0");
-
-            // If search term provided
+                            release.DownloadVolumeFactor = 1;
+
+                        release.UploadVolumeFactor = 1;
+
+                        releases.Add(release);
+                    }
+
+                }
+                catch (Exception ex)
+                {
+                    OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
+                }
+            }
+            // Return found releases
+            return releases;
+        }
+
+        /// <summary>
+        /// Build query to process
+        /// </summary>
+        /// <param name="term">Term to search</param>
+        /// <param name="query">Torznab Query for categories mapping</param>
+        /// <param name="url">Search url for provider</param>
+        /// <param name="page">Page number to request</param>
+        /// <returns>URL to query for parsing and processing results</returns>
+        private string BuildQuery(string term, TorznabQuery query, string url, int page = 0)
+        {
+            var parameters = new NameValueCollection();
+            var categoriesList = MapTorznabCapsToTrackers(query);
+            string searchterm = term;
+
+            // Building our tracker query
+            parameters.Add("incldead", "1");
+            parameters.Add("fullsearch", "0");
+            parameters.Add("scenerelease", "0");
+
+            // If search term provided
             if (!string.IsNullOrWhiteSpace(query.ImdbID))
             {
                 searchterm = "imdbsearch=" + query.ImdbID;
             }
-            else if (!string.IsNullOrWhiteSpace(term))
-            {
-                searchterm = "search=" + System.Web.HttpUtility.UrlEncode(term, Encoding.GetEncoding(28591));
-            }
-            else
-            {
-                // Showing all torrents (just for output function)
-                searchterm = "search=";
-                term = "all";
-            }
-
-            var CatQryStr = "";
-            foreach (var cat in categoriesList)
-                CatQryStr += "&" + cat;
-
-            // Building our query
-            url += "?" + searchterm + "&" + parameters.GetQueryString() + "&" + CatQryStr;
-
-            Output("\nBuilded query for \"" + term + "\"... " + url);
-
-            // Return our search url
-            return url;
-        }
-
-        /// <summary>
-        /// Switch Method for Querying
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryExec(string request)
-        {
-            WebClientStringResult results;
-
-            // Switch in we are in DEV mode with Hard Drive Cache or not
-            if (DevMode && CacheMode)
-            {
-                // Check Cache before querying and load previous results if available
-                results = await QueryCache(request);
-            }
-            else
-            {
-                // Querying tracker directly
-                results = await QueryTracker(request);
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Cache by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryCache(string request)
-        {
-            WebClientStringResult results;
-
-            // Create Directory if not exist
-            System.IO.Directory.CreateDirectory(Directory);
-
-            // Clean Storage Provider Directory from outdated cached queries
-            CleanCacheStorage();
-
-            // Create fingerprint for request
-            var file = Directory + request.GetHashCode() + ".json";
-
-            // Checking modes states
-            if (System.IO.File.Exists(file))
-            {
-                // File exist... loading it right now !
-                Output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
-                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
-            }
-            else
-            {
-                // No cached file found, querying tracker directly
-                results = await QueryTracker(request);
-
-                // Cached file didn't exist for our query, writing it right now !
-                Output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
-                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Tracker by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryTracker(string request)
-        {
-            // Cache mode not enabled or cached file didn't exist for our query
-            Output("\nQuerying tracker for results....");
-
-            // Request our first page
-            LatencyNow();
-            var results = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value, SearchUrl, _emulatedBrowserHeaders);
-
-            // Return results from tracker
-            return results;
-        }
-
-        /// <summary>
-        /// Clean Hard Drive Cache Storage
-        /// </summary>
-        /// <param name="force">Force Provider Folder deletion</param>
-        private void CleanCacheStorage(bool force = false)
-        {
-            // Check cleaning method
-            if (force)
-            {
-                // Deleting Provider Storage folder and all files recursively
-                Output("\nDeleting Provider Storage folder and all files recursively ...");
-
-                // Check if directory exist
-                if (System.IO.Directory.Exists(Directory))
-                {
-                    // Delete storage directory of provider
-                    System.IO.Directory.Delete(Directory, true);
-                    Output("-> Storage folder deleted successfully.");
-                }
-                else
-                {
-                    // No directory, so nothing to do
-                    Output("-> No Storage folder found for this provider !");
-                }
-            }
-            else
-            {
-                var i = 0;
-                // Check if there is file older than ... and delete them
-                Output("\nCleaning Provider Storage folder... in progress.");
-                System.IO.Directory.GetFiles(Directory)
-                .Select(f => new System.IO.FileInfo(f))
-                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
-                .ToList()
-                .ForEach(f => {
-                    Output("Deleting cached file << " + f.Name + " >> ... done.");
-                    f.Delete();
-                    i++;
-                });
-
-                // Inform on what was cleaned during process
-                if (i > 0)
-                {
-                    Output("-> Deleted " + i + " cached files during cleaning.");
-                }
-                else {
-                    Output("-> Nothing deleted during cleaning.");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Generate a random fake latency to avoid detection on tracker side
-        /// </summary>
-        private void LatencyNow()
-        {
-            // Need latency ?
-            if (Latency)
-            {
-                var random = new Random(DateTime.Now.Millisecond);
-                var waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value),
-                    Convert.ToInt32(ConfigData.LatencyEnd.Value));
-                Output("\nLatency Faker => Sleeping for " + waiting + " ms...");
-
-                // Sleep now...
-                System.Threading.Thread.Sleep(waiting);
-            }
-            // Generate a random value in our range
-        }
-
-        /// <summary>
-        /// Find torrent rows in search pages
-        /// </summary>
-        /// <returns>JQuery Object</returns>
-        private CQ FindTorrentRows()
-        {
-            // Return all occurencis of torrents found
-            //return _fDom["#content > table > tr"];
-            return _fDom["# torrentTable > tbody > tr:not(:first)"];
-        }
-
-        /// <summary>
-        /// Download torrent file from tracker
-        /// </summary>
-        /// <param name="link">URL string</param>
-        /// <returns></returns>
-        public override async Task<byte[]> Download(Uri link)
-        {
-
-            // Retrieving ID from link provided
-            var id = ParseUtil.CoerceInt(Regex.Match(link.AbsoluteUri, @"\d+").Value);
-            Output("Torrent Requested ID: " + id);
-
-            // Building login form data
-            var pairs = new Dictionary<string, string> {
-                { "torrentid", id.ToString() },
-                { "_", string.Empty } // ~~ Strange, blank param...
-            };
-
-            // Add emulated XHR request
-            _emulatedBrowserHeaders.Add("X-Prototype-Version", "1.6.0.3");
-            _emulatedBrowserHeaders.Add("X-Requested-With", "XMLHttpRequest");
-
-            // Get torrent file now
-            Output("Getting torrent file now....");
-            var response = await base.Download(link);
-
-            // Remove our XHR request header
-            _emulatedBrowserHeaders.Remove("X-Prototype-Version");
-            _emulatedBrowserHeaders.Remove("X-Requested-With");
-
-            // Return content
-            return response;
-        }
-
-        /// <summary>
-        /// Output message for logging or developpment (console)
-        /// </summary>
-        /// <param name="message">Message to output</param>
-        /// <param name="level">Level for Logger</param>
-        private void Output(string message, string level = "debug")
-        {
-            // Check if we are in dev mode
-            if (DevMode)
-            {
-                // Output message to console
-                Console.WriteLine(message);
-            }
-            else
-            {
-                // Send message to logger with level
-                switch (level)
-                {
-                    default:
-                        goto case "debug";
-                    case "debug":
-                        // Only if Debug Level Enabled on Jackett
-                        if (Engine.Logger.IsDebugEnabled)
-                        {
-                            logger.Debug(message);
-                        }
-                        break;
-                    case "info":
-                        logger.Info(message);
-                        break;
-                    case "error":
-                        logger.Error(message);
-                        break;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Validate Config entered by user on Jackett
-        /// </summary>
-        private void ValidateConfig()
-        {
-            Output("\nValidating Settings ... \n");
-
-            // Check Username Setting
-            if (string.IsNullOrEmpty(ConfigData.Username.Value))
-            {
-                throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
-            }
-            else
-            {
-                Output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value);
-            }
-
-            // Check Password Setting
-            if (string.IsNullOrEmpty(ConfigData.Password.Value))
-            {
-                throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
-            }
-            else
-            {
-                Output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value);
-            }
-
-            // Check Max Page Setting
-            if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
-            {
-                try
-                {
-                    Output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
-                }
-                catch (Exception)
-                {
-                    throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
-                }
-            }
-            else
-            {
-                throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
-            }
-
-            // Check Latency Setting
-            if (ConfigData.Latency.Value)
-            {
-                Output("\nValidated Setting -- Latency Simulation enabled");
-
-                // Check Latency Start Setting
-                if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
-                {
-                    try
-                    {
-                        Output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
-                }
-
-                // Check Latency End Setting
-                if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
-                {
-                    try
-                    {
-                        Output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
-                }
-            }
-
-            // Check Browser Setting
-            if (ConfigData.Browser.Value)
-            {
-                Output("\nValidated Setting -- Browser Simulation enabled");
-
-                // Check ACCEPT header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
-                }
-                else
-                {
-                    Output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value);
-                }
-
-                // Check ACCEPT-LANG header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
-                }
-                else
-                {
-                    Output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value);
-                }
-
-                // Check USER-AGENT header Setting
-                if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
-                {
-                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
-                }
-                else
-                {
-                    Output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value);
-                }
-            }
-            else
-            {
-                // Browser simulation must be enabled (otherwhise, this provider will not work due to tracker's security)
-                throw new ExceptionWithConfigData("Browser Simulation must be enabled for this provider to work, please enable it !", ConfigData);
-            }
-
-            // Check Dev Cache Settings
-            if (ConfigData.HardDriveCache.Value)
-            {
-                Output("\nValidated Setting -- DEV Hard Drive Cache enabled");
-
-                // Check if Dev Mode enabled !
-                if (!ConfigData.DevMode.Value)
-                {
-                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
-                }
-
-                // Check Cache Keep Time Setting
-                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
-                {
-                    try
-                    {
-                        Output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
-                }
-            }
-            else
-            {
-                // Delete cache if previously existed
-                CleanCacheStorage(true);
-            }
-        }
-    }
-}
+            else if (!string.IsNullOrWhiteSpace(term))
+            {
+                searchterm = "search=" + System.Web.HttpUtility.UrlEncode(term, Encoding.GetEncoding(28591));
+            }
+            else
+            {
+                // Showing all torrents (just for output function)
+                searchterm = "search=";
+                term = "all";
+            }
+
+            var CatQryStr = "";
+            foreach (var cat in categoriesList)
+                CatQryStr += "&" + cat;
+
+            // Building our query
+            url += "?" + searchterm + "&" + parameters.GetQueryString() + "&" + CatQryStr;
+
+            Output("\nBuilded query for \"" + term + "\"... " + url);
+
+            // Return our search url
+            return url;
+        }
+
+        /// <summary>
+        /// Switch Method for Querying
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryExec(string request)
+        {
+            WebClientStringResult results;
+
+            // Switch in we are in DEV mode with Hard Drive Cache or not
+            if (DevMode && CacheMode)
+            {
+                // Check Cache before querying and load previous results if available
+                results = await QueryCache(request);
+            }
+            else
+            {
+                // Querying tracker directly
+                results = await QueryTracker(request);
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Cache by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryCache(string request)
+        {
+            WebClientStringResult results;
+
+            // Create Directory if not exist
+            System.IO.Directory.CreateDirectory(Directory);
+
+            // Clean Storage Provider Directory from outdated cached queries
+            CleanCacheStorage();
+
+            // Create fingerprint for request
+            var file = Directory + request.GetHashCode() + ".json";
+
+            // Checking modes states
+            if (System.IO.File.Exists(file))
+            {
+                // File exist... loading it right now !
+                Output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
+                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
+            }
+            else
+            {
+                // No cached file found, querying tracker directly
+                results = await QueryTracker(request);
+
+                // Cached file didn't exist for our query, writing it right now !
+                Output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
+                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Tracker by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryTracker(string request)
+        {
+            // Cache mode not enabled or cached file didn't exist for our query
+            Output("\nQuerying tracker for results....");
+
+            // Request our first page
+            LatencyNow();
+            var results = await RequestStringWithCookiesAndRetry(request, ConfigData.CookieHeader.Value, SearchUrl, _emulatedBrowserHeaders);
+
+            // Return results from tracker
+            return results;
+        }
+
+        /// <summary>
+        /// Clean Hard Drive Cache Storage
+        /// </summary>
+        /// <param name="force">Force Provider Folder deletion</param>
+        private void CleanCacheStorage(bool force = false)
+        {
+            // Check cleaning method
+            if (force)
+            {
+                // Deleting Provider Storage folder and all files recursively
+                Output("\nDeleting Provider Storage folder and all files recursively ...");
+
+                // Check if directory exist
+                if (System.IO.Directory.Exists(Directory))
+                {
+                    // Delete storage directory of provider
+                    System.IO.Directory.Delete(Directory, true);
+                    Output("-> Storage folder deleted successfully.");
+                }
+                else
+                {
+                    // No directory, so nothing to do
+                    Output("-> No Storage folder found for this provider !");
+                }
+            }
+            else
+            {
+                var i = 0;
+                // Check if there is file older than ... and delete them
+                Output("\nCleaning Provider Storage folder... in progress.");
+                System.IO.Directory.GetFiles(Directory)
+                .Select(f => new System.IO.FileInfo(f))
+                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
+                .ToList()
+                .ForEach(f => {
+                    Output("Deleting cached file << " + f.Name + " >> ... done.");
+                    f.Delete();
+                    i++;
+                });
+
+                // Inform on what was cleaned during process
+                if (i > 0)
+                {
+                    Output("-> Deleted " + i + " cached files during cleaning.");
+                }
+                else {
+                    Output("-> Nothing deleted during cleaning.");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Generate a random fake latency to avoid detection on tracker side
+        /// </summary>
+        private void LatencyNow()
+        {
+            // Need latency ?
+            if (Latency)
+            {
+                var random = new Random(DateTime.Now.Millisecond);
+                var waiting = random.Next(Convert.ToInt32(ConfigData.LatencyStart.Value),
+                    Convert.ToInt32(ConfigData.LatencyEnd.Value));
+                Output("\nLatency Faker => Sleeping for " + waiting + " ms...");
+
+                // Sleep now...
+                System.Threading.Thread.Sleep(waiting);
+            }
+            // Generate a random value in our range
+        }
+
+        /// <summary>
+        /// Find torrent rows in search pages
+        /// </summary>
+        /// <returns>JQuery Object</returns>
+        private CQ FindTorrentRows()
+        {
+            // Return all occurencis of torrents found
+            //return _fDom["#content > table > tr"];
+            return _fDom["# torrentTable > tbody > tr:not(:first)"];
+        }
+
+        /// <summary>
+        /// Download torrent file from tracker
+        /// </summary>
+        /// <param name="link">URL string</param>
+        /// <returns></returns>
+        public override async Task<byte[]> Download(Uri link)
+        {
+
+            // Retrieving ID from link provided
+            var id = ParseUtil.CoerceInt(Regex.Match(link.AbsoluteUri, @"\d+").Value);
+            Output("Torrent Requested ID: " + id);
+
+            // Building login form data
+            var pairs = new Dictionary<string, string> {
+                { "torrentid", id.ToString() },
+                { "_", string.Empty } // ~~ Strange, blank param...
+            };
+
+            // Add emulated XHR request
+            _emulatedBrowserHeaders.Add("X-Prototype-Version", "1.6.0.3");
+            _emulatedBrowserHeaders.Add("X-Requested-With", "XMLHttpRequest");
+
+            // Get torrent file now
+            Output("Getting torrent file now....");
+            var response = await base.Download(link);
+
+            // Remove our XHR request header
+            _emulatedBrowserHeaders.Remove("X-Prototype-Version");
+            _emulatedBrowserHeaders.Remove("X-Requested-With");
+
+            // Return content
+            return response;
+        }
+
+        /// <summary>
+        /// Output message for logging or developpment (console)
+        /// </summary>
+        /// <param name="message">Message to output</param>
+        /// <param name="level">Level for Logger</param>
+        private void Output(string message, string level = "debug")
+        {
+            // Check if we are in dev mode
+            if (DevMode)
+            {
+                // Output message to console
+                Console.WriteLine(message);
+            }
+            else
+            {
+                // Send message to logger with level
+                switch (level)
+                {
+                    default:
+                        goto case "debug";
+                    case "debug":
+                        // Only if Debug Level Enabled on Jackett
+                        if (Engine.Logger.IsDebugEnabled)
+                        {
+                            logger.Debug(message);
+                        }
+                        break;
+                    case "info":
+                        logger.Info(message);
+                        break;
+                    case "error":
+                        logger.Error(message);
+                        break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Validate Config entered by user on Jackett
+        /// </summary>
+        private void ValidateConfig()
+        {
+            Output("\nValidating Settings ... \n");
+
+            // Check Username Setting
+            if (string.IsNullOrEmpty(ConfigData.Username.Value))
+            {
+                throw new ExceptionWithConfigData("You must provide a username for this tracker to login !", ConfigData);
+            }
+            else
+            {
+                Output("Validated Setting -- Username (auth) => " + ConfigData.Username.Value);
+            }
+
+            // Check Password Setting
+            if (string.IsNullOrEmpty(ConfigData.Password.Value))
+            {
+                throw new ExceptionWithConfigData("You must provide a password with your username for this tracker to login !", ConfigData);
+            }
+            else
+            {
+                Output("Validated Setting -- Password (auth) => " + ConfigData.Password.Value);
+            }
+
+            // Check Max Page Setting
+            if (!string.IsNullOrEmpty(ConfigData.Pages.Value))
+            {
+                try
+                {
+                    Output("Validated Setting -- Max Pages => " + Convert.ToInt32(ConfigData.Pages.Value));
+                }
+                catch (Exception)
+                {
+                    throw new ExceptionWithConfigData("Please enter a numeric maximum number of pages to crawl !", ConfigData);
+                }
+            }
+            else
+            {
+                throw new ExceptionWithConfigData("Please enter a maximum number of pages to crawl !", ConfigData);
+            }
+
+            // Check Latency Setting
+            if (ConfigData.Latency.Value)
+            {
+                Output("\nValidated Setting -- Latency Simulation enabled");
+
+                // Check Latency Start Setting
+                if (!string.IsNullOrEmpty(ConfigData.LatencyStart.Value))
+                {
+                    try
+                    {
+                        Output("Validated Setting -- Latency Start => " + Convert.ToInt32(ConfigData.LatencyStart.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric latency start in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a start latency !", ConfigData);
+                }
+
+                // Check Latency End Setting
+                if (!string.IsNullOrEmpty(ConfigData.LatencyEnd.Value))
+                {
+                    try
+                    {
+                        Output("Validated Setting -- Latency End => " + Convert.ToInt32(ConfigData.LatencyEnd.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric latency end in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Latency Simulation enabled, Please enter a end latency !", ConfigData);
+                }
+            }
+
+            // Check Browser Setting
+            if (ConfigData.Browser.Value)
+            {
+                Output("\nValidated Setting -- Browser Simulation enabled");
+
+                // Check ACCEPT header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderAccept.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT header !", ConfigData);
+                }
+                else
+                {
+                    Output("Validated Setting -- ACCEPT (header) => " + ConfigData.HeaderAccept.Value);
+                }
+
+                // Check ACCEPT-LANG header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderAcceptLang.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an ACCEPT-LANG header !", ConfigData);
+                }
+                else
+                {
+                    Output("Validated Setting -- ACCEPT-LANG (header) => " + ConfigData.HeaderAcceptLang.Value);
+                }
+
+                // Check USER-AGENT header Setting
+                if (string.IsNullOrEmpty(ConfigData.HeaderUserAgent.Value))
+                {
+                    throw new ExceptionWithConfigData("Browser Simulation enabled, Please enter an USER-AGENT header !", ConfigData);
+                }
+                else
+                {
+                    Output("Validated Setting -- USER-AGENT (header) => " + ConfigData.HeaderUserAgent.Value);
+                }
+            }
+            else
+            {
+                // Browser simulation must be enabled (otherwhise, this provider will not work due to tracker's security)
+                throw new ExceptionWithConfigData("Browser Simulation must be enabled for this provider to work, please enable it !", ConfigData);
+            }
+
+            // Check Dev Cache Settings
+            if (ConfigData.HardDriveCache.Value)
+            {
+                Output("\nValidated Setting -- DEV Hard Drive Cache enabled");
+
+                // Check if Dev Mode enabled !
+                if (!ConfigData.DevMode.Value)
+                {
+                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
+                }
+
+                // Check Cache Keep Time Setting
+                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
+                {
+                    try
+                    {
+                        Output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
+                }
+            }
+            else
+            {
+                // Delete cache if previously existed
+                CleanCacheStorage(true);
+            }
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/PassThePopcorn.cs b/src/Jackett/Indexers/PassThePopcorn.cs
index b654ac21a6e4e45d7db326e8ed8d99e4d913be9a..6840ac944f9d4081cb6afb41a5e922aa7647757a 100644
--- a/src/Jackett/Indexers/PassThePopcorn.cs
+++ b/src/Jackett/Indexers/PassThePopcorn.cs
@@ -46,10 +46,10 @@ namespace Jackett.Indexers
             Language = "en-us";
             Type = "private";
 
-            TorznabCaps.SupportsImdbSearch = true;
-
-            webclient.requestDelay = 2; // 0.5 requests per second
-
+            TorznabCaps.SupportsImdbSearch = true;
+
+            webclient.requestDelay = 2; // 0.5 requests per second
+
             AddCategoryMapping(1, TorznabCatType.Movies, "Feature Film");
             AddCategoryMapping(1, TorznabCatType.MoviesForeign);
             AddCategoryMapping(1, TorznabCatType.MoviesOther);
@@ -113,8 +113,8 @@ namespace Jackett.Indexers
                 movieListSearchUrl = string.Format("{0}?json=noredirect&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
             }
             else
-            {
-                movieListSearchUrl = string.Format("{0}?json=noredirect", SearchUrl);
+            {
+                movieListSearchUrl = string.Format("{0}?json=noredirect", SearchUrl);
             }
 
             var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);
@@ -181,50 +181,50 @@ namespace Jackett.Indexers
                         string Container = (string)torrent["Container"];
                         string Codec = (string)torrent["Codec"];
                         string Resolution = (string)torrent["Resolution"];
-                        string Source = (string)torrent["Source"];
-
-                        if (Year != null)
-                        {
-                            release.Description += string.Format("<br>\nYear: {0}", Year);
-                        }
-                        if (Quality != null)
-                        {
-                            release.Description += string.Format("<br>\nQuality: {0}", Quality);
-                        }
-                        if (Resolution != null)
-                        {
-                            titletags.Add(Resolution);
-                            release.Description += string.Format("<br>\nResolution: {0}", Resolution);
+                        string Source = (string)torrent["Source"];
+
+                        if (Year != null)
+                        {
+                            release.Description += string.Format("<br>\nYear: {0}", Year);
                         }
-                        if (Source != null)
-                        {
-                            titletags.Add(Source);
-                            release.Description += string.Format("<br>\nSource: {0}", Source);
+                        if (Quality != null)
+                        {
+                            release.Description += string.Format("<br>\nQuality: {0}", Quality);
                         }
-                        if (Codec != null)
-                        {
-                            titletags.Add(Codec);
-                            release.Description += string.Format("<br>\nCodec: {0}", Codec);
+                        if (Resolution != null)
+                        {
+                            titletags.Add(Resolution);
+                            release.Description += string.Format("<br>\nResolution: {0}", Resolution);
                         }
-                        if (Container != null)
-                        {
-                            titletags.Add(Container);
-                            release.Description += string.Format("<br>\nContainer: {0}", Container);
+                        if (Source != null)
+                        {
+                            titletags.Add(Source);
+                            release.Description += string.Format("<br>\nSource: {0}", Source);
                         }
-                        if (scene)
-                        {
-                            titletags.Add("Scene");
-                            release.Description += "<br>\nScene";
+                        if (Codec != null)
+                        {
+                            titletags.Add(Codec);
+                            release.Description += string.Format("<br>\nCodec: {0}", Codec);
+                        }
+                        if (Container != null)
+                        {
+                            titletags.Add(Container);
+                            release.Description += string.Format("<br>\nContainer: {0}", Container);
                         }
-                        if (check)
-                        {
-                            titletags.Add("Checked");
-                            release.Description += "<br>\nChecked";
+                        if (scene)
+                        {
+                            titletags.Add("Scene");
+                            release.Description += "<br>\nScene";
                         }
-                        if (golden)
-                        {
-                            titletags.Add("Golden Popcorn");
-                            release.Description += "<br>\nGolden Popcorn";
+                        if (check)
+                        {
+                            titletags.Add("Checked");
+                            release.Description += "<br>\nChecked";
+                        }
+                        if (golden)
+                        {
+                            titletags.Add("Golden Popcorn");
+                            release.Description += "<br>\nGolden Popcorn";
                         }
 
                         if (titletags.Count() > 0)
diff --git a/src/Jackett/Indexers/PiXELHD.cs b/src/Jackett/Indexers/PiXELHD.cs
index 614033a74b6c22189ee041f697fc268502ffae5e..f8e88d2c5acb1603e57c1342ba48f8aa93f0ad51 100644
--- a/src/Jackett/Indexers/PiXELHD.cs
+++ b/src/Jackett/Indexers/PiXELHD.cs
@@ -1,37 +1,37 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-using AngleSharp.Parser.Html;
-using Newtonsoft.Json.Linq;
-using NLog;
-
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using System.Collections.Specialized;
-
-namespace Jackett.Indexers
-{
-    class PiXELHD : BaseIndexer, IIndexer
-    {
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+using AngleSharp.Parser.Html;
+using Newtonsoft.Json.Linq;
+using NLog;
+
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using System.Collections.Specialized;
+
+namespace Jackett.Indexers
+{
+    class PiXELHD : BaseIndexer, IIndexer
+    {
         string LoginUrl { get { return SiteLink + "login.php"; } }
-        string BrowseUrl { get { return SiteLink + "torrents.php"; } }
-
+        string BrowseUrl { get { return SiteLink + "torrents.php"; } }
+
         new ConfigurationDataCaptchaLogin configData
         {
             get { return (ConfigurationDataCaptchaLogin)base.configData; }
             set { base.configData = value; }
-        }
-
-        string input_captcha = null;
-        string input_username = null;
-        string input_password = null;
-
+        }
+
+        string input_captcha = null;
+        string input_username = null;
+        string input_password = null;
+
         public PiXELHD(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService)
             : base(name: "PiXELHD",
                 description: null,
@@ -43,51 +43,51 @@ namespace Jackett.Indexers
                 client: webClient,
                 configData: new ConfigurationDataCaptchaLogin()
                 )
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(1, TorznabCatType.MoviesHD);
-
-        }
-
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
-            var LoginParser = new HtmlParser();
-            var LoginDocument = LoginParser.Parse(loginPage.Content);
-
-            configData.CaptchaCookie.Value = loginPage.Cookies;
-
-            var catchaImg = LoginDocument.QuerySelector("img[alt=\"FuckOff Image\"]");
-            if (catchaImg != null)
-            {
-                var catchaInput = LoginDocument.QuerySelector("input[maxlength=\"6\"]");
-                input_captcha = catchaInput.GetAttribute("name");
-
-                var captchaImage = await RequestBytesWithCookies(SiteLink + catchaImg.GetAttribute("src"), loginPage.Cookies, RequestType.GET, LoginUrl);
-                configData.CaptchaImage.Value = captchaImage.Content;
-            }
-            else
-            {
-                input_captcha = null;
-                configData.CaptchaImage.Value = null;
-            }
-
-            var usernameInput = LoginDocument.QuerySelector("input[maxlength=\"20\"]");
-            input_username = usernameInput.GetAttribute("name");
-
-            var passwordInput = LoginDocument.QuerySelector("input[maxlength=\"40\"]");
-            input_password = passwordInput.GetAttribute("name");
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(1, TorznabCatType.MoviesHD);
+
+        }
+
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
+            var LoginParser = new HtmlParser();
+            var LoginDocument = LoginParser.Parse(loginPage.Content);
+
+            configData.CaptchaCookie.Value = loginPage.Cookies;
+
+            var catchaImg = LoginDocument.QuerySelector("img[alt=\"FuckOff Image\"]");
+            if (catchaImg != null)
+            {
+                var catchaInput = LoginDocument.QuerySelector("input[maxlength=\"6\"]");
+                input_captcha = catchaInput.GetAttribute("name");
+
+                var captchaImage = await RequestBytesWithCookies(SiteLink + catchaImg.GetAttribute("src"), loginPage.Cookies, RequestType.GET, LoginUrl);
+                configData.CaptchaImage.Value = captchaImage.Content;
+            }
+            else
+            {
+                input_captcha = null;
+                configData.CaptchaImage.Value = null;
+            }
+
+            var usernameInput = LoginDocument.QuerySelector("input[maxlength=\"20\"]");
+            input_username = usernameInput.GetAttribute("name");
+
+            var passwordInput = LoginDocument.QuerySelector("input[maxlength=\"40\"]");
+            input_password = passwordInput.GetAttribute("name");
             
-            return configData;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
+            return configData;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
             configData.LoadValuesFromJson(configJson);
 
             var pairs = new Dictionary<string, string>
@@ -95,32 +95,32 @@ namespace Jackett.Indexers
                 { input_username, configData.Username.Value },
                 { input_password, configData.Password.Value },
                 { "keeplogged", "1" }
-            };
-
-            if (input_captcha != null)
-                pairs.Add(input_captcha, configData.CaptchaText.Value);
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CaptchaCookie.Value, true);
-
-            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
-           {
-               var LoginParser = new HtmlParser();
-               var LoginDocument = LoginParser.Parse(result.Content);
-               var errorMessage = LoginDocument.QuerySelector("span.warning:has(br)").TextContent;
-               throw new ExceptionWithConfigData(errorMessage, configData);
-           });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("order_by", "time");
-            queryCollection.Add("order_way", "desc");
-
+            };
+
+            if (input_captcha != null)
+                pairs.Add(input_captcha, configData.CaptchaText.Value);
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CaptchaCookie.Value, true);
+
+            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
+           {
+               var LoginParser = new HtmlParser();
+               var LoginDocument = LoginParser.Parse(result.Content);
+               var errorMessage = LoginDocument.QuerySelector("span.warning:has(br)").TextContent;
+               throw new ExceptionWithConfigData(errorMessage, configData);
+           });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("order_by", "time");
+            queryCollection.Add("order_way", "desc");
+
             if (!string.IsNullOrWhiteSpace(query.ImdbID))
             {
                 queryCollection.Add("imdbid", query.ImdbID);
@@ -128,82 +128,82 @@ namespace Jackett.Indexers
             else if (!string.IsNullOrWhiteSpace(searchString))
             {
                 queryCollection.Add("groupname", searchString);
-            }
-
-            queryCollection.Add("groupname", searchString);
-
-            var searchUrl = BrowseUrl + "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookies(searchUrl);
-            if (results.IsRedirect)
-            {
-                // re login
-                await GetConfigurationForSetup();
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookies(searchUrl);
-            }
-
-            Regex IMDBRegEx = new Regex(@"tt(\d+)", RegexOptions.Compiled);
-            var hParser = new HtmlParser();
-            var ResultDocument = hParser.Parse(results.Content);
+            }
+
+            queryCollection.Add("groupname", searchString);
+
+            var searchUrl = BrowseUrl + "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookies(searchUrl);
+            if (results.IsRedirect)
+            {
+                // re login
+                await GetConfigurationForSetup();
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookies(searchUrl);
+            }
+
+            Regex IMDBRegEx = new Regex(@"tt(\d+)", RegexOptions.Compiled);
+            var hParser = new HtmlParser();
+            var ResultDocument = hParser.Parse(results.Content);
             try
             {
                 var Groups = ResultDocument.QuerySelectorAll("div.browsePoster");
-
-                foreach (var Group in Groups)
-                {
-                    var groupPoster = Group.QuerySelector("img.classBrowsePoster");
-                    var bannerURL = new Uri(SiteLink + groupPoster.GetAttribute("src"));
-
-                    long? IMDBId = null;
-                    var imdbLink = Group.QuerySelector("a[href^=\"http://anonym.to/?http://www.imdb.com/title/tt\"]");
-                    if (imdbLink != null)
-                    {
-                        var IMDBMatch = IMDBRegEx.Match(imdbLink.GetAttribute("href"));
-                        IMDBId = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value);
-                    }
-
-                    var GroupTitle = Group.QuerySelector("strong:has(a[title=\"View Torrent\"])").TextContent.Replace(" ]", "]");
-
-                    var Rows = Group.QuerySelectorAll("tr.group_torrent:has(a[href^=\"torrents.php?id=\"])");
-                    foreach (var Row in Rows)
-                    {
-                        var release = new ReleaseInfo();
-                        release.MinimumRatio = 1;
-                        release.MinimumSeedTime = 72 * 60 * 60;
-
-                        var title = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
-                        var link = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
-                        var added = Row.QuerySelector("td:nth-child(3)");
-                        var Size = Row.QuerySelector("td:nth-child(4)");
-                        var Grabs = Row.QuerySelector("td:nth-child(6)");
-                        var Seeders = Row.QuerySelector("td:nth-child(7)");
-                        var Leechers = Row.QuerySelector("td:nth-child(8)");
-
-                        release.Title = GroupTitle + " " + title.TextContent;
-                        release.Category = new List<int> { TorznabCatType.MoviesHD.ID };
-                        release.Link = new Uri(SiteLink + link.GetAttribute("href"));
-                        release.Comments = new Uri(SiteLink + title.GetAttribute("href"));
-                        release.Guid = release.Link;
-                        release.Size = ReleaseInfo.GetBytes(Size.TextContent);
-                        release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
-                        release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
-                        release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
-                        release.PublishDate = DateTimeUtil.FromTimeAgo(added.TextContent);
-                        release.BannerUrl = bannerURL;
-                        release.Imdb = IMDBId;
-
-                        releases.Add(release);
+
+                foreach (var Group in Groups)
+                {
+                    var groupPoster = Group.QuerySelector("img.classBrowsePoster");
+                    var bannerURL = new Uri(SiteLink + groupPoster.GetAttribute("src"));
+
+                    long? IMDBId = null;
+                    var imdbLink = Group.QuerySelector("a[href^=\"http://anonym.to/?http://www.imdb.com/title/tt\"]");
+                    if (imdbLink != null)
+                    {
+                        var IMDBMatch = IMDBRegEx.Match(imdbLink.GetAttribute("href"));
+                        IMDBId = ParseUtil.CoerceLong(IMDBMatch.Groups[1].Value);
                     }
-                }
+
+                    var GroupTitle = Group.QuerySelector("strong:has(a[title=\"View Torrent\"])").TextContent.Replace(" ]", "]");
+
+                    var Rows = Group.QuerySelectorAll("tr.group_torrent:has(a[href^=\"torrents.php?id=\"])");
+                    foreach (var Row in Rows)
+                    {
+                        var release = new ReleaseInfo();
+                        release.MinimumRatio = 1;
+                        release.MinimumSeedTime = 72 * 60 * 60;
+
+                        var title = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
+                        var link = Row.QuerySelector("a[href^=\"torrents.php?action=download\"]");
+                        var added = Row.QuerySelector("td:nth-child(3)");
+                        var Size = Row.QuerySelector("td:nth-child(4)");
+                        var Grabs = Row.QuerySelector("td:nth-child(6)");
+                        var Seeders = Row.QuerySelector("td:nth-child(7)");
+                        var Leechers = Row.QuerySelector("td:nth-child(8)");
+
+                        release.Title = GroupTitle + " " + title.TextContent;
+                        release.Category = new List<int> { TorznabCatType.MoviesHD.ID };
+                        release.Link = new Uri(SiteLink + link.GetAttribute("href"));
+                        release.Comments = new Uri(SiteLink + title.GetAttribute("href"));
+                        release.Guid = release.Link;
+                        release.Size = ReleaseInfo.GetBytes(Size.TextContent);
+                        release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
+                        release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
+                        release.Grabs = ParseUtil.CoerceLong(Grabs.TextContent);
+                        release.PublishDate = DateTimeUtil.FromTimeAgo(added.TextContent);
+                        release.BannerUrl = bannerURL;
+                        release.Imdb = IMDBId;
+
+                        releases.Add(release);
+                    }
+                }
             }
             catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
+            {
+                OnParseError(results.Content, ex);
             }
 
-            return releases;
-        }
-
-    }
-}
+            return releases;
+        }
+
+    }
+}
diff --git a/src/Jackett/Indexers/PirateTheNet.cs b/src/Jackett/Indexers/PirateTheNet.cs
index 121b99e2289ab9741e396b8cefb434eeb6e21757..b3866c0db5dcef6dff087344b282144b53c2797f 100644
--- a/src/Jackett/Indexers/PirateTheNet.cs
+++ b/src/Jackett/Indexers/PirateTheNet.cs
@@ -1,226 +1,226 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Globalization;
-
-namespace Jackett.Indexers
-{
-    public class PirateTheNet : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "torrentsutils.php"; } }
-        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
-        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
-        TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "W. Europe Standard Time", "W. Europe Standard Time");
-        private readonly List<String> categories = new List<string>() { "1080P", "720P", "BDRip", "BluRay", "BRRip", "DVDR", "DVDRip", "FLAC", "MP3", "MP4", "Packs", "R5", "Remux", "TVRip", "WebRip" };
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public PirateTheNet(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "PirateTheNet",
-                description: "A movie tracker",
-                link: "http://piratethenet.org/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
-            this.configData.DisplayText.Name = "Notice";
-
-            AddCategoryMapping("1080P", TorznabCatType.MoviesHD);
-            AddCategoryMapping("720P", TorznabCatType.MoviesHD);
-            AddCategoryMapping("BDRip", TorznabCatType.MoviesSD);
-            AddCategoryMapping("BluRay", TorznabCatType.MoviesBluRay);
-            AddCategoryMapping("BRRip", TorznabCatType.MoviesSD);
-            AddCategoryMapping("DVDR", TorznabCatType.MoviesDVD);
-            AddCategoryMapping("DVDRip", TorznabCatType.MoviesSD);
-            AddCategoryMapping("FLAC", TorznabCatType.AudioLossless);
-            AddCategoryMapping("MP3", TorznabCatType.AudioMP3);
-            AddCategoryMapping("MP4", TorznabCatType.AudioOther);
-            AddCategoryMapping("Packs", TorznabCatType.Movies);
-            AddCategoryMapping("R5", TorznabCatType.MoviesDVD);
-            AddCategoryMapping("Remux", TorznabCatType.Movies);
-            AddCategoryMapping("TVRip", TorznabCatType.MoviesOther);
-            AddCategoryMapping("WebRip", TorznabCatType.MoviesWEBDL);
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var result1 = await RequestStringWithCookies(CaptchaUrl);
-            var json1 = JObject.Parse(result1.Content);
-            var captchaSelection = json1["images"][0]["hash"];
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "captchaSelection", (string)captchaSelection }
-            };
-
-            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
-
-            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = "Login Failed";
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("action", "torrentstable");
-            queryCollection.Add("viewtype", "0");
-            queryCollection.Add("visiblecategories", "Action,Adventure,Animation,Biography,Comedy,Crime,Documentary,Drama,Eastern,Family,Fantasy,History,Holiday,Horror,Kids,Musical,Mystery,Romance,Sci-Fi,Short,Sports,Thriller,War,Western");
-            queryCollection.Add("page", "1");
-            queryCollection.Add("visibility", "showall");
-            queryCollection.Add("compression", "showall");
-            queryCollection.Add("sort", "added");
-            queryCollection.Add("order", "DESC");
-            queryCollection.Add("titleonly", "true");
-            queryCollection.Add("packs", "showall");
-            queryCollection.Add("bookmarks", "showall");
-            queryCollection.Add("subscriptions", "showall");
-            queryCollection.Add("skw", "showall");
-            queryCollection.Add("advancedsearchparameters", "");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                // search keywords use OR by default and it seems like there's no way to change it, expect unwanted results
-                queryCollection.Add("searchstring", searchString);
-            }
-
-            var cats = MapTorznabCapsToTrackers(query);
-            var hiddenqualities = "";
-            if (cats.Count > 0)
-            {
-                hiddenqualities = String.Join(",", categories.Where(cat => !cats.Contains(cat)));
-            }
-            queryCollection.Add("hiddenqualities", hiddenqualities);
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-            try
-            {
-                CQ dom = results.Content;
-                /*
-                // parse logic for viewtype=1, unfortunately it's missing the release time so we can't use it
-                var movieBlocks = dom["table.main"];
-                foreach (var movieBlock in movieBlocks)
-                {
-                    var qMovieBlock = movieBlock.Cq();
-
-                    var movieLink = qMovieBlock.Find("tr > td[class=colhead] > a").First();
-                    var movieName = movieLink.Text();
-
-                    var qDetailsBlock = qMovieBlock.Find("tr > td.torrentstd > table > tbody > tr");
-                    var qDetailsHeader = qDetailsBlock.ElementAt(0);
-                    var qDetailsTags = qDetailsBlock.ElementAt(1);
-                    var qTorrents = qDetailsBlock.Find("td.moviestorrentstd > table > tbody > tr:eq(0)");
-
-                    foreach (var torrent in qTorrents)
-                    {
-                        var qTorrent = torrent.Cq();
-                        var qCatIcon = qTorrent.Find("td:eq(0) > img");
-                        var qDetailsLink = qTorrent.Find("td:eq(1) > a:eq(0)");
-                        var qSeeders = qTorrent.Find("td:eq(1) > b > a[alt=\"Number of Seeders\"]");
-                        var qLeechers = qTorrent.Find("td:eq(1) > span[alt=\"Number of Leechers\"]");
-                        var qDownloadLink = qTorrent.Find("td:eq(1) > a:has(img[alt=\"Download Torrent\"])");
-                    }
-                }
-                */
-
-                var rows = dom["table.main > tbody > tr"];
-                foreach (var row in rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 72 * 60 * 60;
-
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("td:eq(1) > a:eq(0)"); // link to the movie, not the actual torrent
-                    release.Title = qDetailsLink.Attr("alt");
-
-                    var qCatIcon = qRow.Find("td:eq(0) > img");
-                    var qSeeders = qRow.Find("td:eq(8)");
-                    var qLeechers = qRow.Find("td:eq(9)");
-                    var qDownloadLink = qRow.Find("td > a:has(img[alt=\"Download Torrent\"])");
-                    var qPudDate = qRow.Find("td:eq(5) > nobr");
-                    var qSize = qRow.Find("td:eq(6)");
-
-                    var catStr = qCatIcon.Attr("alt");
-                    release.Category = MapTrackerCatToNewznab(catStr);
-                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href").Substring(1));
-                    release.Title = qDetailsLink.Attr("alt");
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var dateStr = qPudDate.Text().Trim();
-                    DateTime pubDateUtc;
-                    var Timeparts = dateStr.Split(new char[] { ' ' }, 2)[1];
-                    if (dateStr.StartsWith("Today "))
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay;
-                    else if (dateStr.StartsWith("Yesterday "))
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) +
-                            DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay - TimeSpan.FromDays(1);
-                    else
-                        pubDateUtc = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy hh:mm tt", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    release.PublishDate = pubDateUtc.ToLocalTime();
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
-                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
-
-                    var files = qRow.Find("td:nth-child(4)").Text();
-                    release.Files = ParseUtil.CoerceInt(files);
-
-                    var grabs = qRow.Find("td:nth-child(8)").Text();
-                    release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                    release.DownloadVolumeFactor = 0; // ratioless
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using System.Globalization;
+
+namespace Jackett.Indexers
+{
+    public class PirateTheNet : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "torrentsutils.php"; } }
+        private string LoginUrl { get { return SiteLink + "takelogin.php"; } }
+        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
+        TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "W. Europe Standard Time", "W. Europe Standard Time");
+        private readonly List<String> categories = new List<string>() { "1080P", "720P", "BDRip", "BluRay", "BRRip", "DVDR", "DVDRip", "FLAC", "MP3", "MP4", "Packs", "R5", "Remux", "TVRip", "WebRip" };
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public PirateTheNet(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "PirateTheNet",
+                description: "A movie tracker",
+                link: "http://piratethenet.org/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
+            this.configData.DisplayText.Name = "Notice";
+
+            AddCategoryMapping("1080P", TorznabCatType.MoviesHD);
+            AddCategoryMapping("720P", TorznabCatType.MoviesHD);
+            AddCategoryMapping("BDRip", TorznabCatType.MoviesSD);
+            AddCategoryMapping("BluRay", TorznabCatType.MoviesBluRay);
+            AddCategoryMapping("BRRip", TorznabCatType.MoviesSD);
+            AddCategoryMapping("DVDR", TorznabCatType.MoviesDVD);
+            AddCategoryMapping("DVDRip", TorznabCatType.MoviesSD);
+            AddCategoryMapping("FLAC", TorznabCatType.AudioLossless);
+            AddCategoryMapping("MP3", TorznabCatType.AudioMP3);
+            AddCategoryMapping("MP4", TorznabCatType.AudioOther);
+            AddCategoryMapping("Packs", TorznabCatType.Movies);
+            AddCategoryMapping("R5", TorznabCatType.MoviesDVD);
+            AddCategoryMapping("Remux", TorznabCatType.Movies);
+            AddCategoryMapping("TVRip", TorznabCatType.MoviesOther);
+            AddCategoryMapping("WebRip", TorznabCatType.MoviesWEBDL);
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var result1 = await RequestStringWithCookies(CaptchaUrl);
+            var json1 = JObject.Parse(result1.Content);
+            var captchaSelection = json1["images"][0]["hash"];
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "captchaSelection", (string)captchaSelection }
+            };
+
+            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
+
+            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = "Login Failed";
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("action", "torrentstable");
+            queryCollection.Add("viewtype", "0");
+            queryCollection.Add("visiblecategories", "Action,Adventure,Animation,Biography,Comedy,Crime,Documentary,Drama,Eastern,Family,Fantasy,History,Holiday,Horror,Kids,Musical,Mystery,Romance,Sci-Fi,Short,Sports,Thriller,War,Western");
+            queryCollection.Add("page", "1");
+            queryCollection.Add("visibility", "showall");
+            queryCollection.Add("compression", "showall");
+            queryCollection.Add("sort", "added");
+            queryCollection.Add("order", "DESC");
+            queryCollection.Add("titleonly", "true");
+            queryCollection.Add("packs", "showall");
+            queryCollection.Add("bookmarks", "showall");
+            queryCollection.Add("subscriptions", "showall");
+            queryCollection.Add("skw", "showall");
+            queryCollection.Add("advancedsearchparameters", "");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                // search keywords use OR by default and it seems like there's no way to change it, expect unwanted results
+                queryCollection.Add("searchstring", searchString);
+            }
+
+            var cats = MapTorznabCapsToTrackers(query);
+            var hiddenqualities = "";
+            if (cats.Count > 0)
+            {
+                hiddenqualities = String.Join(",", categories.Where(cat => !cats.Contains(cat)));
+            }
+            queryCollection.Add("hiddenqualities", hiddenqualities);
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+            try
+            {
+                CQ dom = results.Content;
+                /*
+                // parse logic for viewtype=1, unfortunately it's missing the release time so we can't use it
+                var movieBlocks = dom["table.main"];
+                foreach (var movieBlock in movieBlocks)
+                {
+                    var qMovieBlock = movieBlock.Cq();
+
+                    var movieLink = qMovieBlock.Find("tr > td[class=colhead] > a").First();
+                    var movieName = movieLink.Text();
+
+                    var qDetailsBlock = qMovieBlock.Find("tr > td.torrentstd > table > tbody > tr");
+                    var qDetailsHeader = qDetailsBlock.ElementAt(0);
+                    var qDetailsTags = qDetailsBlock.ElementAt(1);
+                    var qTorrents = qDetailsBlock.Find("td.moviestorrentstd > table > tbody > tr:eq(0)");
+
+                    foreach (var torrent in qTorrents)
+                    {
+                        var qTorrent = torrent.Cq();
+                        var qCatIcon = qTorrent.Find("td:eq(0) > img");
+                        var qDetailsLink = qTorrent.Find("td:eq(1) > a:eq(0)");
+                        var qSeeders = qTorrent.Find("td:eq(1) > b > a[alt=\"Number of Seeders\"]");
+                        var qLeechers = qTorrent.Find("td:eq(1) > span[alt=\"Number of Leechers\"]");
+                        var qDownloadLink = qTorrent.Find("td:eq(1) > a:has(img[alt=\"Download Torrent\"])");
+                    }
+                }
+                */
+
+                var rows = dom["table.main > tbody > tr"];
+                foreach (var row in rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 72 * 60 * 60;
+
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("td:eq(1) > a:eq(0)"); // link to the movie, not the actual torrent
+                    release.Title = qDetailsLink.Attr("alt");
+
+                    var qCatIcon = qRow.Find("td:eq(0) > img");
+                    var qSeeders = qRow.Find("td:eq(8)");
+                    var qLeechers = qRow.Find("td:eq(9)");
+                    var qDownloadLink = qRow.Find("td > a:has(img[alt=\"Download Torrent\"])");
+                    var qPudDate = qRow.Find("td:eq(5) > nobr");
+                    var qSize = qRow.Find("td:eq(6)");
+
+                    var catStr = qCatIcon.Attr("alt");
+                    release.Category = MapTrackerCatToNewznab(catStr);
+                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href").Substring(1));
+                    release.Title = qDetailsLink.Attr("alt");
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var dateStr = qPudDate.Text().Trim();
+                    DateTime pubDateUtc;
+                    var Timeparts = dateStr.Split(new char[] { ' ' }, 2)[1];
+                    if (dateStr.StartsWith("Today "))
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay;
+                    else if (dateStr.StartsWith("Yesterday "))
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) +
+                            DateTime.ParseExact(dateStr.Split(new char[] { ' ' }, 2)[1], "hh:mm tt", System.Globalization.CultureInfo.InvariantCulture).TimeOfDay - TimeSpan.FromDays(1);
+                    else
+                        pubDateUtc = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy hh:mm tt", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    release.PublishDate = pubDateUtc.ToLocalTime();
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
+
+                    var files = qRow.Find("td:nth-child(4)").Text();
+                    release.Files = ParseUtil.CoerceInt(files);
+
+                    var grabs = qRow.Find("td:nth-child(8)").Text();
+                    release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                    release.DownloadVolumeFactor = 0; // ratioless
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Pretome.cs b/src/Jackett/Indexers/Pretome.cs
index d1bdac6db53114a14c29fc814e172154d1d592ae..a0986572eeddea856e936c72aa865da9b5aec867 100644
--- a/src/Jackett/Indexers/Pretome.cs
+++ b/src/Jackett/Indexers/Pretome.cs
@@ -255,12 +255,12 @@ namespace Jackett.Indexers
                 queryCollection.Add("tags", tags);
                 if(!string.IsNullOrWhiteSpace(tags)) {
                     // if tags are specified match any
-                    queryCollection.Add("tf", "any");
+                    queryCollection.Add("tf", "any");
                 }
-                else
+                else
                 { 
                     // if no tags are specified match all, with any we get random results
-                    queryCollection.Add("tf", "all");
+                    queryCollection.Add("tf", "all");
                 }
             }
 
@@ -271,10 +271,10 @@ namespace Jackett.Indexers
 
             var response = await RequestStringWithCookiesAndRetry(queryUrl);
 
-            if (response.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(queryUrl);
+            if (response.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(queryUrl);
             }
 
             try
@@ -320,7 +320,7 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(9)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    release.DownloadVolumeFactor = 0; // ratioless
+                    release.DownloadVolumeFactor = 0; // ratioless
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/PrivateHD.cs b/src/Jackett/Indexers/PrivateHD.cs
index affb316e09838775e757acf8f0c3334fb5d38939..89d182b857940fbe11668e438a149578a1229349 100644
--- a/src/Jackett/Indexers/PrivateHD.cs
+++ b/src/Jackett/Indexers/PrivateHD.cs
@@ -1,34 +1,34 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models;
-using Newtonsoft.Json.Linq;
-using NLog;
-using Jackett.Utils;
-using CsQuery;
-using System.Web;
-using Jackett.Services;
-using Jackett.Utils.Clients;
-using Jackett.Models.IndexerConfig;
-using System.Globalization;
-
-namespace Jackett.Indexers
-{
-    public class PrivateHD : AvistazTracker, IIndexer
-    {
-        public PrivateHD(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService)
-            : base(name: "PrivateHD",
-                desc: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
-                link: "https://privatehd.to/",
-                indexerManager: indexerManager,
-                logger: logger,
-                protectionService: protectionService,
-                webClient: webClient
-                )
-        {
-            Type = "private";
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models;
+using Newtonsoft.Json.Linq;
+using NLog;
+using Jackett.Utils;
+using CsQuery;
+using System.Web;
+using Jackett.Services;
+using Jackett.Utils.Clients;
+using Jackett.Models.IndexerConfig;
+using System.Globalization;
+
+namespace Jackett.Indexers
+{
+    public class PrivateHD : AvistazTracker, IIndexer
+    {
+        public PrivateHD(IIndexerManagerService indexerManager, IWebClient webClient, Logger logger, IProtectionService protectionService)
+            : base(name: "PrivateHD",
+                desc: "BitTorrent site for High Quality, High Definition (HD) movies and TV Shows",
+                link: "https://privatehd.to/",
+                indexerManager: indexerManager,
+                logger: logger,
+                protectionService: protectionService,
+                webClient: webClient
+                )
+        {
+            Type = "private";
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Psytorrents.cs b/src/Jackett/Indexers/Psytorrents.cs
index e23515138855c291f040f67e117aa736efa07521..f15a11ecbcc010fb601c51de6877eb2d9c241b97 100644
--- a/src/Jackett/Indexers/Psytorrents.cs
+++ b/src/Jackett/Indexers/Psytorrents.cs
@@ -2,8 +2,8 @@
 using NLog;
 using Jackett.Services;
 using Jackett.Utils.Clients;
-using Jackett.Indexers.Abstract;
-
+using Jackett.Indexers.Abstract;
+
 namespace Jackett.Indexers
 {
     public class Psytorrents : GazelleTracker, IIndexer
@@ -22,8 +22,8 @@ namespace Jackett.Indexers
             Type = "private";
 
             AddCategoryMapping(1, TorznabCatType.Audio, "Music");
-            AddCategoryMapping(2, TorznabCatType.Movies, "Movies");
-            AddCategoryMapping(3, TorznabCatType.PC0day, "App");
+            AddCategoryMapping(2, TorznabCatType.Movies, "Movies");
+            AddCategoryMapping(3, TorznabCatType.PC0day, "App");
         }
     }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/Rarbg.cs b/src/Jackett/Indexers/Rarbg.cs
index b7d7d9e67e93f665f45dd1d8e1ede2bf518ab2f2..6dcb7f16aad7b9af5184437f77bc843bd4c861c5 100644
--- a/src/Jackett/Indexers/Rarbg.cs
+++ b/src/Jackett/Indexers/Rarbg.cs
@@ -1,238 +1,238 @@
-using Jackett.Models;
-using Jackett.Models.IndexerConfig;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Text;
-using System.Web;
-
-namespace Jackett.Indexers
-{
-    public class Rarbg : BaseIndexer, IIndexer
-    {
-        readonly static string defaultSiteLink = "https://torrentapi.org/";
-
-        private Uri BaseUri
-        {
-            get { return new Uri(configData.Url.Value); }
-            set { configData.Url.Value = value.ToString(); }
-        }
-
-        private string ApiEndpoint { get { return BaseUri + "pubapi_v2.php"; } }
-
-        new ConfigurationDataUrl configData
-        {
-            get { return (ConfigurationDataUrl)base.configData; }
-            set { base.configData = value; }
-        }
-
-        private DateTime lastTokenFetch;
-        private string token;
-
-        readonly TimeSpan TOKEN_DURATION = TimeSpan.FromMinutes(10);
-
-        private bool HasValidToken { get { return !string.IsNullOrEmpty(token) && lastTokenFetch > DateTime.Now - TOKEN_DURATION; } }
-
-        public Rarbg(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "RARBG",
-                description: null,
-                link: "https://rarbg.to/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataUrl(defaultSiteLink))
-        {
-            Encoding = Encoding.GetEncoding("windows-1252");
+using Jackett.Models;
+using Jackett.Models.IndexerConfig;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Text;
+using System.Web;
+
+namespace Jackett.Indexers
+{
+    public class Rarbg : BaseIndexer, IIndexer
+    {
+        readonly static string defaultSiteLink = "https://torrentapi.org/";
+
+        private Uri BaseUri
+        {
+            get { return new Uri(configData.Url.Value); }
+            set { configData.Url.Value = value.ToString(); }
+        }
+
+        private string ApiEndpoint { get { return BaseUri + "pubapi_v2.php"; } }
+
+        new ConfigurationDataUrl configData
+        {
+            get { return (ConfigurationDataUrl)base.configData; }
+            set { base.configData = value; }
+        }
+
+        private DateTime lastTokenFetch;
+        private string token;
+
+        readonly TimeSpan TOKEN_DURATION = TimeSpan.FromMinutes(10);
+
+        private bool HasValidToken { get { return !string.IsNullOrEmpty(token) && lastTokenFetch > DateTime.Now - TOKEN_DURATION; } }
+
+        public Rarbg(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "RARBG",
+                description: null,
+                link: "https://rarbg.to/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataUrl(defaultSiteLink))
+        {
+            Encoding = Encoding.GetEncoding("windows-1252");
             Language = "en-us";
-            Type = "public";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            webclient.requestDelay = 2; // 0.5 requests per second
-
-            AddCategoryMapping(4, TorznabCatType.XXX, "XXX (18+)");
-            AddCategoryMapping(14, TorznabCatType.MoviesSD, "Movies/XVID");
-            AddCategoryMapping(48, TorznabCatType.MoviesHD, "Movies/XVID/720");
-            AddCategoryMapping(17, TorznabCatType.MoviesSD, "Movies/x264");
-            AddCategoryMapping(44, TorznabCatType.MoviesHD, "Movies/x264/1080");
-            AddCategoryMapping(45, TorznabCatType.MoviesHD, "Movies/x264/720");
-            AddCategoryMapping(47, TorznabCatType.Movies3D, "Movies/x264/3D");
-            AddCategoryMapping(42, TorznabCatType.MoviesBluRay, "Movies/Full BD");
-            AddCategoryMapping(46, TorznabCatType.MoviesBluRay, "Movies/BD Remux");
-            AddCategoryMapping(18, TorznabCatType.TVSD, "TV Episodes");
-            AddCategoryMapping(41, TorznabCatType.TVHD, "TV HD Episodes");
-            AddCategoryMapping(23, TorznabCatType.AudioMP3, "Music/MP3");
-            AddCategoryMapping(25, TorznabCatType.AudioLossless, "Music/FLAC");
-            AddCategoryMapping(27, TorznabCatType.PCGames, "Games/PC ISO");
-            AddCategoryMapping(28, TorznabCatType.PCGames, "Games/PC RIP");
-            AddCategoryMapping(40, TorznabCatType.ConsolePS3, "Games/PS3");
-            AddCategoryMapping(32, TorznabCatType.ConsoleXbox360, "Games/XBOX-360");
-            AddCategoryMapping(33, TorznabCatType.PCISO, "Software/PC ISO");
-            AddCategoryMapping(35, TorznabCatType.BooksEbook, "e-Books");
-        }
-
-
-        async Task CheckToken()
-        {
-            if (!HasValidToken)
-            {
-                var queryCollection = new NameValueCollection();
-                queryCollection.Add("get_token", "get_token");
-
-                var tokenUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
-
-                var result = await RequestStringWithCookiesAndRetry(tokenUrl);
-                var json = JObject.Parse(result.Content);
-                token = json.Value<string>("token");
-                lastTokenFetch = DateTime.Now;
-            }
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            configData.LoadValuesFromJson(configJson);
-            var releases = await PerformQuery(new TorznabQuery());
-
-            await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
-            {
-                throw new Exception("Could not find releases from this URL");
-            });
-
-            return IndexerConfigurationStatus.Completed;
-        }
-
-        public Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            return PerformQuery(query, 0);
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts = 0)
-        {
-            await CheckToken();
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("token", token);
-            queryCollection.Add("format", "json_extended");
-            queryCollection.Add("app_id", "jackett_v" + Engine.ConfigService.GetVersion());
-            queryCollection.Add("limit", "100");
-            queryCollection.Add("ranked", "0");
-
-            if (query.ImdbID != null)
-            {
-                queryCollection.Add("mode", "search");
-                queryCollection.Add("search_imdb", query.ImdbID);
-            }
-            else if (query.RageID != null)
-            {
-                queryCollection.Add("mode", "search");
-                queryCollection.Add("search_tvrage", query.RageID.ToString());
-            }
-            /*else if (query.TvdbID != null)
-            {
-                queryCollection.Add("mode", "search");
-                queryCollection.Add("search_tvdb", query.TvdbID);
-            }*/
-            else if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("mode", "search");
-                queryCollection.Add("search_string", searchString);
-            }
-            else
-            {
-                queryCollection.Add("mode", "list");
-            }
-
-            var cats = string.Join(";", MapTorznabCapsToTrackers(query));
-            if (!string.IsNullOrEmpty(cats))
-            {
-                queryCollection.Add("category", cats);
-            }
-
-            var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
-            var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
-
-            try
-            {
-                var jsonContent = JObject.Parse(response.Content);
-
-                int errorCode = jsonContent.Value<int>("error_code");
-                if (errorCode == 20) // no results found
-                {
-                    return releases.ToArray();
-                }
-
-                if (errorCode > 0) // too many requests per second
-                {
-                    // we use the IwebClient rate limiter now, this shouldn't happen 
-                    throw new Exception(jsonContent.Value<string>("error"));
-
-                    /*if (attempts < 3)
-                    {
-                        await Task.Delay(TimeSpan.FromSeconds(2));
-                        return await PerformQuery(query, ++attempts);
-                    }
-                    else
-                    {
-                        throw new Exception(jsonContent.Value<string>("error"));
-                    }*/
-                }
-
-                foreach (var item in jsonContent.Value<JArray>("torrent_results"))
-                {
-                    var release = new ReleaseInfo();
-                    release.Title = item.Value<string>("title");
-                    release.Category = MapTrackerCatDescToNewznab(item.Value<string>("category"));
-
-                    release.MagnetUri = new Uri(item.Value<string>("download"));
-                    release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];
-
-                    release.Comments = new Uri(item.Value<string>("info_page"));
-                    release.Guid = release.Comments;
-
-                    var episode_info = item.Value<JToken>("episode_info");
-
-                    if (episode_info.HasValues)
-                    {
-                        var imdb = episode_info.Value<string>("imdb");
-                        release.Imdb = ParseUtil.GetImdbID(imdb);
-                        release.TVDBId = episode_info.Value<long?>("tvdb");
-                        release.RageID = episode_info.Value<long?>("tvrage");
-                        release.TMDb = episode_info.Value<long?>("themoviedb");
-                    }
-
-                    // ex: 2015-08-16 21:25:08 +0000
-                    var dateStr = item.Value<string>("pubdate").Replace(" +0000", "");
-                    var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
-                    release.PublishDate = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime();
-
-                    release.Seeders = item.Value<int>("seeders");
-                    release.Peers = item.Value<int>("leechers") + release.Seeders;
-                    release.Size = item.Value<long>("size");
-                    release.DownloadVolumeFactor = 0;
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(response.Content, ex);
-            }
-
-            return releases;
-        }
-
-    }
+            Type = "public";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            webclient.requestDelay = 2; // 0.5 requests per second
+
+            AddCategoryMapping(4, TorznabCatType.XXX, "XXX (18+)");
+            AddCategoryMapping(14, TorznabCatType.MoviesSD, "Movies/XVID");
+            AddCategoryMapping(48, TorznabCatType.MoviesHD, "Movies/XVID/720");
+            AddCategoryMapping(17, TorznabCatType.MoviesSD, "Movies/x264");
+            AddCategoryMapping(44, TorznabCatType.MoviesHD, "Movies/x264/1080");
+            AddCategoryMapping(45, TorznabCatType.MoviesHD, "Movies/x264/720");
+            AddCategoryMapping(47, TorznabCatType.Movies3D, "Movies/x264/3D");
+            AddCategoryMapping(42, TorznabCatType.MoviesBluRay, "Movies/Full BD");
+            AddCategoryMapping(46, TorznabCatType.MoviesBluRay, "Movies/BD Remux");
+            AddCategoryMapping(18, TorznabCatType.TVSD, "TV Episodes");
+            AddCategoryMapping(41, TorznabCatType.TVHD, "TV HD Episodes");
+            AddCategoryMapping(23, TorznabCatType.AudioMP3, "Music/MP3");
+            AddCategoryMapping(25, TorznabCatType.AudioLossless, "Music/FLAC");
+            AddCategoryMapping(27, TorznabCatType.PCGames, "Games/PC ISO");
+            AddCategoryMapping(28, TorznabCatType.PCGames, "Games/PC RIP");
+            AddCategoryMapping(40, TorznabCatType.ConsolePS3, "Games/PS3");
+            AddCategoryMapping(32, TorznabCatType.ConsoleXbox360, "Games/XBOX-360");
+            AddCategoryMapping(33, TorznabCatType.PCISO, "Software/PC ISO");
+            AddCategoryMapping(35, TorznabCatType.BooksEbook, "e-Books");
+        }
+
+
+        async Task CheckToken()
+        {
+            if (!HasValidToken)
+            {
+                var queryCollection = new NameValueCollection();
+                queryCollection.Add("get_token", "get_token");
+
+                var tokenUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
+
+                var result = await RequestStringWithCookiesAndRetry(tokenUrl);
+                var json = JObject.Parse(result.Content);
+                token = json.Value<string>("token");
+                lastTokenFetch = DateTime.Now;
+            }
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            configData.LoadValuesFromJson(configJson);
+            var releases = await PerformQuery(new TorznabQuery());
+
+            await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
+            {
+                throw new Exception("Could not find releases from this URL");
+            });
+
+            return IndexerConfigurationStatus.Completed;
+        }
+
+        public Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            return PerformQuery(query, 0);
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query, int attempts = 0)
+        {
+            await CheckToken();
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("token", token);
+            queryCollection.Add("format", "json_extended");
+            queryCollection.Add("app_id", "jackett_v" + Engine.ConfigService.GetVersion());
+            queryCollection.Add("limit", "100");
+            queryCollection.Add("ranked", "0");
+
+            if (query.ImdbID != null)
+            {
+                queryCollection.Add("mode", "search");
+                queryCollection.Add("search_imdb", query.ImdbID);
+            }
+            else if (query.RageID != null)
+            {
+                queryCollection.Add("mode", "search");
+                queryCollection.Add("search_tvrage", query.RageID.ToString());
+            }
+            /*else if (query.TvdbID != null)
+            {
+                queryCollection.Add("mode", "search");
+                queryCollection.Add("search_tvdb", query.TvdbID);
+            }*/
+            else if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("mode", "search");
+                queryCollection.Add("search_string", searchString);
+            }
+            else
+            {
+                queryCollection.Add("mode", "list");
+            }
+
+            var cats = string.Join(";", MapTorznabCapsToTrackers(query));
+            if (!string.IsNullOrEmpty(cats))
+            {
+                queryCollection.Add("category", cats);
+            }
+
+            var searchUrl = ApiEndpoint + "?" + queryCollection.GetQueryString();
+            var response = await RequestStringWithCookiesAndRetry(searchUrl, string.Empty);
+
+            try
+            {
+                var jsonContent = JObject.Parse(response.Content);
+
+                int errorCode = jsonContent.Value<int>("error_code");
+                if (errorCode == 20) // no results found
+                {
+                    return releases.ToArray();
+                }
+
+                if (errorCode > 0) // too many requests per second
+                {
+                    // we use the IwebClient rate limiter now, this shouldn't happen 
+                    throw new Exception(jsonContent.Value<string>("error"));
+
+                    /*if (attempts < 3)
+                    {
+                        await Task.Delay(TimeSpan.FromSeconds(2));
+                        return await PerformQuery(query, ++attempts);
+                    }
+                    else
+                    {
+                        throw new Exception(jsonContent.Value<string>("error"));
+                    }*/
+                }
+
+                foreach (var item in jsonContent.Value<JArray>("torrent_results"))
+                {
+                    var release = new ReleaseInfo();
+                    release.Title = item.Value<string>("title");
+                    release.Category = MapTrackerCatDescToNewznab(item.Value<string>("category"));
+
+                    release.MagnetUri = new Uri(item.Value<string>("download"));
+                    release.InfoHash = release.MagnetUri.ToString().Split(':')[3].Split('&')[0];
+
+                    release.Comments = new Uri(item.Value<string>("info_page"));
+                    release.Guid = release.Comments;
+
+                    var episode_info = item.Value<JToken>("episode_info");
+
+                    if (episode_info.HasValues)
+                    {
+                        var imdb = episode_info.Value<string>("imdb");
+                        release.Imdb = ParseUtil.GetImdbID(imdb);
+                        release.TVDBId = episode_info.Value<long?>("tvdb");
+                        release.RageID = episode_info.Value<long?>("tvrage");
+                        release.TMDb = episode_info.Value<long?>("themoviedb");
+                    }
+
+                    // ex: 2015-08-16 21:25:08 +0000
+                    var dateStr = item.Value<string>("pubdate").Replace(" +0000", "");
+                    var dateTime = DateTime.ParseExact(dateStr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
+                    release.PublishDate = DateTime.SpecifyKind(dateTime, DateTimeKind.Utc).ToLocalTime();
+
+                    release.Seeders = item.Value<int>("seeders");
+                    release.Peers = item.Value<int>("leechers") + release.Seeders;
+                    release.Size = item.Value<long>("size");
+                    release.DownloadVolumeFactor = 0;
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(response.Content, ex);
+            }
+
+            return releases;
+        }
+
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/Redacted.cs b/src/Jackett/Indexers/Redacted.cs
index 82d0f13092f0e61e3abdfbbf4c88f695f3c7a6c5..1fc5b3fe530a473b5745c58a39625b79e410e41c 100644
--- a/src/Jackett/Indexers/Redacted.cs
+++ b/src/Jackett/Indexers/Redacted.cs
@@ -2,8 +2,8 @@
 using NLog;
 using Jackett.Services;
 using Jackett.Utils.Clients;
-using Jackett.Indexers.Abstract;
-
+using Jackett.Indexers.Abstract;
+
 namespace Jackett.Indexers
 {
     public class PassTheHeadphones : GazelleTracker, IIndexer
@@ -22,12 +22,12 @@ namespace Jackett.Indexers
             Type = "private";
 
             AddCategoryMapping(1, TorznabCatType.Audio, "Music");
-            AddCategoryMapping(2, TorznabCatType.PC, "Applications");
-            AddCategoryMapping(3, TorznabCatType.Books, "E-Books");
-            AddCategoryMapping(4, TorznabCatType.AudioAudiobook, "Audiobooks");
-            AddCategoryMapping(5, TorznabCatType.Movies, "E-Learning Videos");
-            AddCategoryMapping(6, TorznabCatType.TV, "Comedy");
-            AddCategoryMapping(7, TorznabCatType.Books, "Comics");
+            AddCategoryMapping(2, TorznabCatType.PC, "Applications");
+            AddCategoryMapping(3, TorznabCatType.Books, "E-Books");
+            AddCategoryMapping(4, TorznabCatType.AudioAudiobook, "Audiobooks");
+            AddCategoryMapping(5, TorznabCatType.Movies, "E-Learning Videos");
+            AddCategoryMapping(6, TorznabCatType.TV, "Comedy");
+            AddCategoryMapping(7, TorznabCatType.Books, "Comics");
         }
     }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/SceneAccess.cs b/src/Jackett/Indexers/SceneAccess.cs
index fa62fea5824f495c4c887f49f01b55114a72601c..9dcd6ef8815e3c50841e588a996ced1f2f92d3b5 100644
--- a/src/Jackett/Indexers/SceneAccess.cs
+++ b/src/Jackett/Indexers/SceneAccess.cs
@@ -1,175 +1,175 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Web;
-
-namespace Jackett.Indexers
-{
-    class SceneAccess : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "login"; } }
-        private string SearchUrl { get { return SiteLink + "all?search={0}&method=2"; } }
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
-            : base(name: "SceneAccess",
-                description: "Your gateway to the scene",
-                link: "https://sceneaccess.eu/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: c,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            AddCategoryMapping(8, TorznabCatType.MoviesSD);
-            AddCategoryMapping(22, TorznabCatType.MoviesHD);
-            AddCategoryMapping(7, TorznabCatType.MoviesSD);
-            AddCategoryMapping(4, TorznabCatType.Movies);
-
-            AddCategoryMapping(27, TorznabCatType.TVHD);
-            AddCategoryMapping(17, TorznabCatType.TVSD);
-            AddCategoryMapping(11, TorznabCatType.MoviesSD);
-            AddCategoryMapping(26, TorznabCatType.TV);
-
-            AddCategoryMapping(3, TorznabCatType.PCGames);
-            AddCategoryMapping(5, TorznabCatType.ConsolePS3);
-            AddCategoryMapping(20, TorznabCatType.ConsolePSP);
-            AddCategoryMapping(28, TorznabCatType.TV);
-            AddCategoryMapping(23, TorznabCatType.Console);
-            AddCategoryMapping(29, TorznabCatType.Console);
-
-            AddCategoryMapping(40, TorznabCatType.AudioLossless);
-            AddCategoryMapping(13, TorznabCatType.AudioMP3);
-            AddCategoryMapping(15, TorznabCatType.AudioVideo);
-
-            AddCategoryMapping(1, TorznabCatType.PCISO);
-            AddCategoryMapping(2, TorznabCatType.PCISO);
-            AddCategoryMapping(14, TorznabCatType.PCISO);
-            AddCategoryMapping(21, TorznabCatType.Other);
-
-            AddCategoryMapping(41, TorznabCatType.MoviesHD);
-            AddCategoryMapping(42, TorznabCatType.MoviesSD);
-            AddCategoryMapping(43, TorznabCatType.MoviesSD);
-            AddCategoryMapping(44, TorznabCatType.TVHD);
-            AddCategoryMapping(45, TorznabCatType.TVSD);
-
-            AddCategoryMapping(12, TorznabCatType.XXXXviD);
-            AddCategoryMapping(35, TorznabCatType.XXXx264);
-            AddCategoryMapping(36, TorznabCatType.XXX);
-
-            AddCategoryMapping(30, TorznabCatType.MoviesForeign);
-            AddCategoryMapping(31, TorznabCatType.MoviesForeign);
-            AddCategoryMapping(32, TorznabCatType.MoviesForeign);
-            AddCategoryMapping(33, TorznabCatType.TVFOREIGN);
-            AddCategoryMapping(34, TorznabCatType.TVFOREIGN);
-
-            AddCategoryMapping(4, TorznabCatType.Movies);
-            AddCategoryMapping(37, TorznabCatType.XXX);
-            AddCategoryMapping(38, TorznabCatType.Audio);
-
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "submit", "come on in" }
-            };
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("nav_profile"), () =>
-            {
-                CQ dom = result.Content;
-                var messageEl = dom["#login_box_desc"];
-                var errorMessage = messageEl.Text().Trim();
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString())));
-
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom["#torrents-table > tbody > tr.tt_row"];
-                foreach (var row in rows)
-                {
-                    CQ qRow = row.Cq();
-                    var release = new ReleaseInfo();
-
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 129600;
-                    release.Title = qRow.Find(".ttr_name > a").Text();
-                    release.Description = release.Title;
-                    release.Guid = new Uri(SiteLink  + qRow.Find(".ttr_name > a").Attr("href"));
-                    release.Comments = release.Guid;
-                    release.Link = new Uri(SiteLink + qRow.Find(".td_dl > a").Attr("href"));
-
-                    var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue;
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    var timeStr = qRow.Find(".ttr_added").Text();
-                    DateTime time;
-                    if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
-                    {
-                        release.PublishDate = time;
-                    }
-
-                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text());
-                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders;
-
-                    var cat = qRow.Find(".ttr_type a").Attr("href").Replace("?cat=",string.Empty);
-
-                    release.Category = MapTrackerCatToNewznab(cat);
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Web;
+
+namespace Jackett.Indexers
+{
+    class SceneAccess : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "login"; } }
+        private string SearchUrl { get { return SiteLink + "all?search={0}&method=2"; } }
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public SceneAccess(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
+            : base(name: "SceneAccess",
+                description: "Your gateway to the scene",
+                link: "https://sceneaccess.eu/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: c,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            AddCategoryMapping(8, TorznabCatType.MoviesSD);
+            AddCategoryMapping(22, TorznabCatType.MoviesHD);
+            AddCategoryMapping(7, TorznabCatType.MoviesSD);
+            AddCategoryMapping(4, TorznabCatType.Movies);
+
+            AddCategoryMapping(27, TorznabCatType.TVHD);
+            AddCategoryMapping(17, TorznabCatType.TVSD);
+            AddCategoryMapping(11, TorznabCatType.MoviesSD);
+            AddCategoryMapping(26, TorznabCatType.TV);
+
+            AddCategoryMapping(3, TorznabCatType.PCGames);
+            AddCategoryMapping(5, TorznabCatType.ConsolePS3);
+            AddCategoryMapping(20, TorznabCatType.ConsolePSP);
+            AddCategoryMapping(28, TorznabCatType.TV);
+            AddCategoryMapping(23, TorznabCatType.Console);
+            AddCategoryMapping(29, TorznabCatType.Console);
+
+            AddCategoryMapping(40, TorznabCatType.AudioLossless);
+            AddCategoryMapping(13, TorznabCatType.AudioMP3);
+            AddCategoryMapping(15, TorznabCatType.AudioVideo);
+
+            AddCategoryMapping(1, TorznabCatType.PCISO);
+            AddCategoryMapping(2, TorznabCatType.PCISO);
+            AddCategoryMapping(14, TorznabCatType.PCISO);
+            AddCategoryMapping(21, TorznabCatType.Other);
+
+            AddCategoryMapping(41, TorznabCatType.MoviesHD);
+            AddCategoryMapping(42, TorznabCatType.MoviesSD);
+            AddCategoryMapping(43, TorznabCatType.MoviesSD);
+            AddCategoryMapping(44, TorznabCatType.TVHD);
+            AddCategoryMapping(45, TorznabCatType.TVSD);
+
+            AddCategoryMapping(12, TorznabCatType.XXXXviD);
+            AddCategoryMapping(35, TorznabCatType.XXXx264);
+            AddCategoryMapping(36, TorznabCatType.XXX);
+
+            AddCategoryMapping(30, TorznabCatType.MoviesForeign);
+            AddCategoryMapping(31, TorznabCatType.MoviesForeign);
+            AddCategoryMapping(32, TorznabCatType.MoviesForeign);
+            AddCategoryMapping(33, TorznabCatType.TVFOREIGN);
+            AddCategoryMapping(34, TorznabCatType.TVFOREIGN);
+
+            AddCategoryMapping(4, TorznabCatType.Movies);
+            AddCategoryMapping(37, TorznabCatType.XXX);
+            AddCategoryMapping(38, TorznabCatType.Audio);
+
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "submit", "come on in" }
+            };
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SiteLink, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("nav_profile"), () =>
+            {
+                CQ dom = result.Content;
+                var messageEl = dom["#login_box_desc"];
+                var errorMessage = messageEl.Text().Trim();
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var results = await RequestStringWithCookiesAndRetry(string.Format(SearchUrl, HttpUtility.UrlEncode(query.GetQueryString())));
+
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom["#torrents-table > tbody > tr.tt_row"];
+                foreach (var row in rows)
+                {
+                    CQ qRow = row.Cq();
+                    var release = new ReleaseInfo();
+
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 129600;
+                    release.Title = qRow.Find(".ttr_name > a").Text();
+                    release.Description = release.Title;
+                    release.Guid = new Uri(SiteLink  + qRow.Find(".ttr_name > a").Attr("href"));
+                    release.Comments = release.Guid;
+                    release.Link = new Uri(SiteLink + qRow.Find(".td_dl > a").Attr("href"));
+
+                    var sizeStr = qRow.Find(".ttr_size").Contents()[0].NodeValue;
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    var timeStr = qRow.Find(".ttr_added").Text();
+                    DateTime time;
+                    if (DateTime.TryParseExact(timeStr, "yyyy-MM-ddHH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.None, out time))
+                    {
+                        release.PublishDate = time;
+                    }
+
+                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".ttr_seeders").Text());
+                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".ttr_leechers").Text()) + release.Seeders;
+
+                    var cat = qRow.Find(".ttr_type a").Attr("href").Replace("?cat=",string.Empty);
+
+                    release.Category = MapTrackerCatToNewznab(cat);
+
                     var files = qRow.Find("td.ttr_size > a").Text().Split(' ')[0];
                     release.Files = ParseUtil.CoerceInt(files);
 
                     var grabs = qRow.Find("td.ttr_snatched").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    release.DownloadVolumeFactor = 1;
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+                    release.DownloadVolumeFactor = 1;
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/SceneFZ.cs b/src/Jackett/Indexers/SceneFZ.cs
index 7fe1346d89967b7817b1710ba35c1cc85338349a..6a2fc5fc408e8bd120c0db44cac885c7d8247e20 100644
--- a/src/Jackett/Indexers/SceneFZ.cs
+++ b/src/Jackett/Indexers/SceneFZ.cs
@@ -44,51 +44,51 @@ namespace Jackett.Indexers
 
             this.configData.Instructions.Value = "The published date is only available if you set \"Torrent Listing\" to Complex is your profile.";
 
-            AddCategoryMapping("mc32", TorznabCatType.Movies); // Movies
-            AddCategoryMapping("scat22", TorznabCatType.MoviesBluRay); // BluRay
-            AddCategoryMapping("scat40", TorznabCatType.MoviesSD); // Xvid
-            AddCategoryMapping("scat41", TorznabCatType.MoviesDVD); // Dvd
-            AddCategoryMapping("scat47", TorznabCatType.MoviesHD); // HD
-            AddCategoryMapping("scat52", TorznabCatType.MoviesDVD); // DVD-RO
-            AddCategoryMapping("scat53", TorznabCatType.MoviesHD); // HD-RO
-            AddCategoryMapping("scat54", TorznabCatType.MoviesBluRay); // BluRay-RO
-            AddCategoryMapping("scat55", TorznabCatType.MoviesSD); // XVID-RO
-            AddCategoryMapping("scat60", TorznabCatType.MoviesOther); // Sport
-            AddCategoryMapping("mc33", TorznabCatType.TV); // TV
-            AddCategoryMapping("scat66", TorznabCatType.TVSD); // SD
-            AddCategoryMapping("scat67", TorznabCatType.TVSD); // SD-RO
-            AddCategoryMapping("scat68", TorznabCatType.TVHD); // HD
-            AddCategoryMapping("scat69", TorznabCatType.TVHD); // HDTV-RO
-            AddCategoryMapping("mc30", TorznabCatType.Console); // Games
-            AddCategoryMapping("scat58", TorznabCatType.ConsolePS3); // PS2
-            AddCategoryMapping("scat16", TorznabCatType.PCGames); // Pc-Iso
-            AddCategoryMapping("scat17", TorznabCatType.Console); // Misc
-            AddCategoryMapping("scat18", TorznabCatType.PCGames); // Pc-Rip
-            AddCategoryMapping("scat19", TorznabCatType.Console); // Consoles
-            AddCategoryMapping("scat57", TorznabCatType.ConsoleXbox360); // Xbox 360
-            AddCategoryMapping("scat46", TorznabCatType.Console); // Oldies
-            AddCategoryMapping("scat59", TorznabCatType.ConsolePS3); // PS3
-            AddCategoryMapping("mc31", TorznabCatType.PC); // Soft
-            AddCategoryMapping("scat20", TorznabCatType.PC); // Pc-Iso
-            AddCategoryMapping("scat21", TorznabCatType.PC); // Misc
-            AddCategoryMapping("scat48", TorznabCatType.PCMac); // Mac OS
-            AddCategoryMapping("mc27", TorznabCatType.Audio); // Music
-            AddCategoryMapping("scat8", TorznabCatType.AudioMP3); // MP3
-            AddCategoryMapping("scat45", TorznabCatType.AudioVideo); // Videoclips
-            AddCategoryMapping("scat61", TorznabCatType.AudioLossless); // FLAC
-            AddCategoryMapping("mc35", TorznabCatType.PCPhoneOther); // Mobile
-            AddCategoryMapping("scat44", TorznabCatType.PCPhoneOther); // Misc
-            AddCategoryMapping("scat64", TorznabCatType.PCPhoneIOS); // iOS
-            AddCategoryMapping("scat65", TorznabCatType.PCPhoneAndroid); // Android
-            AddCategoryMapping("mc28", TorznabCatType.TVAnime); // Anime
-            AddCategoryMapping("scat13", TorznabCatType.TVAnime); // Tv-Eps
-            AddCategoryMapping("scat12", TorznabCatType.TVAnime); // Cartoons
-            AddCategoryMapping("mc29", TorznabCatType.TVDocumentary); // Docs
-            AddCategoryMapping("scat14", TorznabCatType.Books); // Books
-            AddCategoryMapping("scat15", TorznabCatType.Other); // Misc
-            AddCategoryMapping("mc36", TorznabCatType.PC0day); // 0Day
-            AddCategoryMapping("mc34", TorznabCatType.XXX); // XXX 18
-            AddCategoryMapping("scat33", TorznabCatType.Other); // Images
+            AddCategoryMapping("mc32", TorznabCatType.Movies); // Movies
+            AddCategoryMapping("scat22", TorznabCatType.MoviesBluRay); // BluRay
+            AddCategoryMapping("scat40", TorznabCatType.MoviesSD); // Xvid
+            AddCategoryMapping("scat41", TorznabCatType.MoviesDVD); // Dvd
+            AddCategoryMapping("scat47", TorznabCatType.MoviesHD); // HD
+            AddCategoryMapping("scat52", TorznabCatType.MoviesDVD); // DVD-RO
+            AddCategoryMapping("scat53", TorznabCatType.MoviesHD); // HD-RO
+            AddCategoryMapping("scat54", TorznabCatType.MoviesBluRay); // BluRay-RO
+            AddCategoryMapping("scat55", TorznabCatType.MoviesSD); // XVID-RO
+            AddCategoryMapping("scat60", TorznabCatType.MoviesOther); // Sport
+            AddCategoryMapping("mc33", TorznabCatType.TV); // TV
+            AddCategoryMapping("scat66", TorznabCatType.TVSD); // SD
+            AddCategoryMapping("scat67", TorznabCatType.TVSD); // SD-RO
+            AddCategoryMapping("scat68", TorznabCatType.TVHD); // HD
+            AddCategoryMapping("scat69", TorznabCatType.TVHD); // HDTV-RO
+            AddCategoryMapping("mc30", TorznabCatType.Console); // Games
+            AddCategoryMapping("scat58", TorznabCatType.ConsolePS3); // PS2
+            AddCategoryMapping("scat16", TorznabCatType.PCGames); // Pc-Iso
+            AddCategoryMapping("scat17", TorznabCatType.Console); // Misc
+            AddCategoryMapping("scat18", TorznabCatType.PCGames); // Pc-Rip
+            AddCategoryMapping("scat19", TorznabCatType.Console); // Consoles
+            AddCategoryMapping("scat57", TorznabCatType.ConsoleXbox360); // Xbox 360
+            AddCategoryMapping("scat46", TorznabCatType.Console); // Oldies
+            AddCategoryMapping("scat59", TorznabCatType.ConsolePS3); // PS3
+            AddCategoryMapping("mc31", TorznabCatType.PC); // Soft
+            AddCategoryMapping("scat20", TorznabCatType.PC); // Pc-Iso
+            AddCategoryMapping("scat21", TorznabCatType.PC); // Misc
+            AddCategoryMapping("scat48", TorznabCatType.PCMac); // Mac OS
+            AddCategoryMapping("mc27", TorznabCatType.Audio); // Music
+            AddCategoryMapping("scat8", TorznabCatType.AudioMP3); // MP3
+            AddCategoryMapping("scat45", TorznabCatType.AudioVideo); // Videoclips
+            AddCategoryMapping("scat61", TorznabCatType.AudioLossless); // FLAC
+            AddCategoryMapping("mc35", TorznabCatType.PCPhoneOther); // Mobile
+            AddCategoryMapping("scat44", TorznabCatType.PCPhoneOther); // Misc
+            AddCategoryMapping("scat64", TorznabCatType.PCPhoneIOS); // iOS
+            AddCategoryMapping("scat65", TorznabCatType.PCPhoneAndroid); // Android
+            AddCategoryMapping("mc28", TorznabCatType.TVAnime); // Anime
+            AddCategoryMapping("scat13", TorznabCatType.TVAnime); // Tv-Eps
+            AddCategoryMapping("scat12", TorznabCatType.TVAnime); // Cartoons
+            AddCategoryMapping("mc29", TorznabCatType.TVDocumentary); // Docs
+            AddCategoryMapping("scat14", TorznabCatType.Books); // Books
+            AddCategoryMapping("scat15", TorznabCatType.Other); // Misc
+            AddCategoryMapping("mc36", TorznabCatType.PC0day); // 0Day
+            AddCategoryMapping("mc34", TorznabCatType.XXX); // XXX 18
+            AddCategoryMapping("scat33", TorznabCatType.Other); // Images
             AddCategoryMapping("scat34", TorznabCatType.Other); // Video
         }
 
@@ -140,9 +140,9 @@ namespace Jackett.Indexers
                     var qRow = row.Cq();
                     var qTitleLink = qRow.Find("a[href^=\"details\"]").First();
                     if (qTitleLink.HasAttr("title"))
-                        release.Title = qTitleLink.Attr("title");
-                    else
-                        release.Title = qTitleLink.Text();
+                        release.Title = qTitleLink.Attr("title");
+                    else
+                        release.Title = qTitleLink.Text();
                     release.Description = qRow.Find("small > i").Text();
                     release.Guid = new Uri(SiteLink + qTitleLink.Attr("href"));
                     release.Comments = release.Guid;
@@ -160,8 +160,8 @@ namespace Jackett.Indexers
 
                     release.Seeders = ParseUtil.CoerceInt(qRow.Find("td > a[href*=\"&toseeders=1\"]:first-child, td:has(a[href*=\"&toseeders=1\"]) > b:nth-child(1)").Text());
                     release.Peers = ParseUtil.CoerceInt(qRow.Find("td > a[href*=\"&todlers=1\"]:last-child, a[href*=\"&toseeders=1\"] + b").Text().Replace("L.", "")) + release.Seeders;
-                    release.Grabs = ParseUtil.CoerceLong(qRow.Find("td[style]:has(a[href*=\"tosnatchers=1\"])").Text().Replace(" Completed", ""));
-
+                    release.Grabs = ParseUtil.CoerceLong(qRow.Find("td[style]:has(a[href*=\"tosnatchers=1\"])").Text().Replace(" Completed", ""));
+
                     release.DownloadVolumeFactor = 0;
                     release.UploadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/SceneTime.cs b/src/Jackett/Indexers/SceneTime.cs
index f2af21102a70d996287b6aebeaed8f2e7f8e46c1..1bbe36da4f12a70cb1ff89549df69a9cd7fa461c 100644
--- a/src/Jackett/Indexers/SceneTime.cs
+++ b/src/Jackett/Indexers/SceneTime.cs
@@ -37,7 +37,7 @@ namespace Jackett.Indexers
                 client: w,
                 logger: l,
                 p: ps,
-                configData: new ConfigurationDataRecaptchaLogin("For best results, change the 'Torrents per page' setting to the maximum in your profile on the SceneTime webpage."))
+                configData: new ConfigurationDataRecaptchaLogin("For best results, change the 'Torrents per page' setting to the maximum in your profile on the SceneTime webpage."))
         {
             Encoding = Encoding.GetEncoding("iso-8859-1");
             Language = "en-us";
@@ -96,7 +96,7 @@ namespace Jackett.Indexers
                 result.CookieHeader.Value = loginPage.Cookies;
                 result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
                 return result;
-            }
+            }
             else
             {
                 var stdResult = new ConfigurationDataBasicLogin();
@@ -105,7 +105,7 @@ namespace Jackett.Indexers
                 stdResult.Password.Value = configData.Password.Value;
                 stdResult.CookieHeader.Value = loginPage.Cookies;
                 return stdResult;
-            }
+            }
         }
 
         public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
@@ -205,7 +205,7 @@ namespace Jackett.Indexers
                     var qDescCol = descCol.Cq();
                     var qLink = qDescCol.Find("a");
                     release.Title = qLink.Text();
-                    if (!query.MatchQueryStringAND(release.Title))
+                    if (!query.MatchQueryStringAND(release.Title))
                         continue;
 
                     release.Description = release.Title;
@@ -222,11 +222,11 @@ namespace Jackett.Indexers
                     release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(seedersIndex).Cq().Text().Trim());
                     release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(leechersIndex).Cq().Text().Trim()) + release.Seeders;
 
-                    if (row.Cq().Find("font > b:contains(Freeleech)").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (row.Cq().Find("font > b:contains(Freeleech)").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/Shazbat.cs b/src/Jackett/Indexers/Shazbat.cs
index d8ebf58ea2f1f41fa69613aa4709574371a3a11a..1301a596728ec20cb1fbb2a5ff2d9d5214dbaeec 100644
--- a/src/Jackett/Indexers/Shazbat.cs
+++ b/src/Jackett/Indexers/Shazbat.cs
@@ -1,265 +1,265 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-using System.Globalization;
-using System.Text.RegularExpressions;
-using System.Xml.Linq;
-using System.Xml.XPath;
-
-namespace Jackett.Indexers
-{
-    public class Shazbat : BaseIndexer, IIndexer
-    {
-        private string LoginUrl { get { return SiteLink + "login"; } }
-        private string SearchUrl { get { return SiteLink + "search"; } }
-        private string TorrentsUrl { get { return SiteLink + "torrents"; } }
-        private string ShowUrl { get { return SiteLink + "show?id="; } }
-        private string RSSProfile { get { return SiteLink + "rss_feeds"; } }
-
-        new ConfigurationDataBasicLoginWithRSS configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSS)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public Shazbat(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
-            : base(name: "Shazbat",
-                description: "Modern indexer",
-                link: "https://www.shazbat.tv/",
-                caps: new TorznabCapabilities(TorznabCatType.TV,
-                                              TorznabCatType.TVHD,
-                                              TorznabCatType.TVSD),
-                manager: i,
-                client: c,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSS())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "en-us";
-            Type = "private";
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "referer", "login"},
-                { "query", ""},
-                { "tv_login", configData.Username.Value },
-                { "tv_password", configData.Password.Value },
-                { "email", "" }
-            };
-
-            // Get cookie
-            var firstRequest = await RequestStringWithCookiesAndRetry(LoginUrl);
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("glyphicon-log-out"), () =>
-            {
-                throw new ExceptionWithConfigData("The username and password entered do not match.", configData);
-            });
-
-            var rssProfile = await RequestStringWithCookiesAndRetry(RSSProfile);
-            CQ rssDom = rssProfile.Content;
-            configData.RSSKey.Value = rssDom.Find(".col-sm-9:eq(0)").Text().Trim();
-            if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
-            {
-                throw new ExceptionWithConfigData("Failed to find RSS key.", configData);
-            }
-
-            SaveConfig();
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        protected async Task<WebClientStringResult> ReloginIfNecessary(WebClientStringResult response)
-        {
-            if (!response.Content.Contains("onclick=\"document.location='logout'\""))
-            {
-                await ApplyConfiguration(null);
-                response.Request.Cookies = CookieHeader;
-                return await webclient.GetString(response.Request);
-            }
-            return response;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-
-            var queryString = query.GetQueryString();
-            var url = TorrentsUrl;
-
-            WebClientStringResult results = null;
-
-            var searchUrls = new List<string>();
-            if (!string.IsNullOrWhiteSpace(query.SanitizedSearchTerm))
-            {
-                var pairs = new Dictionary<string, string>();
-                pairs.Add("search", query.SanitizedSearchTerm);
-
-                results = await PostDataWithCookiesAndRetry(SearchUrl, pairs, null, TorrentsUrl);
-                results = await ReloginIfNecessary(results);
-                CQ dom = results.Content;
-                var shows = dom.Find("div.show[data-id]");
-                foreach (var show in shows)
-                {
-                    var showUrl = ShowUrl + show.GetAttribute("data-id");
-                    searchUrls.Add(showUrl);
-                }
-            }
-            else
-            {
-                searchUrls.Add(TorrentsUrl);
-            }
-
-            try
-            {
-                foreach (var searchUrl in searchUrls)
-                {
-                    results = await RequestStringWithCookies(searchUrl);
-                    results = await ReloginIfNecessary(results);
-
-                    CQ dom = results.Content;
-                    var rows = dom["#torrent-table tr"];
-
-                    if (!string.IsNullOrWhiteSpace(queryString))
-                    {
-                        rows = dom["table tr"];
-                    }
-
-                    var globalFreeleech = dom.Find("span:contains(\"Freeleech until:\"):has(span.datetime)").Any();
-
-                    foreach (var row in rows.Skip(1))
-                    {
-                        var release = new ReleaseInfo();
-                        var qRow = row.Cq();
-                        var titleRow = qRow.Find("td:eq(2)").First();
-                        titleRow.Children().Remove();
-                        release.Title = titleRow.Text().Trim();
-                        if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
-                            continue;
-
-                        var qBanner = qRow.Find("div[style^=\"cursor: pointer; background-image:url\"]");
-                        var qBannerStyle = qBanner.Attr("style");
-                        if (!string.IsNullOrEmpty(qBannerStyle))
-                        {
-                            var bannerImg = Regex.Match(qBannerStyle, @"url\('(.*?)'\);").Groups[1].Value;
-                            release.BannerUrl = new Uri(SiteLink + bannerImg);
-                        }
-
-                        var qLink = row.Cq().Find("td:eq(4) a:eq(0)");
-                        release.Link = new Uri(SiteLink + qLink.Attr("href"));
-                        release.Guid = release.Link;
-                        var qLinkComm = row.Cq().Find("td:eq(4) a:eq(1)");
-                        release.Comments = new Uri(SiteLink + qLinkComm.Attr("href"));
-
-                        var dateString = qRow.Find(".datetime").Attr("data-timestamp");
-                        if (dateString != null)
-                            release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(ParseUtil.CoerceDouble(dateString)).ToLocalTime();
-                        var infoString = row.Cq().Find("td:eq(3)").Text();
-
-                        release.Size = ParseUtil.CoerceLong(Regex.Match(infoString, "\\((\\d+)\\)").Value.Replace("(", "").Replace(")", ""));
-
-                        var infosplit = infoString.Replace("/", string.Empty).Split(":".ToCharArray());
-                        release.Seeders = ParseUtil.CoerceInt(infosplit[1]);
-                        release.Peers = release.Seeders + ParseUtil.CoerceInt(infosplit[2]);
-
-                        if (globalFreeleech)
-                            release.DownloadVolumeFactor = 0;
-                        else
-                            release.DownloadVolumeFactor = 1;
-
-                        release.UploadVolumeFactor = 1;
-
-                        // var tags = row.Cq().Find(".label-tag").Text(); These don't see to parse - bad tags?
-
-                        releases.Add(release);
-                    }
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-            /* else
-             {
-                 var rssUrl = SiteLink + "rss/recent?passkey=" + configData.RSSKey.Value;
-
-                 results = await RequestStringWithCookiesAndRetry(rssUrl);
-                 try
-                 {
-                     var doc = XDocument.Parse(results.Content);
-                     foreach (var result in doc.Descendants("item"))
-                     {
-                         var xTitle = result.Element("title").Value;
-                         var xLink = result.Element("link").Value;
-                         var xGUID = result.Element("guid").Value;
-                         var xDesc = result.Element("description").Value;
-                         var xDate = result.Element("pubDate").Value;
-                         var release = new ReleaseInfo();
-                         release.Guid  =release.Link =  new Uri(xLink);
-                         release.MinimumRatio = 1;
-                         release.Seeders = 1; // We are not supplied with peer info so just mark it as one.
-                         foreach (var element in xDesc.Split(";".ToCharArray()))
-                         {
-                             var split = element.IndexOf(':');
-                             if (split > -1)
-                             {
-                                 var key = element.Substring(0, split).Trim();
-                                 var value = element.Substring(split+1).Trim();
-
-                                 switch (key)
-                                 {
-                                     case "Filename":
-                                         release.Title = release.Description = value;
-                                         break;
-                                 }
-                             }
-                         }
-
-                         //"Thu, 24 Sep 2015 18:07:07 +0000"
-                         release.PublishDate = DateTime.ParseExact(xDate, "ddd, dd MMM yyyy HH:mm:ss +0000", CultureInfo.InvariantCulture);
-
-                         if (!string.IsNullOrWhiteSpace(release.Title))
-                         {
-                             releases.Add(release);
-                         }
-                     }
-                 }
-                 catch (Exception ex)
-                 {
-                     OnParseError(results.Content, ex);
-                 }*/
-
-
-            foreach (var release in releases)
-            {
-                if (release.Title.Contains("1080p") || release.Title.Contains("720p"))
-                {
-                    release.Category = new List<int> { TorznabCatType.TVHD.ID };
-                }
-                else
-                {
-                    release.Category = new List<int> { TorznabCatType.TVSD.ID };
-                }
-            }
-
-            return releases;
-        }
-    }
-}
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.Xml.Linq;
+using System.Xml.XPath;
+
+namespace Jackett.Indexers
+{
+    public class Shazbat : BaseIndexer, IIndexer
+    {
+        private string LoginUrl { get { return SiteLink + "login"; } }
+        private string SearchUrl { get { return SiteLink + "search"; } }
+        private string TorrentsUrl { get { return SiteLink + "torrents"; } }
+        private string ShowUrl { get { return SiteLink + "show?id="; } }
+        private string RSSProfile { get { return SiteLink + "rss_feeds"; } }
+
+        new ConfigurationDataBasicLoginWithRSS configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSS)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public Shazbat(IIndexerManagerService i, IWebClient c, Logger l, IProtectionService ps)
+            : base(name: "Shazbat",
+                description: "Modern indexer",
+                link: "https://www.shazbat.tv/",
+                caps: new TorznabCapabilities(TorznabCatType.TV,
+                                              TorznabCatType.TVHD,
+                                              TorznabCatType.TVSD),
+                manager: i,
+                client: c,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSS())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "en-us";
+            Type = "private";
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "referer", "login"},
+                { "query", ""},
+                { "tv_login", configData.Username.Value },
+                { "tv_password", configData.Password.Value },
+                { "email", "" }
+            };
+
+            // Get cookie
+            var firstRequest = await RequestStringWithCookiesAndRetry(LoginUrl);
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("glyphicon-log-out"), () =>
+            {
+                throw new ExceptionWithConfigData("The username and password entered do not match.", configData);
+            });
+
+            var rssProfile = await RequestStringWithCookiesAndRetry(RSSProfile);
+            CQ rssDom = rssProfile.Content;
+            configData.RSSKey.Value = rssDom.Find(".col-sm-9:eq(0)").Text().Trim();
+            if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
+            {
+                throw new ExceptionWithConfigData("Failed to find RSS key.", configData);
+            }
+
+            SaveConfig();
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        protected async Task<WebClientStringResult> ReloginIfNecessary(WebClientStringResult response)
+        {
+            if (!response.Content.Contains("onclick=\"document.location='logout'\""))
+            {
+                await ApplyConfiguration(null);
+                response.Request.Cookies = CookieHeader;
+                return await webclient.GetString(response.Request);
+            }
+            return response;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+
+            var queryString = query.GetQueryString();
+            var url = TorrentsUrl;
+
+            WebClientStringResult results = null;
+
+            var searchUrls = new List<string>();
+            if (!string.IsNullOrWhiteSpace(query.SanitizedSearchTerm))
+            {
+                var pairs = new Dictionary<string, string>();
+                pairs.Add("search", query.SanitizedSearchTerm);
+
+                results = await PostDataWithCookiesAndRetry(SearchUrl, pairs, null, TorrentsUrl);
+                results = await ReloginIfNecessary(results);
+                CQ dom = results.Content;
+                var shows = dom.Find("div.show[data-id]");
+                foreach (var show in shows)
+                {
+                    var showUrl = ShowUrl + show.GetAttribute("data-id");
+                    searchUrls.Add(showUrl);
+                }
+            }
+            else
+            {
+                searchUrls.Add(TorrentsUrl);
+            }
+
+            try
+            {
+                foreach (var searchUrl in searchUrls)
+                {
+                    results = await RequestStringWithCookies(searchUrl);
+                    results = await ReloginIfNecessary(results);
+
+                    CQ dom = results.Content;
+                    var rows = dom["#torrent-table tr"];
+
+                    if (!string.IsNullOrWhiteSpace(queryString))
+                    {
+                        rows = dom["table tr"];
+                    }
+
+                    var globalFreeleech = dom.Find("span:contains(\"Freeleech until:\"):has(span.datetime)").Any();
+
+                    foreach (var row in rows.Skip(1))
+                    {
+                        var release = new ReleaseInfo();
+                        var qRow = row.Cq();
+                        var titleRow = qRow.Find("td:eq(2)").First();
+                        titleRow.Children().Remove();
+                        release.Title = titleRow.Text().Trim();
+                        if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
+                            continue;
+
+                        var qBanner = qRow.Find("div[style^=\"cursor: pointer; background-image:url\"]");
+                        var qBannerStyle = qBanner.Attr("style");
+                        if (!string.IsNullOrEmpty(qBannerStyle))
+                        {
+                            var bannerImg = Regex.Match(qBannerStyle, @"url\('(.*?)'\);").Groups[1].Value;
+                            release.BannerUrl = new Uri(SiteLink + bannerImg);
+                        }
+
+                        var qLink = row.Cq().Find("td:eq(4) a:eq(0)");
+                        release.Link = new Uri(SiteLink + qLink.Attr("href"));
+                        release.Guid = release.Link;
+                        var qLinkComm = row.Cq().Find("td:eq(4) a:eq(1)");
+                        release.Comments = new Uri(SiteLink + qLinkComm.Attr("href"));
+
+                        var dateString = qRow.Find(".datetime").Attr("data-timestamp");
+                        if (dateString != null)
+                            release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(ParseUtil.CoerceDouble(dateString)).ToLocalTime();
+                        var infoString = row.Cq().Find("td:eq(3)").Text();
+
+                        release.Size = ParseUtil.CoerceLong(Regex.Match(infoString, "\\((\\d+)\\)").Value.Replace("(", "").Replace(")", ""));
+
+                        var infosplit = infoString.Replace("/", string.Empty).Split(":".ToCharArray());
+                        release.Seeders = ParseUtil.CoerceInt(infosplit[1]);
+                        release.Peers = release.Seeders + ParseUtil.CoerceInt(infosplit[2]);
+
+                        if (globalFreeleech)
+                            release.DownloadVolumeFactor = 0;
+                        else
+                            release.DownloadVolumeFactor = 1;
+
+                        release.UploadVolumeFactor = 1;
+
+                        // var tags = row.Cq().Find(".label-tag").Text(); These don't see to parse - bad tags?
+
+                        releases.Add(release);
+                    }
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+            /* else
+             {
+                 var rssUrl = SiteLink + "rss/recent?passkey=" + configData.RSSKey.Value;
+
+                 results = await RequestStringWithCookiesAndRetry(rssUrl);
+                 try
+                 {
+                     var doc = XDocument.Parse(results.Content);
+                     foreach (var result in doc.Descendants("item"))
+                     {
+                         var xTitle = result.Element("title").Value;
+                         var xLink = result.Element("link").Value;
+                         var xGUID = result.Element("guid").Value;
+                         var xDesc = result.Element("description").Value;
+                         var xDate = result.Element("pubDate").Value;
+                         var release = new ReleaseInfo();
+                         release.Guid  =release.Link =  new Uri(xLink);
+                         release.MinimumRatio = 1;
+                         release.Seeders = 1; // We are not supplied with peer info so just mark it as one.
+                         foreach (var element in xDesc.Split(";".ToCharArray()))
+                         {
+                             var split = element.IndexOf(':');
+                             if (split > -1)
+                             {
+                                 var key = element.Substring(0, split).Trim();
+                                 var value = element.Substring(split+1).Trim();
+
+                                 switch (key)
+                                 {
+                                     case "Filename":
+                                         release.Title = release.Description = value;
+                                         break;
+                                 }
+                             }
+                         }
+
+                         //"Thu, 24 Sep 2015 18:07:07 +0000"
+                         release.PublishDate = DateTime.ParseExact(xDate, "ddd, dd MMM yyyy HH:mm:ss +0000", CultureInfo.InvariantCulture);
+
+                         if (!string.IsNullOrWhiteSpace(release.Title))
+                         {
+                             releases.Add(release);
+                         }
+                     }
+                 }
+                 catch (Exception ex)
+                 {
+                     OnParseError(results.Content, ex);
+                 }*/
+
+
+            foreach (var release in releases)
+            {
+                if (release.Title.Contains("1080p") || release.Title.Contains("720p"))
+                {
+                    release.Category = new List<int> { TorznabCatType.TVHD.ID };
+                }
+                else
+                {
+                    release.Category = new List<int> { TorznabCatType.TVSD.ID };
+                }
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/ShowRSS.cs b/src/Jackett/Indexers/ShowRSS.cs
index c865f378b7e0919b71d5a81aed7d9dae70e73f22..ff305b0ac44ae4a7cf8f61ed7f476ecf07c42834 100644
--- a/src/Jackett/Indexers/ShowRSS.cs
+++ b/src/Jackett/Indexers/ShowRSS.cs
@@ -1,115 +1,115 @@
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Threading.Tasks;
-using System.Xml;
-using System.Text;
-using Jackett.Models.IndexerConfig;
-
-namespace Jackett.Indexers
-{
-    public class ShowRSS : BaseIndexer, IIndexer
-    {
-        private string SearchAllUrl { get { return SiteLink + "feeds/all.rss"; } }
-
-        new ConfigurationData configData
-        {
-            get { return (ConfigurationData)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
-            : base(name: "ShowRSS",
-                description: "showRSS is a service that allows you to keep track of your favorite TV shows",
-                link: "http://showrss.info/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationData())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "en-us";
-            Type = "public";
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            configData.LoadValuesFromJson(configJson);
-            var releases = await PerformQuery(new TorznabQuery());
-
-            await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
-            {
-                throw new Exception("Could not find releases from this URL");
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public override Task<byte[]> Download(Uri link)
-        {
-            throw new NotImplementedException();
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var episodeSearchUrl = string.Format(SearchAllUrl);
-            var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
-            var xmlDoc = new XmlDocument();
-
-            try
-            {
-                xmlDoc.LoadXml(result.Content);
-                ReleaseInfo release;
-                string serie_title;
-
-                foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
-                {
-                    release = new ReleaseInfo();
-
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-
-                    serie_title = node.SelectSingleNode(".//*[local-name()='rawtitle']").InnerText;
-                    release.Title = serie_title;
-
-                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
-                    int category = 0;
-                    int.TryParse(node.SelectSingleNode("title").InnerText, out category);
-                    release.Category = new List<int> { category };
-                    var test = node.SelectSingleNode("enclosure");
-                    release.Guid = new Uri(test.Attributes["url"].Value);
-                    release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);
-
-                    release.Description = node.SelectSingleNode("description").InnerText;
-                    release.InfoHash = node.SelectSingleNode("description").InnerText;
-                    release.Size = 0;
-                    release.Seeders = 1;
-                    release.Peers = 1;
-                    release.DownloadVolumeFactor = 0;
-                    release.UploadVolumeFactor = 1;
-                    release.MagnetUri = new Uri(node.SelectSingleNode("link").InnerText);
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(result.Content, ex);
-            }
-
-            return releases;
-        }
-    }
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
+using System.Xml;
+using System.Text;
+using Jackett.Models.IndexerConfig;
+
+namespace Jackett.Indexers
+{
+    public class ShowRSS : BaseIndexer, IIndexer
+    {
+        private string SearchAllUrl { get { return SiteLink + "feeds/all.rss"; } }
+
+        new ConfigurationData configData
+        {
+            get { return (ConfigurationData)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public ShowRSS(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
+            : base(name: "ShowRSS",
+                description: "showRSS is a service that allows you to keep track of your favorite TV shows",
+                link: "http://showrss.info/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationData())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "en-us";
+            Type = "public";
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            configData.LoadValuesFromJson(configJson);
+            var releases = await PerformQuery(new TorznabQuery());
+
+            await ConfigureIfOK(string.Empty, releases.Count() > 0, () =>
+            {
+                throw new Exception("Could not find releases from this URL");
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public override Task<byte[]> Download(Uri link)
+        {
+            throw new NotImplementedException();
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var episodeSearchUrl = string.Format(SearchAllUrl);
+            var result = await RequestStringWithCookiesAndRetry(episodeSearchUrl, string.Empty);
+            var xmlDoc = new XmlDocument();
+
+            try
+            {
+                xmlDoc.LoadXml(result.Content);
+                ReleaseInfo release;
+                string serie_title;
+
+                foreach (XmlNode node in xmlDoc.GetElementsByTagName("item"))
+                {
+                    release = new ReleaseInfo();
+
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+
+                    serie_title = node.SelectSingleNode(".//*[local-name()='rawtitle']").InnerText;
+                    release.Title = serie_title;
+
+                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    release.Comments = new Uri(node.SelectSingleNode("link").InnerText);
+                    int category = 0;
+                    int.TryParse(node.SelectSingleNode("title").InnerText, out category);
+                    release.Category = new List<int> { category };
+                    var test = node.SelectSingleNode("enclosure");
+                    release.Guid = new Uri(test.Attributes["url"].Value);
+                    release.PublishDate = DateTime.Parse(node.SelectSingleNode("pubDate").InnerText, CultureInfo.InvariantCulture);
+
+                    release.Description = node.SelectSingleNode("description").InnerText;
+                    release.InfoHash = node.SelectSingleNode("description").InnerText;
+                    release.Size = 0;
+                    release.Seeders = 1;
+                    release.Peers = 1;
+                    release.DownloadVolumeFactor = 0;
+                    release.UploadVolumeFactor = 1;
+                    release.MagnetUri = new Uri(node.SelectSingleNode("link").InnerText);
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(result.Content, ex);
+            }
+
+            return releases;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/SpeedCD.cs b/src/Jackett/Indexers/SpeedCD.cs
index 6eae710d248d6e313a1033b92971710ac78e75d3..5b17f105fc264887f0b543f628f3e1b9b91bdca8 100644
--- a/src/Jackett/Indexers/SpeedCD.cs
+++ b/src/Jackett/Indexers/SpeedCD.cs
@@ -179,8 +179,8 @@ namespace Jackett.Indexers
                     if (torrentData.Find("span:contains(\"[Freeleech]\")").Any())
                         release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/Superbits.cs b/src/Jackett/Indexers/Superbits.cs
index 8f3e53dac0c022bd92d89f628c15f02be4429e73..9a5b5df16d6f287dc380767f6922eba010868383 100644
--- a/src/Jackett/Indexers/Superbits.cs
+++ b/src/Jackett/Indexers/Superbits.cs
@@ -1,198 +1,198 @@
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using Newtonsoft.Json;
-using System.Globalization;
-
-namespace Jackett.Indexers
-{
-    public class Superbits : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
-        private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
-
-        new ConfigurationDataBasicLogin configData
-        {
-            get { return (ConfigurationDataBasicLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public Superbits(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "Superbits",
-                description: null,
-                link: "https://superbits.org/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "sv-sw";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(1, TorznabCatType.MoviesDVD, "DVD-R Swesub");
-            AddCategoryMapping(2, TorznabCatType.TV, "DVD-R TV");
-            AddCategoryMapping(3, TorznabCatType.BooksEbook, "eBok");
-            AddCategoryMapping(4, TorznabCatType.MoviesHD, "Film 1080");
-            AddCategoryMapping(5, TorznabCatType.Movies3D, "Film 3D");
-            AddCategoryMapping(6, TorznabCatType.MoviesHD, "Film 720");
-            AddCategoryMapping(7, TorznabCatType.MoviesBluRay, "Film Bluray");
-            AddCategoryMapping(8, TorznabCatType.TV, "Svensk TV");
-            AddCategoryMapping(9, TorznabCatType.AudioAudiobook, "Ljudböcker");
-            AddCategoryMapping(10, TorznabCatType.AudioVideo, "Musikvideos");
-            AddCategoryMapping(11, TorznabCatType.BooksMagazines, "E-tidningar");
-            AddCategoryMapping(12, TorznabCatType.Audio, "Musik");
-            AddCategoryMapping(13, TorznabCatType.Other, "Omslag");
-            AddCategoryMapping(14, TorznabCatType.Other, "Övrigt");
-            AddCategoryMapping(15, TorznabCatType.PCGames, "PC-Spel");
-            AddCategoryMapping(16, TorznabCatType.PC0day, "Program");
-            AddCategoryMapping(17, TorznabCatType.ConsolePS3, "PS3");
-            AddCategoryMapping(18, TorznabCatType.TV, "TV");
-            AddCategoryMapping(19, TorznabCatType.ConsoleWii, "Wii");
-            AddCategoryMapping(20, TorznabCatType.ConsoleXbox, "Xbox");
-            AddCategoryMapping(21, TorznabCatType.MoviesOther, "Xvid");
-            AddCategoryMapping(22, TorznabCatType.XXX, "XXX");
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var queryCollection = new NameValueCollection();
-
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using Newtonsoft.Json;
+using System.Globalization;
+
+namespace Jackett.Indexers
+{
+    public class Superbits : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "api/v1/torrents"; } }
+        private string LoginUrl { get { return SiteLink + "api/v1/auth"; } }
+
+        new ConfigurationDataBasicLogin configData
+        {
+            get { return (ConfigurationDataBasicLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public Superbits(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "Superbits",
+                description: null,
+                link: "https://superbits.org/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "sv-sw";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(1, TorznabCatType.MoviesDVD, "DVD-R Swesub");
+            AddCategoryMapping(2, TorznabCatType.TV, "DVD-R TV");
+            AddCategoryMapping(3, TorznabCatType.BooksEbook, "eBok");
+            AddCategoryMapping(4, TorznabCatType.MoviesHD, "Film 1080");
+            AddCategoryMapping(5, TorznabCatType.Movies3D, "Film 3D");
+            AddCategoryMapping(6, TorznabCatType.MoviesHD, "Film 720");
+            AddCategoryMapping(7, TorznabCatType.MoviesBluRay, "Film Bluray");
+            AddCategoryMapping(8, TorznabCatType.TV, "Svensk TV");
+            AddCategoryMapping(9, TorznabCatType.AudioAudiobook, "Ljudböcker");
+            AddCategoryMapping(10, TorznabCatType.AudioVideo, "Musikvideos");
+            AddCategoryMapping(11, TorznabCatType.BooksMagazines, "E-tidningar");
+            AddCategoryMapping(12, TorznabCatType.Audio, "Musik");
+            AddCategoryMapping(13, TorznabCatType.Other, "Omslag");
+            AddCategoryMapping(14, TorznabCatType.Other, "Övrigt");
+            AddCategoryMapping(15, TorznabCatType.PCGames, "PC-Spel");
+            AddCategoryMapping(16, TorznabCatType.PC0day, "Program");
+            AddCategoryMapping(17, TorznabCatType.ConsolePS3, "PS3");
+            AddCategoryMapping(18, TorznabCatType.TV, "TV");
+            AddCategoryMapping(19, TorznabCatType.ConsoleWii, "Wii");
+            AddCategoryMapping(20, TorznabCatType.ConsoleXbox, "Xbox");
+            AddCategoryMapping(21, TorznabCatType.MoviesOther, "Xvid");
+            AddCategoryMapping(22, TorznabCatType.XXX, "XXX");
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var queryCollection = new NameValueCollection();
+
             queryCollection.Add("username", configData.Username.Value);
-            queryCollection.Add("password", configData.Password.Value);
-
-            var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
-            var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
-
-            await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
-            {
-                throw new ExceptionWithConfigData(loginResult.Content, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-            var queryCollection = new NameValueCollection();
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-
-            queryCollection.Add("extendedSearch", "false");
-            queryCollection.Add("freeleech", "false");
-            queryCollection.Add("index", "0");
-            queryCollection.Add("limit", "100");
-            queryCollection.Add("order", "desc");
-            queryCollection.Add("page", "search");
-            if (query.ImdbID != null)
-                queryCollection.Add("searchText", query.ImdbID);
-            else
-                queryCollection.Add("searchText", searchString);
-            queryCollection.Add("sort", "d");
-            queryCollection.Add("section", "all");
-            queryCollection.Add("stereoscopic", "false");
-            queryCollection.Add("sweaudio", "false");
-            queryCollection.Add("swesub", "false");
-            queryCollection.Add("watchview", "false");
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-                queryCollection.Add("categories[]", cat);
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-            var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
-
-            try
-            {
-                //var json = JArray.Parse(results.Content);
-                dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
-                foreach (var row in json)
-                {
-                    var release = new ReleaseInfo();
-                    var descriptions = new List<string>();
-                    var tags = new List<string>();
-
-                    release.MinimumRatio = 1.1;
-                    release.MinimumSeedTime = 48 * 60 * 60;
-                    release.Title = row.name;
-                    release.Category = MapTrackerCatToNewznab(row.category.ToString());
-                    release.Size = row.size;
-                    release.Seeders = row.seeders;
-                    release.Peers = row.leechers + release.Seeders;
-                    release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
-                    release.Files = row.numfiles;
-                    release.Grabs = row.times_completed;
-
-                    release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
-                    release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
-
-                    if (row.frileech == 1)
-                        release.DownloadVolumeFactor = 0;
-                    else
-                        release.DownloadVolumeFactor = 1;
-                    release.UploadVolumeFactor = 1;
-
-                    if (!string.IsNullOrWhiteSpace(row.customcover.ToString()))
-                        release.BannerUrl = new Uri(SiteLink + row.customcover);
-
-                    if (row.imdbid2 != null && row.imdbid2.ToString().StartsWith("tt"))
-                    { 
-                        release.Imdb = ParseUtil.CoerceLong(row.imdbid2.ToString().Substring(2));
-                        descriptions.Add("Title: " + row.title);
-                        descriptions.Add("Year: " + row.year);
-                        descriptions.Add("Genres: " + row.genres);
-                        descriptions.Add("Tagline: " + row.tagline);
-                        descriptions.Add("Cast: " + row.cast);
-                        descriptions.Add("Rating: " + row.rating);
-                        descriptions.Add("Plot: " + row.plot);
-
-                        release.BannerUrl = new Uri(SiteLink + "img/imdb/" + row.imdbid2 + ".jpg");
-                    }
-
-                    if ((int)row.p2p == 1)
-                        tags.Add("P2P");
-                    if ((int)row.pack == 1)
-                        tags.Add("Pack");
-                    if ((int)row.reqid != 0)
-                        tags.Add("Request");
-                    if ((int)row.sweaudio != 0)
-                        tags.Add("Swedish audio");
-                    if ((int)row.swesub != 0)
-                        tags.Add("Swedish subtitles");
-
-                    if (tags.Count > 0)
-                        descriptions.Add("Tags: " + string.Join(", ", tags));
-
-                    var preDate = row.preDate.ToString();
-                    if (!string.IsNullOrWhiteSpace(preDate) && preDate != "1970-01-01 01:00:00")
-                        descriptions.Add("PRE: " + preDate);
-
-                    descriptions.Add("Section: " + row.section);
-
-                    release.Description = string.Join("<br>\n", descriptions);
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
+            queryCollection.Add("password", configData.Password.Value);
+
+            var loginUrl = LoginUrl + "?" + queryCollection.GetQueryString();
+            var loginResult = await RequestStringWithCookies(loginUrl, null, SiteLink);
+
+            await ConfigureIfOK(loginResult.Cookies, loginResult.Content.Contains("\"user\""), () =>
+            {
+                throw new ExceptionWithConfigData(loginResult.Content, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+            var queryCollection = new NameValueCollection();
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+
+            queryCollection.Add("extendedSearch", "false");
+            queryCollection.Add("freeleech", "false");
+            queryCollection.Add("index", "0");
+            queryCollection.Add("limit", "100");
+            queryCollection.Add("order", "desc");
+            queryCollection.Add("page", "search");
+            if (query.ImdbID != null)
+                queryCollection.Add("searchText", query.ImdbID);
+            else
+                queryCollection.Add("searchText", searchString);
+            queryCollection.Add("sort", "d");
+            queryCollection.Add("section", "all");
+            queryCollection.Add("stereoscopic", "false");
+            queryCollection.Add("sweaudio", "false");
+            queryCollection.Add("swesub", "false");
+            queryCollection.Add("watchview", "false");
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+                queryCollection.Add("categories[]", cat);
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+            var results = await RequestStringWithCookies(searchUrl, null, SiteLink);
+
+            try
+            {
+                //var json = JArray.Parse(results.Content);
+                dynamic json = JsonConvert.DeserializeObject<dynamic>(results.Content);
+                foreach (var row in json)
+                {
+                    var release = new ReleaseInfo();
+                    var descriptions = new List<string>();
+                    var tags = new List<string>();
+
+                    release.MinimumRatio = 1.1;
+                    release.MinimumSeedTime = 48 * 60 * 60;
+                    release.Title = row.name;
+                    release.Category = MapTrackerCatToNewznab(row.category.ToString());
+                    release.Size = row.size;
+                    release.Seeders = row.seeders;
+                    release.Peers = row.leechers + release.Seeders;
+                    release.PublishDate = DateTime.ParseExact(row.added.ToString() + " +01:00", "yyyy-MM-dd HH:mm:ss zzz", CultureInfo.InvariantCulture);
+                    release.Files = row.numfiles;
+                    release.Grabs = row.times_completed;
+
+                    release.Comments = new Uri(SiteLink + "torrent/" + row.id.ToString() + "/");
+                    release.Link = new Uri(SiteLink + "api/v1/torrents/download/" + row.id.ToString());
+
+                    if (row.frileech == 1)
+                        release.DownloadVolumeFactor = 0;
+                    else
+                        release.DownloadVolumeFactor = 1;
+                    release.UploadVolumeFactor = 1;
+
+                    if (!string.IsNullOrWhiteSpace(row.customcover.ToString()))
+                        release.BannerUrl = new Uri(SiteLink + row.customcover);
+
+                    if (row.imdbid2 != null && row.imdbid2.ToString().StartsWith("tt"))
+                    { 
+                        release.Imdb = ParseUtil.CoerceLong(row.imdbid2.ToString().Substring(2));
+                        descriptions.Add("Title: " + row.title);
+                        descriptions.Add("Year: " + row.year);
+                        descriptions.Add("Genres: " + row.genres);
+                        descriptions.Add("Tagline: " + row.tagline);
+                        descriptions.Add("Cast: " + row.cast);
+                        descriptions.Add("Rating: " + row.rating);
+                        descriptions.Add("Plot: " + row.plot);
+
+                        release.BannerUrl = new Uri(SiteLink + "img/imdb/" + row.imdbid2 + ".jpg");
+                    }
+
+                    if ((int)row.p2p == 1)
+                        tags.Add("P2P");
+                    if ((int)row.pack == 1)
+                        tags.Add("Pack");
+                    if ((int)row.reqid != 0)
+                        tags.Add("Request");
+                    if ((int)row.sweaudio != 0)
+                        tags.Add("Swedish audio");
+                    if ((int)row.swesub != 0)
+                        tags.Add("Swedish subtitles");
+
+                    if (tags.Count > 0)
+                        descriptions.Add("Tags: " + string.Join(", ", tags));
+
+                    var preDate = row.preDate.ToString();
+                    if (!string.IsNullOrWhiteSpace(preDate) && preDate != "1970-01-01 01:00:00")
+                        descriptions.Add("PRE: " + preDate);
+
+                    descriptions.Add("Section: " + row.section);
+
+                    release.Description = string.Join("<br>\n", descriptions);
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/T411.cs b/src/Jackett/Indexers/T411.cs
index 868be08ba13c251dd22860b9d005cb92fa32a75e..cb5470a662945f7b9baf4b55e4ee50cb221a5420 100644
--- a/src/Jackett/Indexers/T411.cs
+++ b/src/Jackett/Indexers/T411.cs
@@ -1,278 +1,278 @@
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-
-namespace Jackett.Indexers
-{
-    public class T411 : BaseIndexer, IIndexer
-    {
-        const string ApiUrl = "https://api.t411.ai";
-        const string AuthUrl = ApiUrl + "/auth";
-        const string SearchUrl = ApiUrl + "/torrents/search/";
-        const string TermsUrl = ApiUrl + "/terms/tree";
-        const string DownloadUrl = ApiUrl + "/torrents/download/";
-        private string CommentsUrl { get { return SiteLink + "torrents/"; } }
-
-        new ConfigurationDataLoginTokin configData
-        {
-            get { return (ConfigurationDataLoginTokin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        private Dictionary<int, List<int>> _mediaCategoryMapping = new Dictionary<int, List<int>>();
-
-        public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
-            : base(name: "T411",
-                description: "French Torrent Tracker",
-                link: "https://t411.ai/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataLoginTokin())
-        {
-            Encoding = Encoding.UTF8;
-            Type = "semi-private";
-            Language = "fr-fr";
-
-            // 210, FilmVidéo
-            AddCategoryMapping(210, 402, TorznabCatType.Movies, "Vidéoclips");
-            AddCategoryMapping(210, 433, TorznabCatType.TV, "Série TV");
-            AddCategoryMapping(210, 455, TorznabCatType.TVAnime, "Animation");
-            AddCategoryMapping(210, 631, TorznabCatType.Movies, "Film");
-            AddCategoryMapping(210, 633, TorznabCatType.Movies, "Concert");
-            AddCategoryMapping(210, 634, TorznabCatType.TVDocumentary, "Documentaire");
-            AddCategoryMapping(210, 635, TorznabCatType.TV, "Spectacle");
-            AddCategoryMapping(210, 636, TorznabCatType.TVSport, "Sport");
-            AddCategoryMapping(210, 637, TorznabCatType.TVAnime, "Animation Série");
-            AddCategoryMapping(210, 639, TorznabCatType.TV, "Emission TV");
-
-            // 233, Application
-            AddCategoryMapping(233, 234, TorznabCatType.PC, "Linux");
-            AddCategoryMapping(233, 235, TorznabCatType.PCMac, "MacOS");
-            AddCategoryMapping(233, 236, TorznabCatType.PC, "Windows");
-            AddCategoryMapping(233, 625, TorznabCatType.PCPhoneOther, "Smartphone");
-            AddCategoryMapping(233, 627, TorznabCatType.PCPhoneOther, "Tablette");
-            AddCategoryMapping(233, 629, TorznabCatType.PC, "Autre");
-            AddCategoryMapping(233, 638, TorznabCatType.PC, "Formation");
-
-            // 395, Audio
-            AddCategoryMapping(395, 400, TorznabCatType.Audio, "Karaoke");
-            AddCategoryMapping(395, 403, TorznabCatType.Audio, "Samples");
-            AddCategoryMapping(395, 623, TorznabCatType.Audio, "Musique");
-            AddCategoryMapping(395, 642, TorznabCatType.Audio, "Podcast Radio");
-
-            // 404, eBook
-            AddCategoryMapping(404, 405, TorznabCatType.Books, "Audio");
-            AddCategoryMapping(404, 406, TorznabCatType.Books, "Bds");
-            AddCategoryMapping(404, 407, TorznabCatType.Books, "Comics");
-            AddCategoryMapping(404, 408, TorznabCatType.Books, "Livres");
-            AddCategoryMapping(404, 409, TorznabCatType.Books, "Mangas");
-            AddCategoryMapping(404, 410, TorznabCatType.Books, "Presse");
-
-            // 456, xXx
-            AddCategoryMapping(456, 461, TorznabCatType.XXX, "eBooks");
-            AddCategoryMapping(456, 462, TorznabCatType.XXX, "Jeux vidéo");
-            AddCategoryMapping(456, 632, TorznabCatType.XXX, "Video");
-            AddCategoryMapping(456, 641, TorznabCatType.XXX, "Animation");
-
-            // 624, Jeu vidéo
-            AddCategoryMapping(624, 239, TorznabCatType.PCGames, "Linux");
-            AddCategoryMapping(624, 245, TorznabCatType.PCMac, "MacOS");
-            AddCategoryMapping(624, 246, TorznabCatType.PCGames, "Windows");
-            AddCategoryMapping(624, 307, TorznabCatType.ConsoleNDS, "Nintendo");
-            AddCategoryMapping(624, 308, TorznabCatType.ConsolePS4, "Sony");
-            AddCategoryMapping(624, 309, TorznabCatType.ConsoleXbox, "Microsoft");
-            AddCategoryMapping(624, 626, TorznabCatType.PCPhoneOther, "Smartphone");
-            AddCategoryMapping(624, 628, TorznabCatType.PCPhoneOther, "Tablette");
-            AddCategoryMapping(624, 630, TorznabCatType.ConsoleOther, "Autre");
-        }
-
-        private void AddCategoryMapping(int trackerMediaCategory, int trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
-        {
-            AddCategoryMapping(trackerCategory, newznabCategory, trackerCategoryDesc);
-            if (!_mediaCategoryMapping.ContainsKey(trackerMediaCategory))
-                _mediaCategoryMapping.Add(trackerMediaCategory, new List<int>());
-            _mediaCategoryMapping[trackerMediaCategory].Add(trackerCategory);
-        }
-
-        private KeyValuePair<int, List<int>> GetCategoryFromSubCat(int subCategory)
-        {
-            try
-            {
-                return _mediaCategoryMapping.First(pair => pair.Value.Contains(subCategory));
-            }
-            catch (Exception)
-            {
-                return new KeyValuePair<int, List<int>>(0, new List<int>() { 0 }); //If the provided category does not exist, we return 0 (ALL)
-            }
-        }
-
-        async Task<string> GetAuthToken(bool forceFetch = false)
-        {
-            if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
-            {
-                return configData.ApiToken.Value;
-            }
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value }
-            };
-
-            var response = await PostDataWithCookies(AuthUrl, pairs);
-            var responseContent = response.Content;
-            var jsonResponse = JObject.Parse(responseContent);
-            if (jsonResponse["error"] != null)
-            {
-                throw new ApplicationException((string)jsonResponse["error"]);
-            }
-            configData.ApiToken.Value = (string)jsonResponse["token"];
-            configData.LastTokenFetchDateTime = DateTime.Now;
-            return configData.ApiToken.Value;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            configData.LoadValuesFromJson(configJson);
-
-            Exception tokenFetchEx = null;
-            try
-            {
-                await GetAuthToken(true);
-            }
-            catch (Exception ex)
-            {
-                tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
-            }
-
-            await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
-            {
-                throw tokenFetchEx;
-            });
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            // API doesn't support getting the latest torrents, searching for the empty string will cause an error and all torrents returned
-            var searchUrl = SearchUrl + HttpUtility.UrlEncode(query.SanitizedSearchTerm).Replace("+", "%20");
-            searchUrl += "?offset=0&limit=200&cat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Key;
-
-            // handle special term search for tvsearch
-            var queryStringOverride = query.SanitizedSearchTerm;
-            switch (query.QueryType)
-            {
-                case "tvsearch":
-                    // T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
-                    // So here we take LastOrDefault from the category ids, so if the query specify an animation tv serie, we select the correct id.
-                    searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.LastOrDefault();
-                    if (query.Season >= 1 && query.Season <= 30)
-                    {
-                        var seasonTermValue = 967 + query.Season;
-                        searchUrl += "&term[45][]=" + seasonTermValue;
-                        queryStringOverride += " " + query.Season;
-                    }
-
-                    if (query.Episode != null)
-                    {
-                        int episodeInt;
-                        int episodeCategoryOffset = 936;
-                        ParseUtil.TryCoerceInt(query.Episode, out episodeInt);
-                        if (episodeInt >= 1 && episodeInt <= 8)
-                            episodeCategoryOffset = 936;
-                        else if (episodeInt >= 9 && episodeInt <= 30)
-                            episodeCategoryOffset = 937;
-                        else if (episodeInt >= 31)
-                            episodeCategoryOffset = 1057;
-                        searchUrl += "&term[46][]=" + (episodeCategoryOffset + episodeInt);
-                        queryStringOverride += " " + query.Episode;
-                    }
-                    break;
-                case "movie":
-                    // T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
-                    // So here we take FirstOrDefault from the category ids, so if the query specify an animation movie, we select the correct id.
-                    searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.FirstOrDefault();
-                    break;
-            }
-
-            var headers = new Dictionary<string, string>();
-            headers.Add("Authorization", await GetAuthToken());
-
-            var response = await RequestStringWithCookies(searchUrl, null, null, headers);
-            var results = response.Content;
-
-            var jsonStart = results.IndexOf('{');
-            var jsonLength = results.Length - jsonStart;
-            var jsonResult = JObject.Parse(results.Substring(jsonStart));
-            try
-            {
-                var items = (JArray)jsonResult["torrents"];
-                foreach (var item in items)
-                {
-                    if (item.GetType() == typeof(JValue))
-                    {
-                        logger.Debug(string.Format("{0}: skipping torrent ID {1} (pending release without details)", ID, item.ToString()));
-                        continue;
-                    }
-                    var release = new ReleaseInfo();
-
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-                    release.DownloadVolumeFactor = 0;
-                    release.DownloadVolumeFactor = 1;
-                    var torrentId = (string)item["id"];
-                    release.Link = new Uri(DownloadUrl + torrentId);
-                    release.Title = (string)item["name"];
-
-                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title, null, queryStringOverride))
-                        continue;
-
-                    if ((string)item["isVerified"] == "1")
-                        release.Description = "Verified";
-                    release.Comments = new Uri(CommentsUrl + (string)item["rewritename"]);
-                    release.Guid = release.Comments;
-
-                    var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
-                    release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();
-
-                    release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
-                    release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;
-                    release.Size = ParseUtil.CoerceLong((string)item["size"]);
-                    release.Category = MapTrackerCatToNewznab((string)item["category"]);
-                    release.Grabs = ParseUtil.CoerceLong((string)item["times_completed"]);
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results, ex);
-            }
-            return releases;
-        }
-
-        public override async Task<byte[]> Download(Uri link)
-        {
-            var headers = new Dictionary<string, string>();
-            headers.Add("Authorization", await GetAuthToken());
-
-            var response = await RequestBytesWithCookies(link.AbsoluteUri, null, RequestType.GET, null, null, headers);
-            return response.Content;
-        }
-    }
-}
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+
+namespace Jackett.Indexers
+{
+    public class T411 : BaseIndexer, IIndexer
+    {
+        const string ApiUrl = "https://api.t411.ai";
+        const string AuthUrl = ApiUrl + "/auth";
+        const string SearchUrl = ApiUrl + "/torrents/search/";
+        const string TermsUrl = ApiUrl + "/terms/tree";
+        const string DownloadUrl = ApiUrl + "/torrents/download/";
+        private string CommentsUrl { get { return SiteLink + "torrents/"; } }
+
+        new ConfigurationDataLoginTokin configData
+        {
+            get { return (ConfigurationDataLoginTokin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        private Dictionary<int, List<int>> _mediaCategoryMapping = new Dictionary<int, List<int>>();
+
+        public T411(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
+            : base(name: "T411",
+                description: "French Torrent Tracker",
+                link: "https://t411.ai/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataLoginTokin())
+        {
+            Encoding = Encoding.UTF8;
+            Type = "semi-private";
+            Language = "fr-fr";
+
+            // 210, FilmVidéo
+            AddCategoryMapping(210, 402, TorznabCatType.Movies, "Vidéoclips");
+            AddCategoryMapping(210, 433, TorznabCatType.TV, "Série TV");
+            AddCategoryMapping(210, 455, TorznabCatType.TVAnime, "Animation");
+            AddCategoryMapping(210, 631, TorznabCatType.Movies, "Film");
+            AddCategoryMapping(210, 633, TorznabCatType.Movies, "Concert");
+            AddCategoryMapping(210, 634, TorznabCatType.TVDocumentary, "Documentaire");
+            AddCategoryMapping(210, 635, TorznabCatType.TV, "Spectacle");
+            AddCategoryMapping(210, 636, TorznabCatType.TVSport, "Sport");
+            AddCategoryMapping(210, 637, TorznabCatType.TVAnime, "Animation Série");
+            AddCategoryMapping(210, 639, TorznabCatType.TV, "Emission TV");
+
+            // 233, Application
+            AddCategoryMapping(233, 234, TorznabCatType.PC, "Linux");
+            AddCategoryMapping(233, 235, TorznabCatType.PCMac, "MacOS");
+            AddCategoryMapping(233, 236, TorznabCatType.PC, "Windows");
+            AddCategoryMapping(233, 625, TorznabCatType.PCPhoneOther, "Smartphone");
+            AddCategoryMapping(233, 627, TorznabCatType.PCPhoneOther, "Tablette");
+            AddCategoryMapping(233, 629, TorznabCatType.PC, "Autre");
+            AddCategoryMapping(233, 638, TorznabCatType.PC, "Formation");
+
+            // 395, Audio
+            AddCategoryMapping(395, 400, TorznabCatType.Audio, "Karaoke");
+            AddCategoryMapping(395, 403, TorznabCatType.Audio, "Samples");
+            AddCategoryMapping(395, 623, TorznabCatType.Audio, "Musique");
+            AddCategoryMapping(395, 642, TorznabCatType.Audio, "Podcast Radio");
+
+            // 404, eBook
+            AddCategoryMapping(404, 405, TorznabCatType.Books, "Audio");
+            AddCategoryMapping(404, 406, TorznabCatType.Books, "Bds");
+            AddCategoryMapping(404, 407, TorznabCatType.Books, "Comics");
+            AddCategoryMapping(404, 408, TorznabCatType.Books, "Livres");
+            AddCategoryMapping(404, 409, TorznabCatType.Books, "Mangas");
+            AddCategoryMapping(404, 410, TorznabCatType.Books, "Presse");
+
+            // 456, xXx
+            AddCategoryMapping(456, 461, TorznabCatType.XXX, "eBooks");
+            AddCategoryMapping(456, 462, TorznabCatType.XXX, "Jeux vidéo");
+            AddCategoryMapping(456, 632, TorznabCatType.XXX, "Video");
+            AddCategoryMapping(456, 641, TorznabCatType.XXX, "Animation");
+
+            // 624, Jeu vidéo
+            AddCategoryMapping(624, 239, TorznabCatType.PCGames, "Linux");
+            AddCategoryMapping(624, 245, TorznabCatType.PCMac, "MacOS");
+            AddCategoryMapping(624, 246, TorznabCatType.PCGames, "Windows");
+            AddCategoryMapping(624, 307, TorznabCatType.ConsoleNDS, "Nintendo");
+            AddCategoryMapping(624, 308, TorznabCatType.ConsolePS4, "Sony");
+            AddCategoryMapping(624, 309, TorznabCatType.ConsoleXbox, "Microsoft");
+            AddCategoryMapping(624, 626, TorznabCatType.PCPhoneOther, "Smartphone");
+            AddCategoryMapping(624, 628, TorznabCatType.PCPhoneOther, "Tablette");
+            AddCategoryMapping(624, 630, TorznabCatType.ConsoleOther, "Autre");
+        }
+
+        private void AddCategoryMapping(int trackerMediaCategory, int trackerCategory, TorznabCategory newznabCategory, string trackerCategoryDesc = null)
+        {
+            AddCategoryMapping(trackerCategory, newznabCategory, trackerCategoryDesc);
+            if (!_mediaCategoryMapping.ContainsKey(trackerMediaCategory))
+                _mediaCategoryMapping.Add(trackerMediaCategory, new List<int>());
+            _mediaCategoryMapping[trackerMediaCategory].Add(trackerCategory);
+        }
+
+        private KeyValuePair<int, List<int>> GetCategoryFromSubCat(int subCategory)
+        {
+            try
+            {
+                return _mediaCategoryMapping.First(pair => pair.Value.Contains(subCategory));
+            }
+            catch (Exception)
+            {
+                return new KeyValuePair<int, List<int>>(0, new List<int>() { 0 }); //If the provided category does not exist, we return 0 (ALL)
+            }
+        }
+
+        async Task<string> GetAuthToken(bool forceFetch = false)
+        {
+            if (!forceFetch && configData.LastTokenFetchDateTime > DateTime.Now - TimeSpan.FromHours(48))
+            {
+                return configData.ApiToken.Value;
+            }
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value }
+            };
+
+            var response = await PostDataWithCookies(AuthUrl, pairs);
+            var responseContent = response.Content;
+            var jsonResponse = JObject.Parse(responseContent);
+            if (jsonResponse["error"] != null)
+            {
+                throw new ApplicationException((string)jsonResponse["error"]);
+            }
+            configData.ApiToken.Value = (string)jsonResponse["token"];
+            configData.LastTokenFetchDateTime = DateTime.Now;
+            return configData.ApiToken.Value;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            configData.LoadValuesFromJson(configJson);
+
+            Exception tokenFetchEx = null;
+            try
+            {
+                await GetAuthToken(true);
+            }
+            catch (Exception ex)
+            {
+                tokenFetchEx = new ExceptionWithConfigData(ex.Message, configData);
+            }
+
+            await ConfigureIfOK(string.Empty, tokenFetchEx == null, () =>
+            {
+                throw tokenFetchEx;
+            });
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            // API doesn't support getting the latest torrents, searching for the empty string will cause an error and all torrents returned
+            var searchUrl = SearchUrl + HttpUtility.UrlEncode(query.SanitizedSearchTerm).Replace("+", "%20");
+            searchUrl += "?offset=0&limit=200&cat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Key;
+
+            // handle special term search for tvsearch
+            var queryStringOverride = query.SanitizedSearchTerm;
+            switch (query.QueryType)
+            {
+                case "tvsearch":
+                    // T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
+                    // So here we take LastOrDefault from the category ids, so if the query specify an animation tv serie, we select the correct id.
+                    searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.LastOrDefault();
+                    if (query.Season >= 1 && query.Season <= 30)
+                    {
+                        var seasonTermValue = 967 + query.Season;
+                        searchUrl += "&term[45][]=" + seasonTermValue;
+                        queryStringOverride += " " + query.Season;
+                    }
+
+                    if (query.Episode != null)
+                    {
+                        int episodeInt;
+                        int episodeCategoryOffset = 936;
+                        ParseUtil.TryCoerceInt(query.Episode, out episodeInt);
+                        if (episodeInt >= 1 && episodeInt <= 8)
+                            episodeCategoryOffset = 936;
+                        else if (episodeInt >= 9 && episodeInt <= 30)
+                            episodeCategoryOffset = 937;
+                        else if (episodeInt >= 31)
+                            episodeCategoryOffset = 1057;
+                        searchUrl += "&term[46][]=" + (episodeCategoryOffset + episodeInt);
+                        queryStringOverride += " " + query.Episode;
+                    }
+                    break;
+                case "movie":
+                    // T411 make the difference beetween Animation Movies and TV Animation Series, while Torznab does not.
+                    // So here we take FirstOrDefault from the category ids, so if the query specify an animation movie, we select the correct id.
+                    searchUrl += "&subcat=" + GetCategoryFromSubCat(query.Categories.FirstOrDefault()).Value.FirstOrDefault();
+                    break;
+            }
+
+            var headers = new Dictionary<string, string>();
+            headers.Add("Authorization", await GetAuthToken());
+
+            var response = await RequestStringWithCookies(searchUrl, null, null, headers);
+            var results = response.Content;
+
+            var jsonStart = results.IndexOf('{');
+            var jsonLength = results.Length - jsonStart;
+            var jsonResult = JObject.Parse(results.Substring(jsonStart));
+            try
+            {
+                var items = (JArray)jsonResult["torrents"];
+                foreach (var item in items)
+                {
+                    if (item.GetType() == typeof(JValue))
+                    {
+                        logger.Debug(string.Format("{0}: skipping torrent ID {1} (pending release without details)", ID, item.ToString()));
+                        continue;
+                    }
+                    var release = new ReleaseInfo();
+
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+                    release.DownloadVolumeFactor = 0;
+                    release.DownloadVolumeFactor = 1;
+                    var torrentId = (string)item["id"];
+                    release.Link = new Uri(DownloadUrl + torrentId);
+                    release.Title = (string)item["name"];
+
+                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title, null, queryStringOverride))
+                        continue;
+
+                    if ((string)item["isVerified"] == "1")
+                        release.Description = "Verified";
+                    release.Comments = new Uri(CommentsUrl + (string)item["rewritename"]);
+                    release.Guid = release.Comments;
+
+                    var dateUtc = DateTime.ParseExact((string)item["added"], "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
+                    release.PublishDate = DateTime.SpecifyKind(dateUtc, DateTimeKind.Utc).ToLocalTime();
+
+                    release.Seeders = ParseUtil.CoerceInt((string)item["seeders"]);
+                    release.Peers = ParseUtil.CoerceInt((string)item["leechers"]) + release.Seeders;
+                    release.Size = ParseUtil.CoerceLong((string)item["size"]);
+                    release.Category = MapTrackerCatToNewznab((string)item["category"]);
+                    release.Grabs = ParseUtil.CoerceLong((string)item["times_completed"]);
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results, ex);
+            }
+            return releases;
+        }
+
+        public override async Task<byte[]> Download(Uri link)
+        {
+            var headers = new Dictionary<string, string>();
+            headers.Add("Authorization", await GetAuthToken());
+
+            var response = await RequestBytesWithCookies(link.AbsoluteUri, null, RequestType.GET, null, null, headers);
+            return response.Content;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/TVChaosUK.cs b/src/Jackett/Indexers/TVChaosUK.cs
index 2230593354b135d863d172469bab15eea51c3122..421910b77d6abd6541e1de9a84eeab2dd9bfdf04 100644
--- a/src/Jackett/Indexers/TVChaosUK.cs
+++ b/src/Jackett/Indexers/TVChaosUK.cs
@@ -202,7 +202,7 @@ namespace Jackett.Indexers
                 // The TVChaos UK search requires an exact match of the search string.
                 // But it seems like they just send the unfiltered search to the SQL server in a like query (LIKE '%$searchstring%').
                 // So we replace any whitespace/special character with % to make the search more usable.
-                Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
+                Regex ReplaceRegex = new Regex("[^a-zA-Z0-9]+");
                 searchString = ReplaceRegex.Replace(searchString, "%");
 
                 var searchParams = new Dictionary<string, string> {
@@ -214,11 +214,11 @@ namespace Jackett.Indexers
                 };
 
                 var searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams);
-                if (searchPage.IsRedirect)
-                {
-                    // re-login
-                    await ApplyConfiguration(null);
-                    searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams);
+                if (searchPage.IsRedirect)
+                {
+                    // re-login
+                    await ApplyConfiguration(null);
+                    searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams);
                 }
 
                 try
@@ -258,18 +258,18 @@ namespace Jackett.Indexers
                         // If its not apps or audio we can only mark as general TV
                         if (release.Category.Count() == 0)
                             release.Category.Add(5030);
-
-                        var grabs = qRow.Find("td:nth-child(6)").Text();
-                        release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                        if (qRow.Find("img[alt*=\"Free Torrent\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0;
-                        else
-                            release.DownloadVolumeFactor = 1;
-
-                        if (qRow.Find("img[alt*=\"x2 Torrent\"]").Length >= 1)
-                            release.UploadVolumeFactor = 2;
-                        else
+
+                        var grabs = qRow.Find("td:nth-child(6)").Text();
+                        release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                        if (qRow.Find("img[alt*=\"Free Torrent\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0;
+                        else
+                            release.DownloadVolumeFactor = 1;
+
+                        if (qRow.Find("img[alt*=\"x2 Torrent\"]").Length >= 1)
+                            release.UploadVolumeFactor = 2;
+                        else
                             release.UploadVolumeFactor = 1;
 
                         releases.Add(release);
diff --git a/src/Jackett/Indexers/TVVault.cs b/src/Jackett/Indexers/TVVault.cs
index 6a3776ce83b63bf8a2356b728153d7aaa14f32f5..82a7488ef477f1e1c23cee90e9378244c518ad57 100644
--- a/src/Jackett/Indexers/TVVault.cs
+++ b/src/Jackett/Indexers/TVVault.cs
@@ -9,10 +9,10 @@ using System.Collections.Generic;
 using System;
 using System.Text;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using AngleSharp.Parser.Html;
-using System.Text.RegularExpressions;
-
+using System.Collections.Specialized;
+using AngleSharp.Parser.Html;
+using System.Text.RegularExpressions;
+
 namespace Jackett.Indexers
 {
     public class TVVault : BaseIndexer, IIndexer
@@ -58,90 +58,90 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
 
-        private string StripSearchString(string term)
-        {
-            // Search does not support searching with episode numbers so strip it if we have one
-            // Ww AND filter the result later to archive the proper result
-            term = Regex.Replace(term, @"[S|E]\d\d", string.Empty);
-            return term.Trim();
+        private string StripSearchString(string term)
+        {
+            // Search does not support searching with episode numbers so strip it if we have one
+            // Ww AND filter the result later to archive the proper result
+            term = Regex.Replace(term, @"[S|E]\d\d", string.Empty);
+            return term.Trim();
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("searchstr", StripSearchString(searchString));
-            queryCollection.Add("order_by", "s3");
-            queryCollection.Add("order_way", "desc");
-            queryCollection.Add("disablegrouping", "1");
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("searchstr", StripSearchString(searchString));
+            queryCollection.Add("order_by", "s3");
+            queryCollection.Add("order_way", "desc");
+            queryCollection.Add("disablegrouping", "1");
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
             var results = await RequestStringWithCookies(searchUrl);
             try
             {
                 string RowsSelector = "table.torrent_table > tbody > tr.torrent";
 
-                var SearchResultParser = new HtmlParser();
+                var SearchResultParser = new HtmlParser();
                 var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                foreach (var Row in Rows)
+                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                foreach (var Row in Rows)
                 {
                     var release = new ReleaseInfo();
 
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 0;
-
-                    var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
-                    var DescStr = qDetailsLink.NextSibling;
-                    var Files = Row.QuerySelector("td:nth-child(3)");
-                    var Added = Row.QuerySelector("td:nth-child(4)");
-                    var Size = Row.QuerySelector("td:nth-child(5)").FirstChild;
-                    var Grabs = Row.QuerySelector("td:nth-child(6)");
-                    var Seeders = Row.QuerySelector("td:nth-child(7)");
-                    var Leechers = Row.QuerySelector("td:nth-child(8)");
-                    var FreeLeech = Row.QuerySelector("strong.freeleech_normal");
-
-                    var TorrentIdParts = qDetailsLink.GetAttribute("href").Split('=');
-                    var TorrentId = TorrentIdParts[TorrentIdParts.Length - 1];
-                    var DLLink = "torrents.php?action=download&id=" + TorrentId.ToString();
-
-                    release.Description = DescStr.TextContent.Trim();
-                    release.Title = qDetailsLink.TextContent + " " + release.Description;
-                    release.PublishDate = DateTimeUtil.FromTimeAgo(Added.TextContent);
-                    release.Category = new List<int> { TvCategoryParser.ParseTvShowQuality(release.Description) };
-
-                    release.Link = new Uri(SiteLink + DLLink);
-                    release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
-                    release.Guid = release.Link;
-
-                    release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
-                    release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
-                    release.Size = ReleaseInfo.GetBytes(Size.TextContent);
-                    release.Grabs = ReleaseInfo.GetBytes(Grabs.TextContent);
-                    release.Files = ReleaseInfo.GetBytes(Files.TextContent);
-
-                    if (FreeLeech != null)
-                        release.DownloadVolumeFactor = 0;
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 0;
+
+                    var qDetailsLink = Row.QuerySelector("a[href^=\"torrents.php?id=\"]");
+                    var DescStr = qDetailsLink.NextSibling;
+                    var Files = Row.QuerySelector("td:nth-child(3)");
+                    var Added = Row.QuerySelector("td:nth-child(4)");
+                    var Size = Row.QuerySelector("td:nth-child(5)").FirstChild;
+                    var Grabs = Row.QuerySelector("td:nth-child(6)");
+                    var Seeders = Row.QuerySelector("td:nth-child(7)");
+                    var Leechers = Row.QuerySelector("td:nth-child(8)");
+                    var FreeLeech = Row.QuerySelector("strong.freeleech_normal");
+
+                    var TorrentIdParts = qDetailsLink.GetAttribute("href").Split('=');
+                    var TorrentId = TorrentIdParts[TorrentIdParts.Length - 1];
+                    var DLLink = "torrents.php?action=download&id=" + TorrentId.ToString();
+
+                    release.Description = DescStr.TextContent.Trim();
+                    release.Title = qDetailsLink.TextContent + " " + release.Description;
+                    release.PublishDate = DateTimeUtil.FromTimeAgo(Added.TextContent);
+                    release.Category = new List<int> { TvCategoryParser.ParseTvShowQuality(release.Description) };
+
+                    release.Link = new Uri(SiteLink + DLLink);
+                    release.Comments = new Uri(SiteLink + qDetailsLink.GetAttribute("href"));
+                    release.Guid = release.Link;
+
+                    release.Seeders = ParseUtil.CoerceInt(Seeders.TextContent);
+                    release.Peers = ParseUtil.CoerceInt(Leechers.TextContent) + release.Seeders;
+                    release.Size = ReleaseInfo.GetBytes(Size.TextContent);
+                    release.Grabs = ReleaseInfo.GetBytes(Grabs.TextContent);
+                    release.Files = ReleaseInfo.GetBytes(Files.TextContent);
+
+                    if (FreeLeech != null)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
-                }
+                }
             }
             catch (Exception ex)
             {
diff --git a/src/Jackett/Indexers/TehConnection.cs b/src/Jackett/Indexers/TehConnection.cs
index ece1115ef8d79cf37fa81b727f9f24bd36df9d46..481d5549aacf99c3a2bdef41ecfc2422bad8bce8 100644
--- a/src/Jackett/Indexers/TehConnection.cs
+++ b/src/Jackett/Indexers/TehConnection.cs
@@ -115,9 +115,9 @@ namespace Jackett.Indexers
             {
                 movieListSearchUrl = string.Format("{0}?action=basic&searchstr={1}", SearchUrl, HttpUtility.UrlEncode(query.GetQueryString()));
             }
-            else
-            {
-                movieListSearchUrl = SearchUrl;
+            else
+            {
+                movieListSearchUrl = SearchUrl;
             }
 
             var results = await RequestStringWithCookiesAndRetry(movieListSearchUrl);
@@ -165,10 +165,10 @@ namespace Jackett.Indexers
                         var seeders = ParseUtil.CoerceInt(qRow.Find("img[title='Seeders']").First().Parent().Text().Trim());
                         var peers = ParseUtil.CoerceInt(qRow.Find("img[title='Leechers']").First().Parent().Text().Trim()) + seeders;
                         var CoverElement = dom.Find("div[id='poster'] > a > img");
-                        if (CoverElement.Any())
-                        {
-                            Uri CoverUrl = new Uri(dom.Find("div[id='poster'] > a > img").First().Attr("src").Trim());
-                            release.BannerUrl = CoverUrl;
+                        if (CoverElement.Any())
+                        {
+                            Uri CoverUrl = new Uri(dom.Find("div[id='poster'] > a > img").First().Attr("src").Trim());
+                            release.BannerUrl = CoverUrl;
                         }
                         
                         bool freeleech = qRow.Find("span[class='freeleech']").Length == 1 ? true : false;
@@ -181,9 +181,9 @@ namespace Jackett.Indexers
                             { sizeStr = secondSizeStr.Replace("(", "").Replace(")", "").Trim(); }
                         }
 
-                        if(string.IsNullOrWhiteSpace(title))
-                        {
-                            title = dom.Find("div.title_text").Text() + " - " + qRow.Find("div.details_title > a").Text();
+                        if(string.IsNullOrWhiteSpace(title))
+                        {
+                            title = dom.Find("div.title_text").Text() + " - " + qRow.Find("div.details_title > a").Text();
                         }
                         
 
@@ -203,15 +203,15 @@ namespace Jackett.Indexers
                             release.Imdb = imdb_id;
                         }
 
-                        var files = qRow.Find("div[id^=\"filelist\"] tr").Count()-1;
-                        release.Files = files;
-                        release.Grabs = ParseUtil.CoerceLong(grabs);
-
-                        if (freeleech)
-                            release.DownloadVolumeFactor = 0;
-                        else
-                            release.DownloadVolumeFactor = 1;
-
+                        var files = qRow.Find("div[id^=\"filelist\"] tr").Count()-1;
+                        release.Files = files;
+                        release.Grabs = ParseUtil.CoerceLong(grabs);
+
+                        if (freeleech)
+                            release.DownloadVolumeFactor = 0;
+                        else
+                            release.DownloadVolumeFactor = 1;
+
                         release.UploadVolumeFactor = 1;
 
                         if (configFreeLeechOnly && !freeleech)
diff --git a/src/Jackett/Indexers/TorrentBytes.cs b/src/Jackett/Indexers/TorrentBytes.cs
index 728838cb863039a2ee4443d1da2bb6fbfe3fb903..29df21b67efa719fc8ff425304a454c73084fe12 100644
--- a/src/Jackett/Indexers/TorrentBytes.cs
+++ b/src/Jackett/Indexers/TorrentBytes.cs
@@ -92,8 +92,8 @@ namespace Jackett.Indexers
                 CQ dom = result.Content;
                 var messageEl = dom["td.embedded"].First();
                 var errorMessage = messageEl.Text();
-                if (string.IsNullOrWhiteSpace(errorMessage))
-                    errorMessage = result.Content;
+                if (string.IsNullOrWhiteSpace(errorMessage))
+                    errorMessage = result.Content;
                 throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
@@ -136,10 +136,10 @@ namespace Jackett.Indexers
         {
             var response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
             // On IP change the cookies become invalid, login again and retry
-            if (response.IsRedirect)
-            {
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
+            if (response.IsRedirect)
+            {
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookiesAndRetry(searchUrl, null, BrowseUrl);
             }
 
             var results = response.Content;
@@ -190,11 +190,11 @@ namespace Jackett.Indexers
                     if (grabs != "----")
                         release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (row.Cq().Find("font[color=\"green\"]:contains(F):contains(L)").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (row.Cq().Find("font[color=\"green\"]:contains(F):contains(L)").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/TorrentDay.cs b/src/Jackett/Indexers/TorrentDay.cs
index b67cb81e8d724d67b3b0aa57cbb9acc57144d348..4250ec4a05589a570f77ab5829c71504369fdf40 100644
--- a/src/Jackett/Indexers/TorrentDay.cs
+++ b/src/Jackett/Indexers/TorrentDay.cs
@@ -1,66 +1,66 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
-namespace Jackett.Indexers
-{
-    public class TorrentDay : BaseIndexer, IIndexer
-    {
-        private string StartPageUrl { get { return SiteLink + "login.php"; } }
-        private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        public new string[] AlternativeSiteLinks { get; protected set; } = new string[] {
-            "https://tdonline.org/",
-            "https://secure.torrentday.com/",
-            "https://torrentday.eu/",
-            "https://torrentday.it/",
-            "https://classic.torrentday.com/",
-            "https://www.torrentday.com/",
-            "https://td-update.com/",
-            "https://www.torrentday.me/",
-            "https://www.torrentday.ru/",
-            "https://www.torrentday.com/",
-            "https://www.td.af/",
-        };
-
-        new ConfigurationDataRecaptchaLogin configData
-        {
-            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public TorrentDay(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
-            : base(name: "TorrentDay",
-                description: "TorrentDay",
-                link: "https://torrentday.it/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataRecaptchaLogin())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+
+namespace Jackett.Indexers
+{
+    public class TorrentDay : BaseIndexer, IIndexer
+    {
+        private string StartPageUrl { get { return SiteLink + "login.php"; } }
+        private string LoginUrl { get { return SiteLink + "tak3login.php"; } }
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        public new string[] AlternativeSiteLinks { get; protected set; } = new string[] {
+            "https://tdonline.org/",
+            "https://secure.torrentday.com/",
+            "https://torrentday.eu/",
+            "https://torrentday.it/",
+            "https://classic.torrentday.com/",
+            "https://www.torrentday.com/",
+            "https://td-update.com/",
+            "https://www.torrentday.me/",
+            "https://www.torrentday.ru/",
+            "https://www.torrentday.com/",
+            "https://www.td.af/",
+        };
+
+        new ConfigurationDataRecaptchaLogin configData
+        {
+            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public TorrentDay(IIndexerManagerService i, Logger l, IWebClient wc, IProtectionService ps)
+            : base(name: "TorrentDay",
+                description: "TorrentDay",
+                link: "https://torrentday.it/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataRecaptchaLogin())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
             AddCategoryMapping(29, TorznabCatType.TVAnime); // Anime
             AddCategoryMapping(28, TorznabCatType.PC); // Appz/Packs
             AddCategoryMapping(42, TorznabCatType.AudioAudiobook); // Audio Books
@@ -103,163 +103,163 @@ namespace Jackett.Indexers
             AddCategoryMapping(2, TorznabCatType.TVSD); // TV/XviD
 
             AddCategoryMapping(6, TorznabCatType.XXX); // XXX/Movies
-            AddCategoryMapping(15, TorznabCatType.XXXPacks); // XXX/Packs
-        }
-
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty);
-            if (loginPage.IsRedirect)
-                loginPage = await RequestStringWithCookies(loginPage.RedirectingTo, string.Empty);
-            if (loginPage.IsRedirect)
-                loginPage = await RequestStringWithCookies(loginPage.RedirectingTo, string.Empty);
-            CQ cq = loginPage.Content;
-            var result = this.configData;
-            result.CookieHeader.Value = loginPage.Cookies;
-            result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
-            result.Captcha.Version = "2";
-            return result;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "g-recaptcha-response", configData.Captcha.Value }
-            };
-
-            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
-            {
-                // Cookie was manually supplied
-                CookieHeader = configData.Captcha.Cookie;
-                try
-                {
-                    var results = await PerformQuery(new TorznabQuery());
-                    if (results.Count() == 0)
-                    {
-                        throw new Exception("Your cookie did not work");
-                    }
-
-                    SaveConfig();
-                    IsConfigured = true;
-                    return IndexerConfigurationStatus.Completed;
-                }
-                catch (Exception e)
-                {
-                    IsConfigured = false;
-                    throw new Exception("Your cookie did not work: " + e.Message);
-                }
-            }
-
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var messageEl = dom["#login"];
-                messageEl.Children("form").Remove();
-                var errorMessage = messageEl.Text().Trim();
-
-                if (string.IsNullOrWhiteSpace(errorMessage))
-                {
-                    errorMessage = dom.Text();
-                }
-
-                if (string.IsNullOrWhiteSpace(errorMessage) && result.IsRedirect)
-                {
-                    errorMessage = string.Format("Got a redirect to {0}, please adjust your the alternative link", result.RedirectingTo);
-                }
-
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            var queryUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-
-            if (!string.IsNullOrWhiteSpace(query.ImdbID) && query.ImdbID.ToLower().StartsWith("tt"))
-            {
-                queryCollection.Add("search", query.ImdbID);
-            }
-            else
-            {
-                if (!string.IsNullOrWhiteSpace(searchString))
-                    queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-                queryCollection.Add("c" + cat, "1");
-
-            if (queryCollection.Count > 0)
-                queryUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(queryUrl);
-
-            // Check for being logged out
-            if (results.IsRedirect)
-                if (results.RedirectingTo.Contains("login.php"))
-                    throw new ExceptionWithConfigData("Login failed, please reconfigure the tracker to update the cookies", configData);
-                else
-                    throw new ExceptionWithConfigData(string.Format("Got a redirect to {0}, please adjust your the alternative link", results.RedirectingTo), configData);
-
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom["#torrentTable > tbody > tr.browse"];
-                foreach (var row in rows)
-                {
-                    CQ qRow = row.Cq();
-                    var release = new ReleaseInfo();
-
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 172800;
-                    release.Title = qRow.Find(".torrentName").Text();
-
-                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    release.Guid = new Uri(SiteLink + qRow.Find(".torrentName").Attr("href"));
-                    release.Comments = release.Guid;
-                    release.Link = new Uri(SiteLink + qRow.Find(".dlLinksInfo > a").Attr("href"));
-
-                    var sizeStr = qRow.Find(".sizeInfo").Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    var dateStr = qRow.Find(".ulInfo").Text().Split('|').Last().Trim();
-                    var agoIdx = dateStr.IndexOf("ago");
-                    if (agoIdx > -1)
-                    {
-                        dateStr = dateStr.Substring(0, agoIdx);
-                    }
-                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text());
-                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders;
-
-                    var cat = qRow.Find("td:eq(0) a").First().Attr("href").Split('#')[0].Substring(15);//browse.php?cat=24
-                    release.Category = MapTrackerCatToNewznab(cat);
-
-                    if (qRow.Find("span.flTags").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+            AddCategoryMapping(15, TorznabCatType.XXXPacks); // XXX/Packs
+        }
+
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(StartPageUrl, string.Empty);
+            if (loginPage.IsRedirect)
+                loginPage = await RequestStringWithCookies(loginPage.RedirectingTo, string.Empty);
+            if (loginPage.IsRedirect)
+                loginPage = await RequestStringWithCookies(loginPage.RedirectingTo, string.Empty);
+            CQ cq = loginPage.Content;
+            var result = this.configData;
+            result.CookieHeader.Value = loginPage.Cookies;
+            result.Captcha.SiteKey = cq.Find(".g-recaptcha").Attr("data-sitekey");
+            result.Captcha.Version = "2";
+            return result;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "g-recaptcha-response", configData.Captcha.Value }
+            };
+
+            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
+            {
+                // Cookie was manually supplied
+                CookieHeader = configData.Captcha.Cookie;
+                try
+                {
+                    var results = await PerformQuery(new TorznabQuery());
+                    if (results.Count() == 0)
+                    {
+                        throw new Exception("Your cookie did not work");
+                    }
+
+                    SaveConfig();
+                    IsConfigured = true;
+                    return IndexerConfigurationStatus.Completed;
+                }
+                catch (Exception e)
+                {
+                    IsConfigured = false;
+                    throw new Exception("Your cookie did not work: " + e.Message);
+                }
+            }
+
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, configData.CookieHeader.Value, true, SiteLink, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var messageEl = dom["#login"];
+                messageEl.Children("form").Remove();
+                var errorMessage = messageEl.Text().Trim();
+
+                if (string.IsNullOrWhiteSpace(errorMessage))
+                {
+                    errorMessage = dom.Text();
+                }
+
+                if (string.IsNullOrWhiteSpace(errorMessage) && result.IsRedirect)
+                {
+                    errorMessage = string.Format("Got a redirect to {0}, please adjust your the alternative link", result.RedirectingTo);
+                }
+
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            var queryUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+
+            if (!string.IsNullOrWhiteSpace(query.ImdbID) && query.ImdbID.ToLower().StartsWith("tt"))
+            {
+                queryCollection.Add("search", query.ImdbID);
+            }
+            else
+            {
+                if (!string.IsNullOrWhiteSpace(searchString))
+                    queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+                queryCollection.Add("c" + cat, "1");
+
+            if (queryCollection.Count > 0)
+                queryUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(queryUrl);
+
+            // Check for being logged out
+            if (results.IsRedirect)
+                if (results.RedirectingTo.Contains("login.php"))
+                    throw new ExceptionWithConfigData("Login failed, please reconfigure the tracker to update the cookies", configData);
+                else
+                    throw new ExceptionWithConfigData(string.Format("Got a redirect to {0}, please adjust your the alternative link", results.RedirectingTo), configData);
+
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom["#torrentTable > tbody > tr.browse"];
+                foreach (var row in rows)
+                {
+                    CQ qRow = row.Cq();
+                    var release = new ReleaseInfo();
+
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 172800;
+                    release.Title = qRow.Find(".torrentName").Text();
+
+                    if ((query.ImdbID == null || !TorznabCaps.SupportsImdbSearch) && !query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    release.Guid = new Uri(SiteLink + qRow.Find(".torrentName").Attr("href"));
+                    release.Comments = release.Guid;
+                    release.Link = new Uri(SiteLink + qRow.Find(".dlLinksInfo > a").Attr("href"));
+
+                    var sizeStr = qRow.Find(".sizeInfo").Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    var dateStr = qRow.Find(".ulInfo").Text().Split('|').Last().Trim();
+                    var agoIdx = dateStr.IndexOf("ago");
+                    if (agoIdx > -1)
+                    {
+                        dateStr = dateStr.Substring(0, agoIdx);
+                    }
+                    release.PublishDate = DateTimeUtil.FromTimeAgo(dateStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qRow.Find(".seedersInfo").Text());
+                    release.Peers = ParseUtil.CoerceInt(qRow.Find(".leechersInfo").Text()) + release.Seeders;
+
+                    var cat = qRow.Find("td:eq(0) a").First().Attr("href").Split('#')[0].Substring(15);//browse.php?cat=24
+                    release.Category = MapTrackerCatToNewznab(cat);
+
+                    if (qRow.Find("span.flTags").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-            return releases;
-        }
-    }
-}
+                        release.DownloadVolumeFactor = 1;
+
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/TorrentHeaven.cs b/src/Jackett/Indexers/TorrentHeaven.cs
index 6057f58ef2c97cc199bc39b5accaab88b14105ba..2eb7bf5fc0bbb9ee862c40243c0206c53ceaf466 100644
--- a/src/Jackett/Indexers/TorrentHeaven.cs
+++ b/src/Jackett/Indexers/TorrentHeaven.cs
@@ -10,18 +10,18 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-using System.Linq;
-using System.Text.RegularExpressions;
-
+using System.Collections.Specialized;
+using System.Text;
+using System.Linq;
+using System.Text.RegularExpressions;
+
 namespace Jackett.Indexers
 {
     public class TorrentHeaven : BaseIndexer, IIndexer
     {
         string IndexUrl { get { return SiteLink + "index.php"; } }
         string LoginCompleteUrl { get { return SiteLink + "index.php?strWebValue=account&strWebAction=login_complete&ancestry=verify"; } }
-        static readonly string certificateHash = "6F5CE30D578C2A7AECFB919D0D013976D395055F";
+        static readonly string certificateHash = "6F5CE30D578C2A7AECFB919D0D013976D395055F";
 
         new ConfigurationDataCaptchaLogin configData
         {
@@ -39,80 +39,80 @@ namespace Jackett.Indexers
                    logger: l,
                    p: ps,
                    configData: new ConfigurationDataCaptchaLogin())
-        {
+        {
             Encoding = Encoding.GetEncoding("iso-8859-1");
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(1,   TorznabCatType.PCGames); // GAMES/PC
-            AddCategoryMapping(3,   TorznabCatType.Console); // GAMES/Sonstige
-            AddCategoryMapping(59,  TorznabCatType.ConsolePS4); // GAMES/PlayStation
-            AddCategoryMapping(60,  TorznabCatType.ConsolePSP); // GAMES/PSP
-            AddCategoryMapping(63,  TorznabCatType.ConsoleWii); // GAMES/Wii
-            AddCategoryMapping(67,  TorznabCatType.ConsoleXbox360); // GAMES/XBOX 360
-            AddCategoryMapping(68,  TorznabCatType.PCPhoneOther); // GAMES/PDA / Handy
-            AddCategoryMapping(72,  TorznabCatType.ConsoleNDS); // GAMES/NDS
-
-            AddCategoryMapping(7 ,  TorznabCatType.MoviesDVD); // MOVIES/DVD
-            AddCategoryMapping(8,   TorznabCatType.MoviesSD); // MOVIES/SD
-            AddCategoryMapping(37,  TorznabCatType.MoviesDVD); // MOVIES/DVD Spezial
-            AddCategoryMapping(41,  TorznabCatType.MoviesForeign); // MOVIES/International
-            AddCategoryMapping(101, TorznabCatType.MoviesHD); // MOVIES/720p
-            AddCategoryMapping(102, TorznabCatType.MoviesHD); // MOVIES/1080p
-            AddCategoryMapping(103, TorznabCatType.MoviesHD); // MOVIES/AVCHD
-            AddCategoryMapping(104, TorznabCatType.MoviesBluRay); // MOVIES/Bluray
-            AddCategoryMapping(106, TorznabCatType.Movies3D); // MOVIES/3D
-
-            AddCategoryMapping(14,  TorznabCatType.Audio); // AUDIO/Musik
-            AddCategoryMapping(15,  TorznabCatType.AudioAudiobook); // AUDIO/Hörbücher
-            AddCategoryMapping(16,  TorznabCatType.AudioAudiobook); // AUDIO/Hörspiele
-            AddCategoryMapping(36,  TorznabCatType.AudioLossless); // AUDIO/Flac
-            AddCategoryMapping(42,  TorznabCatType.AudioOther); // AUDIO/Soundtracks
-            AddCategoryMapping(58,  TorznabCatType.AudioVideo); // AUDIO/Musikvideos
-
-            AddCategoryMapping(18,  TorznabCatType.TVSD); // TV/Serien SD
-            AddCategoryMapping(19,  TorznabCatType.TVHD); // TV/Serien HD 720p
-            AddCategoryMapping(20,  TorznabCatType.TVHD); // TV/Serien HD 1080p
-            AddCategoryMapping(49,  TorznabCatType.TVSD); // TV/Serien DVD
-            AddCategoryMapping(51,  TorznabCatType.TVDocumentary); // TV/Doku SD
-            AddCategoryMapping(52,  TorznabCatType.TVDocumentary); // TV/Doku HD
-            AddCategoryMapping(53,  TorznabCatType.TV); // TV/Serien Complete Packs
-            AddCategoryMapping(54,  TorznabCatType.TVSport); // TV/Sport
-            AddCategoryMapping(66,  TorznabCatType.TVFOREIGN); // TV/International
- 
-            AddCategoryMapping(22,  TorznabCatType.Books); // MISC/EBooks
-            AddCategoryMapping(24,  TorznabCatType.Other); // MISC/Sonstiges
-            AddCategoryMapping(25,  TorznabCatType.Other); // MISC/Tonspuren
-            AddCategoryMapping(108, TorznabCatType.TVAnime); // MISC/Anime
-
-            AddCategoryMapping(28,  TorznabCatType.PC); // APPLICATIONS/PC
-            AddCategoryMapping(29,  TorznabCatType.PCPhoneOther); // APPLICATIONS/Mobile
-            AddCategoryMapping(30,  TorznabCatType.PC); // APPLICATIONS/Sonstige
-            AddCategoryMapping(70,  TorznabCatType.PC); // APPLICATIONS/Linux
+            AddCategoryMapping(1,   TorznabCatType.PCGames); // GAMES/PC
+            AddCategoryMapping(3,   TorznabCatType.Console); // GAMES/Sonstige
+            AddCategoryMapping(59,  TorznabCatType.ConsolePS4); // GAMES/PlayStation
+            AddCategoryMapping(60,  TorznabCatType.ConsolePSP); // GAMES/PSP
+            AddCategoryMapping(63,  TorznabCatType.ConsoleWii); // GAMES/Wii
+            AddCategoryMapping(67,  TorznabCatType.ConsoleXbox360); // GAMES/XBOX 360
+            AddCategoryMapping(68,  TorznabCatType.PCPhoneOther); // GAMES/PDA / Handy
+            AddCategoryMapping(72,  TorznabCatType.ConsoleNDS); // GAMES/NDS
+
+            AddCategoryMapping(7 ,  TorznabCatType.MoviesDVD); // MOVIES/DVD
+            AddCategoryMapping(8,   TorznabCatType.MoviesSD); // MOVIES/SD
+            AddCategoryMapping(37,  TorznabCatType.MoviesDVD); // MOVIES/DVD Spezial
+            AddCategoryMapping(41,  TorznabCatType.MoviesForeign); // MOVIES/International
+            AddCategoryMapping(101, TorznabCatType.MoviesHD); // MOVIES/720p
+            AddCategoryMapping(102, TorznabCatType.MoviesHD); // MOVIES/1080p
+            AddCategoryMapping(103, TorznabCatType.MoviesHD); // MOVIES/AVCHD
+            AddCategoryMapping(104, TorznabCatType.MoviesBluRay); // MOVIES/Bluray
+            AddCategoryMapping(106, TorznabCatType.Movies3D); // MOVIES/3D
+
+            AddCategoryMapping(14,  TorznabCatType.Audio); // AUDIO/Musik
+            AddCategoryMapping(15,  TorznabCatType.AudioAudiobook); // AUDIO/Hörbücher
+            AddCategoryMapping(16,  TorznabCatType.AudioAudiobook); // AUDIO/Hörspiele
+            AddCategoryMapping(36,  TorznabCatType.AudioLossless); // AUDIO/Flac
+            AddCategoryMapping(42,  TorznabCatType.AudioOther); // AUDIO/Soundtracks
+            AddCategoryMapping(58,  TorznabCatType.AudioVideo); // AUDIO/Musikvideos
+
+            AddCategoryMapping(18,  TorznabCatType.TVSD); // TV/Serien SD
+            AddCategoryMapping(19,  TorznabCatType.TVHD); // TV/Serien HD 720p
+            AddCategoryMapping(20,  TorznabCatType.TVHD); // TV/Serien HD 1080p
+            AddCategoryMapping(49,  TorznabCatType.TVSD); // TV/Serien DVD
+            AddCategoryMapping(51,  TorznabCatType.TVDocumentary); // TV/Doku SD
+            AddCategoryMapping(52,  TorznabCatType.TVDocumentary); // TV/Doku HD
+            AddCategoryMapping(53,  TorznabCatType.TV); // TV/Serien Complete Packs
+            AddCategoryMapping(54,  TorznabCatType.TVSport); // TV/Sport
+            AddCategoryMapping(66,  TorznabCatType.TVFOREIGN); // TV/International
+ 
+            AddCategoryMapping(22,  TorznabCatType.Books); // MISC/EBooks
+            AddCategoryMapping(24,  TorznabCatType.Other); // MISC/Sonstiges
+            AddCategoryMapping(25,  TorznabCatType.Other); // MISC/Tonspuren
+            AddCategoryMapping(108, TorznabCatType.TVAnime); // MISC/Anime
+
+            AddCategoryMapping(28,  TorznabCatType.PC); // APPLICATIONS/PC
+            AddCategoryMapping(29,  TorznabCatType.PCPhoneOther); // APPLICATIONS/Mobile
+            AddCategoryMapping(30,  TorznabCatType.PC); // APPLICATIONS/Sonstige
+            AddCategoryMapping(70,  TorznabCatType.PC); // APPLICATIONS/Linux
             AddCategoryMapping(71,  TorznabCatType.PCMac); // APPLICATIONS/Mac
         }
 
-        public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
-        {
-            base.LoadValuesFromJson(jsonConfig, useProtectionService);
-
-            // add self signed cert to trusted certs
-            webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
+        public override void LoadValuesFromJson(JToken jsonConfig, bool useProtectionService = false)
+        {
+            base.LoadValuesFromJson(jsonConfig, useProtectionService);
+
+            // add self signed cert to trusted certs
+            webclient.AddTrustedCertificate(new Uri(SiteLink).Host, certificateHash);
         }
 
         public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(IndexUrl, string.Empty);
-            CQ dom = loginPage.Content;
-            CQ qCaptchaImg = dom.Find("td.tablea > img").First();
-            if(qCaptchaImg.Length == 1) {
+        {
+            var loginPage = await RequestStringWithCookies(IndexUrl, string.Empty);
+            CQ dom = loginPage.Content;
+            CQ qCaptchaImg = dom.Find("td.tablea > img").First();
+            if(qCaptchaImg.Length == 1) {
                 var CaptchaUrl = SiteLink + qCaptchaImg.Attr("src");
                 var captchaImage = await RequestBytesWithCookies(CaptchaUrl, loginPage.Cookies);
-                configData.CaptchaImage.Value = captchaImage.Content;
+                configData.CaptchaImage.Value = captchaImage.Content;
             }
-            else
-            {
-                configData.CaptchaImage.Value = new byte[0];
+            else
+            {
+                configData.CaptchaImage.Value = new byte[0];
             }
             configData.CaptchaCookie.Value = loginPage.Cookies;
             return configData;
@@ -132,19 +132,19 @@ namespace Jackett.Indexers
                 { "password", configData.Password.Value }
             };
 
-            if (!string.IsNullOrWhiteSpace(configData.CaptchaText.Value))
-            {
-                pairs.Add("proofcode", configData.CaptchaText.Value);
+            if (!string.IsNullOrWhiteSpace(configData.CaptchaText.Value))
+            {
+                pairs.Add("proofcode", configData.CaptchaText.Value);
             }
 
             var result = await RequestLoginAndFollowRedirect(IndexUrl, pairs, configData.CaptchaCookie.Value, true, null, IndexUrl, true);
-            if (result.Content == null || (!result.Content.Contains("login_complete") && !result.Content.Contains("index.php?strWebValue=account&strWebAction=logout")))
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom["table > tbody > tr > td[valign=top][width=100%]"].Html();
-                if(errorMessage.Length == 0)
-                    errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            if (result.Content == null || (!result.Content.Contains("login_complete") && !result.Content.Contains("index.php?strWebValue=account&strWebAction=logout")))
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom["table > tbody > tr > td[valign=top][width=100%]"].Html();
+                if(errorMessage.Length == 0)
+                    errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             }
 
             var result2 = await RequestStringWithCookies(LoginCompleteUrl, result.Cookies);
@@ -158,36 +158,36 @@ namespace Jackett.Indexers
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = IndexUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("strWebValue", "torrent");
-            queryCollection.Add("strWebAction", "search");
-            queryCollection.Add("sort", "torrent_added");
-            queryCollection.Add("by", "d");
-            queryCollection.Add("type", "0");
-            queryCollection.Add("do_search", "suchen");
-            queryCollection.Add("time", "0");
-            queryCollection.Add("details", "title");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("searchstring", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("dirs" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = IndexUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("strWebValue", "torrent");
+            queryCollection.Add("strWebAction", "search");
+            queryCollection.Add("sort", "torrent_added");
+            queryCollection.Add("by", "d");
+            queryCollection.Add("type", "0");
+            queryCollection.Add("do_search", "suchen");
+            queryCollection.Add("time", "0");
+            queryCollection.Add("details", "title");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("searchstring", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("dirs" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookies(searchUrl);
@@ -201,56 +201,56 @@ namespace Jackett.Indexers
                 foreach (var row in rows.Skip(1))
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 0.8;
+                    release.MinimumRatio = 0.8;
                     release.MinimumSeedTime = 0;
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=details]").First();
-                    release.Title = TitleRegexp.Match(qDetailsLink.Attr("onmouseover")).Groups[1].Value;
-
-                    var qCatLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=search&dir=]").First();
-                    var qDLLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=download&id=]").First();
-                    var qSeeders = qRow.Find("td.column1:eq(3)");
-                    var qLeechers = qRow.Find("td.column2:eq(3)");
-                    var qDateStr = qRow.Find("font:has(a)").First();
-                    var qSize = qRow.Find("td.column2[align=center]").First();
-
-                    var catStr = qCatLink.Attr("href").Split('=')[3].Split('#')[0];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=details]").First();
+                    release.Title = TitleRegexp.Match(qDetailsLink.Attr("onmouseover")).Groups[1].Value;
+
+                    var qCatLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=search&dir=]").First();
+                    var qDLLink = qRow.Find("a[href^=index.php?strWebValue=torrent&strWebAction=download&id=]").First();
+                    var qSeeders = qRow.Find("td.column1:eq(3)");
+                    var qLeechers = qRow.Find("td.column2:eq(3)");
+                    var qDateStr = qRow.Find("font:has(a)").First();
+                    var qSize = qRow.Find("td.column2[align=center]").First();
+
+                    var catStr = qCatLink.Attr("href").Split('=')[3].Split('#')[0];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text().Trim();
                     var dateStrParts = dateStr.Split();
-                    DateTime dateGerman;
-                    if (dateStrParts[0] == "Heute")
-                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]);
-                    else if (dateStrParts[0] == "Gestern")
-                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]) - TimeSpan.FromDays(1);
-                    else
-                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStrParts[0]+ dateStrParts[1], "dd.MM.yyyyHH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime dateGerman;
+                    if (dateStrParts[0] == "Heute")
+                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]);
+                    else if (dateStrParts[0] == "Gestern")
+                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStrParts[1]) - TimeSpan.FromDays(1);
+                    else
+                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStrParts[0]+ dateStrParts[1], "dd.MM.yyyyHH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc.ToLocalTime();
 
                     var grabs = qRow.Find("td:nth-child(7)").Text();
-                    release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                    if (qRow.Find("img[src=\"themes/images/freeleech.png\"]").Length >= 1)
+                    release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                    if (qRow.Find("img[src=\"themes/images/freeleech.png\"]").Length >= 1)
                         release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("img[src=\"themes/images/DL50.png\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
+                    else if (qRow.Find("img[src=\"themes/images/DL50.png\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/TorrentLeech.cs b/src/Jackett/Indexers/TorrentLeech.cs
index 978d541f131b408d32a2f01e646b857e3d62d8a6..9c35d0840c74c1974e646ef7b48e4e1cff29af6e 100644
--- a/src/Jackett/Indexers/TorrentLeech.cs
+++ b/src/Jackett/Indexers/TorrentLeech.cs
@@ -85,7 +85,7 @@ namespace Jackett.Indexers
             AddCategoryMapping(5, TorznabCatType.Books);
             AddCategoryMapping(45, TorznabCatType.BooksEbook, "Books/EBooks");
             AddCategoryMapping(46, TorznabCatType.BooksComics, "Books/Comics");
-
+
             AddCategoryMapping(23, TorznabCatType.PCISO);
             AddCategoryMapping(24, TorznabCatType.PCMac);
             AddCategoryMapping(25, TorznabCatType.PCPhoneOther);
@@ -120,7 +120,7 @@ namespace Jackett.Indexers
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
+            var searchString = query.GetQueryString();
             searchString = searchString.Replace('-', ' '); // remove dashes as they exclude search strings
             var searchUrl = SearchUrl;
 
@@ -140,10 +140,10 @@ namespace Jackett.Indexers
                         searchUrl += ",";
                     searchUrl += cat;
                 }
-            }
-            else
-            {
-                searchUrl += "newfilter/2"; // include 0day and music
+            }
+            else
+            {
+                searchUrl += "newfilter/2"; // include 0day and music
             }
 
             var results = await RequestStringWithCookiesAndRetry(searchUrl);
@@ -177,7 +177,7 @@ namespace Jackett.Indexers
                     release.Comments = release.Guid;
                     release.Title = qLink.Text();
 
-                    if (!query.MatchQueryStringAND(release.Title))
+                    if (!query.MatchQueryStringAND(release.Title))
                         continue;
 
                     release.Link = new Uri(qRow.Find(".quickdownload > a").Attr("href"));
@@ -197,7 +197,7 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(6)").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    release.DownloadVolumeFactor = 1;
+                    release.DownloadVolumeFactor = 1;
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/TorrentNetwork.cs b/src/Jackett/Indexers/TorrentNetwork.cs
index 6f0ad19eb82cbd5c6eff8f3f3085a5d099101ac1..53c3b18f9fb67b9d1792d2b8a4af8c1f00a4f441 100644
--- a/src/Jackett/Indexers/TorrentNetwork.cs
+++ b/src/Jackett/Indexers/TorrentNetwork.cs
@@ -10,9 +10,9 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-
+using System.Collections.Specialized;
+using System.Text;
+
 namespace Jackett.Indexers
 {
     public class TorrentNetwork : BaseIndexer, IIndexer
@@ -41,45 +41,45 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(1,  TorznabCatType.AudioAudiobook); // aBook
-            AddCategoryMapping(4,  TorznabCatType.PCMac); // App|Mac
-            AddCategoryMapping(5,  TorznabCatType.PC); // App|Win
-            AddCategoryMapping(7,  TorznabCatType.TVDocumentary); // Docu|HD
-            AddCategoryMapping(6,  TorznabCatType.TVDocumentary); // Docu|SD
-            AddCategoryMapping(8,  TorznabCatType.Books); // eBook
-            AddCategoryMapping(10, TorznabCatType.PCGames); // Game|PC
-            AddCategoryMapping(13, TorznabCatType.ConsolePS4); // Game|PSX
-            AddCategoryMapping(12, TorznabCatType.ConsoleWii); // Game|Wii
-            AddCategoryMapping(14, TorznabCatType.ConsoleXbox); // Game|XBOX
-            AddCategoryMapping(30, TorznabCatType.Other); // Misc
-            AddCategoryMapping(17, TorznabCatType.MoviesHD); // Movie|DE|1080p
-            AddCategoryMapping(20, TorznabCatType.MoviesHD); // Movie|DE|2160p
-            AddCategoryMapping(36, TorznabCatType.Movies3D); // Movie|DE|3D
-            AddCategoryMapping(18, TorznabCatType.MoviesHD); // Movie|DE|720p
-            AddCategoryMapping(34, TorznabCatType.TVAnime); // Movie|DE|Anime
-            AddCategoryMapping(19, TorznabCatType.MoviesBluRay); // Movie|DE|BluRay
-            AddCategoryMapping(45, TorznabCatType.Movies); // Movie|DE|Remux
-            AddCategoryMapping(24, TorznabCatType.MoviesSD); // Movie|DE|SD
-            AddCategoryMapping(39, TorznabCatType.Movies); // Movie|EN/JP|Anime
-            AddCategoryMapping(43, TorznabCatType.MoviesHD); // Movie|EN|1080p
-            AddCategoryMapping(37, TorznabCatType.MoviesHD); // Movie|EN|2160p
-            AddCategoryMapping(35, TorznabCatType.MoviesHD); // Movie|EN|720p
-            AddCategoryMapping(38, TorznabCatType.MoviesBluRay); // Movie|EN|BluRay
-            AddCategoryMapping(46, TorznabCatType.Movies); // Movie|EN|Remux
-            AddCategoryMapping(22, TorznabCatType.MoviesSD); // Movie|EN|SD
-            AddCategoryMapping(44, TorznabCatType.AudioLossless); // Music|Flac
-            AddCategoryMapping(25, TorznabCatType.AudioMP3); // Music|MP3
-            AddCategoryMapping(26, TorznabCatType.AudioVideo); // Music|Video
-            AddCategoryMapping(31, TorznabCatType.TVSport); // Sport
-            AddCategoryMapping(2,  TorznabCatType.TVAnime); // TV|DE|Anime
-            AddCategoryMapping(28, TorznabCatType.TVHD); // TV|DE|HD
-            AddCategoryMapping(16, TorznabCatType.TV); // TV|DE|Pack
-            AddCategoryMapping(27, TorznabCatType.TVSD); // TV|DE|SD
-            AddCategoryMapping(41, TorznabCatType.TVAnime); // TV|EN/JP|Anime
-            AddCategoryMapping(40, TorznabCatType.TVHD); // TV|EN|HD
-            AddCategoryMapping(42, TorznabCatType.TV); // TV|EN|Pack
-            AddCategoryMapping(29, TorznabCatType.TVSD); // TV|EN|SD
-            AddCategoryMapping(33, TorznabCatType.XXX); // XXX|HD
+            AddCategoryMapping(1,  TorznabCatType.AudioAudiobook); // aBook
+            AddCategoryMapping(4,  TorznabCatType.PCMac); // App|Mac
+            AddCategoryMapping(5,  TorznabCatType.PC); // App|Win
+            AddCategoryMapping(7,  TorznabCatType.TVDocumentary); // Docu|HD
+            AddCategoryMapping(6,  TorznabCatType.TVDocumentary); // Docu|SD
+            AddCategoryMapping(8,  TorznabCatType.Books); // eBook
+            AddCategoryMapping(10, TorznabCatType.PCGames); // Game|PC
+            AddCategoryMapping(13, TorznabCatType.ConsolePS4); // Game|PSX
+            AddCategoryMapping(12, TorznabCatType.ConsoleWii); // Game|Wii
+            AddCategoryMapping(14, TorznabCatType.ConsoleXbox); // Game|XBOX
+            AddCategoryMapping(30, TorznabCatType.Other); // Misc
+            AddCategoryMapping(17, TorznabCatType.MoviesHD); // Movie|DE|1080p
+            AddCategoryMapping(20, TorznabCatType.MoviesHD); // Movie|DE|2160p
+            AddCategoryMapping(36, TorznabCatType.Movies3D); // Movie|DE|3D
+            AddCategoryMapping(18, TorznabCatType.MoviesHD); // Movie|DE|720p
+            AddCategoryMapping(34, TorznabCatType.TVAnime); // Movie|DE|Anime
+            AddCategoryMapping(19, TorznabCatType.MoviesBluRay); // Movie|DE|BluRay
+            AddCategoryMapping(45, TorznabCatType.Movies); // Movie|DE|Remux
+            AddCategoryMapping(24, TorznabCatType.MoviesSD); // Movie|DE|SD
+            AddCategoryMapping(39, TorznabCatType.Movies); // Movie|EN/JP|Anime
+            AddCategoryMapping(43, TorznabCatType.MoviesHD); // Movie|EN|1080p
+            AddCategoryMapping(37, TorznabCatType.MoviesHD); // Movie|EN|2160p
+            AddCategoryMapping(35, TorznabCatType.MoviesHD); // Movie|EN|720p
+            AddCategoryMapping(38, TorznabCatType.MoviesBluRay); // Movie|EN|BluRay
+            AddCategoryMapping(46, TorznabCatType.Movies); // Movie|EN|Remux
+            AddCategoryMapping(22, TorznabCatType.MoviesSD); // Movie|EN|SD
+            AddCategoryMapping(44, TorznabCatType.AudioLossless); // Music|Flac
+            AddCategoryMapping(25, TorznabCatType.AudioMP3); // Music|MP3
+            AddCategoryMapping(26, TorznabCatType.AudioVideo); // Music|Video
+            AddCategoryMapping(31, TorznabCatType.TVSport); // Sport
+            AddCategoryMapping(2,  TorznabCatType.TVAnime); // TV|DE|Anime
+            AddCategoryMapping(28, TorznabCatType.TVHD); // TV|DE|HD
+            AddCategoryMapping(16, TorznabCatType.TV); // TV|DE|Pack
+            AddCategoryMapping(27, TorznabCatType.TVSD); // TV|DE|SD
+            AddCategoryMapping(41, TorznabCatType.TVAnime); // TV|EN/JP|Anime
+            AddCategoryMapping(40, TorznabCatType.TVHD); // TV|EN|HD
+            AddCategoryMapping(42, TorznabCatType.TV); // TV|EN|Pack
+            AddCategoryMapping(29, TorznabCatType.TVSD); // TV|EN|SD
+            AddCategoryMapping(33, TorznabCatType.XXX); // XXX|HD
             AddCategoryMapping(32, TorznabCatType.XXX); // XXX|SD
         }
 
@@ -94,44 +94,44 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom["table.tableinborder"].Html();
-                errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"), () =>
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom["table.tableinborder"].Html();
+                errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("_by", "0");
-            queryCollection.Add("sort", "4");
-            queryCollection.Add("type", "desc");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("_by", "0");
+            queryCollection.Add("sort", "4");
+            queryCollection.Add("type", "desc");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookies(searchUrl);
@@ -144,39 +144,39 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 0.8;
+                    release.MinimumRatio = 0.8;
                     release.MinimumSeedTime = 48 * 60 * 60;
 
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
-                    var qTitle = qDetailsLink.Find("b").First();
-                    release.Title = qTitle.Text();
-
-                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
-                    var qDLLink = qRow.Find("a.download").First();
-                    var qSeeders = qRow.Find("td.torrenttable:eq(7)");
-                    var qLeechers = qRow.Find("td.torrenttable:eq(8)");
-                    var qDateStr = qRow.Find("td.torrenttable:eq(4)").First();
-                    var qSize = qRow.Find("td.torrenttable:eq(5)").First();
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1].Split('\'')[0];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=details.php?id=]").First();
+                    var qTitle = qDetailsLink.Find("b").First();
+                    release.Title = qTitle.Text();
+
+                    var qCatLink = qRow.Find("a[href^=browse.php?cat=]").First();
+                    var qDLLink = qRow.Find("a.download").First();
+                    var qSeeders = qRow.Find("td.torrenttable:eq(7)");
+                    var qLeechers = qRow.Find("td.torrenttable:eq(8)");
+                    var qDateStr = qRow.Find("td.torrenttable:eq(4)").First();
+                    var qSize = qRow.Find("td.torrenttable:eq(5)").First();
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1].Split('\'')[0];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text().Trim();
-                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "MMM d yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc.ToLocalTime();
 
                     var files = qRow.Find("td:nth-child(4)").Text();
@@ -185,13 +185,13 @@ namespace Jackett.Indexers
                     var grabs = qRow.Find("td:nth-child(8)").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[src=\"pic/torrent_ou.gif\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("font[color=\"gray\"]:contains(50% Down)").Length >= 1)
-                        release.DownloadVolumeFactor = 0.5;
+                    if (qRow.Find("img[src=\"pic/torrent_ou.gif\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("font[color=\"gray\"]:contains(50% Down)").Length >= 1)
+                        release.DownloadVolumeFactor = 0.5;
                     else
-                        release.DownloadVolumeFactor = 1;
-
+                        release.DownloadVolumeFactor = 1;
+
                     release.UploadVolumeFactor = 1;
 
                     releases.Add(release);
diff --git a/src/Jackett/Indexers/TorrentSyndikat.cs b/src/Jackett/Indexers/TorrentSyndikat.cs
index fc85245327f14134bc4e3e3c083d52af57358a93..872d4b7e7b34a46f6169ae30d3a130703c80db62 100644
--- a/src/Jackett/Indexers/TorrentSyndikat.cs
+++ b/src/Jackett/Indexers/TorrentSyndikat.cs
@@ -1,221 +1,221 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Globalization;
-using System.Text.RegularExpressions;
-
-namespace Jackett.Indexers
-{
-    public class TorrentSyndikat : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "eing2.php"; } }
-        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
-        TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "W. Europe Standard Time", "W. Europe Standard Time");
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public TorrentSyndikat(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "Torrent-Syndikat",
-                description: "A German general tracker",
-                link: "https://torrent-syndikat.org/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "de-de";
-            Type = "private";
-
-            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
-            this.configData.DisplayText.Name = "Notice";
-
-            AddCategoryMapping(2,  TorznabCatType.PC); // Apps / Windows
-            AddCategoryMapping(13, TorznabCatType.PC); // Apps / Linux
-            AddCategoryMapping(4,  TorznabCatType.PCMac); // Apps / Mac
-            AddCategoryMapping(6,  TorznabCatType.PC); // Apps / Misc
-
-            AddCategoryMapping(12, TorznabCatType.PCGames); // Spiele / PC
-            AddCategoryMapping(8,  TorznabCatType.ConsolePSP); // Spiele / PSX/PSP
-            AddCategoryMapping(7,  TorznabCatType.ConsoleWii); // Spiele / Wii
-            AddCategoryMapping(32, TorznabCatType.ConsoleXbox); // Spiele / XBOX
-            AddCategoryMapping(41, TorznabCatType.ConsoleNDS); // Spiele / Nintendo DS
-
-            AddCategoryMapping(22, TorznabCatType.Movies3D); // Filme / 3D
-            AddCategoryMapping(3,  TorznabCatType.MoviesBluRay); // Filme / BluRay
-            AddCategoryMapping(11, TorznabCatType.MoviesOther); // Filme / REMUX
-            AddCategoryMapping(42, TorznabCatType.MoviesHD); // Filme / 2160p
-            AddCategoryMapping(9,  TorznabCatType.MoviesHD); // Filme / 1080p
-            AddCategoryMapping(20, TorznabCatType.MoviesHD); // Filme / 720p
-            AddCategoryMapping(21, TorznabCatType.MoviesDVD); // Filme / DVD
-            AddCategoryMapping(10, TorznabCatType.MoviesSD); // Filme / SD
-            AddCategoryMapping(31, TorznabCatType.MoviesOther); // Filme / Anime
-            AddCategoryMapping(37, TorznabCatType.MoviesForeign); // Filme / Englisch
-
-            AddCategoryMapping(16, TorznabCatType.TVHD); // TV / Serien/HD
-            AddCategoryMapping(15, TorznabCatType.TVSD); // TV / Serien/SD
-            AddCategoryMapping(44, TorznabCatType.TVHD); // TV / Packs/UHD
-            AddCategoryMapping(23, TorznabCatType.TVHD); // TV / Packs/HD
-            AddCategoryMapping(27, TorznabCatType.TVSD); // TV / Packs/SD
-            AddCategoryMapping(28, TorznabCatType.TVDocumentary); // TV / Dokus/SD
-            AddCategoryMapping(29, TorznabCatType.TVDocumentary); // TV / Dokus/HD
-            AddCategoryMapping(30, TorznabCatType.TVSport); // TV / Sport
-            AddCategoryMapping(40, TorznabCatType.TVAnime); // TV / Anime
-            AddCategoryMapping(36, TorznabCatType.TVFOREIGN); // TV / Englisch
-
-            AddCategoryMapping(24, TorznabCatType.AudioLossless); // Audio / FLAC
-            AddCategoryMapping(25, TorznabCatType.AudioMP3); // Audio / MP3
-            AddCategoryMapping(35, TorznabCatType.AudioOther); // Audio / Other
-            AddCategoryMapping(26, TorznabCatType.Audio); // Audio / Packs
-            AddCategoryMapping(18, TorznabCatType.AudioAudiobook); // Audio / aBooks
-            AddCategoryMapping(33, TorznabCatType.AudioVideo); // Audio / Videos
-
-            AddCategoryMapping(17, TorznabCatType.Books); // Misc / eBooks
-            AddCategoryMapping(5,  TorznabCatType.PCPhoneOther); // Misc / Mobile
-            AddCategoryMapping(39, TorznabCatType.Other); // Misc / Bildung
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var result1 = await RequestStringWithCookies(CaptchaUrl);
-            var json1 = JObject.Parse(result1.Content);
-            var captchaSelection = json1["images"][0]["hash"];
-
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "captchaSelection", (string)captchaSelection },
-                { "submitme", "X" }
-            };
-
-            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
-
-            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("/logout.php"), () =>
-            {
-                var errorMessage = result2.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("searchin", "title");
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("rel_type", "0"); // Alle
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                // use AND+wildcard operator to avoid getting to many useless results
-                var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList();
-                searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList(); //  remove words with less than 3 characters
-                searchStringArray = searchStringArray.Where(x => !new string[] { "der", "die", "das", "the" }.Contains(x.ToLower())).ToList(); //  remove words with less than 3 characters
-                searchStringArray = searchStringArray.Select(x => "+" + x + "*").ToList(); // add AND operators+wildcards
-                var searchStringFinal = String.Join(" ", searchStringArray);
-                queryCollection.Add("search", searchStringFinal);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-            try
-            {
-                CQ dom = results.Content;
-                var rows = dom["table.torrent_table > tbody > tr"];
-                var globalFreeleech = dom.Find("legend:contains(\"Freeleech\")+ul > li > b:contains(\"Freeleech\")").Any();
-                foreach (var row in rows.Skip(1))
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 96*60*60;
-
-                    var qRow = row.Cq();
-
-                    var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    var qLink = row.ChildElements.ElementAt(2).FirstElementChild.Cq();
-                    release.Link = new Uri(SiteLink + qLink.Attr("href"));
-                    var torrentId = qLink.Attr("href").Split('=').Last();
-
-                    var descCol = row.ChildElements.ElementAt(1);
-                    var qCommentLink = descCol.FirstElementChild.Cq();
-                    var torrentTag = descCol.Cq().Find("span.torrent-tag");
-                    var torrentTags = torrentTag.Elements.Select(x => x.InnerHTML).ToList();
-                    release.Title = qCommentLink.Attr("title");
-                    release.Description = String.Join(", ", torrentTags);
-                    release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href").Replace("&hit=1", ""));
-                    release.Guid = release.Comments;
-
-                    var torrent_details = descCol.ChildElements.Last();
-                    var dateStr = torrent_details.ChildNodes.ElementAt(torrent_details.ChildNodes.Length-3).Cq().Text().Replace(" von ", "").Trim();
-                    DateTime dateGerman;
-                    if (dateStr.StartsWith("Heute "))
-                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]);
-                    else if (dateStr.StartsWith("Gestern "))
-                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]) - TimeSpan.FromDays(1);
-                    else
-                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
-                    release.PublishDate = pubDateUtc.ToLocalTime();
-
-                    var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text());
-                    release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()) + release.Seeders;
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+using System.Globalization;
+using System.Text.RegularExpressions;
+
+namespace Jackett.Indexers
+{
+    public class TorrentSyndikat : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "eing2.php"; } }
+        private string CaptchaUrl { get { return SiteLink + "simpleCaptcha.php?numImages=1"; } }
+        TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "W. Europe Standard Time", "W. Europe Standard Time");
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get { return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public TorrentSyndikat(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "Torrent-Syndikat",
+                description: "A German general tracker",
+                link: "https://torrent-syndikat.org/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "de-de";
+            Type = "private";
+
+            this.configData.DisplayText.Value = "Only the results from the first search result page are shown, adjust your profile settings to show the maximum.";
+            this.configData.DisplayText.Name = "Notice";
+
+            AddCategoryMapping(2,  TorznabCatType.PC); // Apps / Windows
+            AddCategoryMapping(13, TorznabCatType.PC); // Apps / Linux
+            AddCategoryMapping(4,  TorznabCatType.PCMac); // Apps / Mac
+            AddCategoryMapping(6,  TorznabCatType.PC); // Apps / Misc
+
+            AddCategoryMapping(12, TorznabCatType.PCGames); // Spiele / PC
+            AddCategoryMapping(8,  TorznabCatType.ConsolePSP); // Spiele / PSX/PSP
+            AddCategoryMapping(7,  TorznabCatType.ConsoleWii); // Spiele / Wii
+            AddCategoryMapping(32, TorznabCatType.ConsoleXbox); // Spiele / XBOX
+            AddCategoryMapping(41, TorznabCatType.ConsoleNDS); // Spiele / Nintendo DS
+
+            AddCategoryMapping(22, TorznabCatType.Movies3D); // Filme / 3D
+            AddCategoryMapping(3,  TorznabCatType.MoviesBluRay); // Filme / BluRay
+            AddCategoryMapping(11, TorznabCatType.MoviesOther); // Filme / REMUX
+            AddCategoryMapping(42, TorznabCatType.MoviesHD); // Filme / 2160p
+            AddCategoryMapping(9,  TorznabCatType.MoviesHD); // Filme / 1080p
+            AddCategoryMapping(20, TorznabCatType.MoviesHD); // Filme / 720p
+            AddCategoryMapping(21, TorznabCatType.MoviesDVD); // Filme / DVD
+            AddCategoryMapping(10, TorznabCatType.MoviesSD); // Filme / SD
+            AddCategoryMapping(31, TorznabCatType.MoviesOther); // Filme / Anime
+            AddCategoryMapping(37, TorznabCatType.MoviesForeign); // Filme / Englisch
+
+            AddCategoryMapping(16, TorznabCatType.TVHD); // TV / Serien/HD
+            AddCategoryMapping(15, TorznabCatType.TVSD); // TV / Serien/SD
+            AddCategoryMapping(44, TorznabCatType.TVHD); // TV / Packs/UHD
+            AddCategoryMapping(23, TorznabCatType.TVHD); // TV / Packs/HD
+            AddCategoryMapping(27, TorznabCatType.TVSD); // TV / Packs/SD
+            AddCategoryMapping(28, TorznabCatType.TVDocumentary); // TV / Dokus/SD
+            AddCategoryMapping(29, TorznabCatType.TVDocumentary); // TV / Dokus/HD
+            AddCategoryMapping(30, TorznabCatType.TVSport); // TV / Sport
+            AddCategoryMapping(40, TorznabCatType.TVAnime); // TV / Anime
+            AddCategoryMapping(36, TorznabCatType.TVFOREIGN); // TV / Englisch
+
+            AddCategoryMapping(24, TorznabCatType.AudioLossless); // Audio / FLAC
+            AddCategoryMapping(25, TorznabCatType.AudioMP3); // Audio / MP3
+            AddCategoryMapping(35, TorznabCatType.AudioOther); // Audio / Other
+            AddCategoryMapping(26, TorznabCatType.Audio); // Audio / Packs
+            AddCategoryMapping(18, TorznabCatType.AudioAudiobook); // Audio / aBooks
+            AddCategoryMapping(33, TorznabCatType.AudioVideo); // Audio / Videos
+
+            AddCategoryMapping(17, TorznabCatType.Books); // Misc / eBooks
+            AddCategoryMapping(5,  TorznabCatType.PCPhoneOther); // Misc / Mobile
+            AddCategoryMapping(39, TorznabCatType.Other); // Misc / Bildung
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var result1 = await RequestStringWithCookies(CaptchaUrl);
+            var json1 = JObject.Parse(result1.Content);
+            var captchaSelection = json1["images"][0]["hash"];
+
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "captchaSelection", (string)captchaSelection },
+                { "submitme", "X" }
+            };
+
+            var result2 = await RequestLoginAndFollowRedirect(LoginUrl, pairs, result1.Cookies, true, null, null, true);
+
+            await ConfigureIfOK(result2.Cookies, result2.Content.Contains("/logout.php"), () =>
+            {
+                var errorMessage = result2.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("searchin", "title");
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("rel_type", "0"); // Alle
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                // use AND+wildcard operator to avoid getting to many useless results
+                var searchStringArray = Regex.Split(searchString.Trim(), "[ _.-]+", RegexOptions.Compiled).ToList();
+                searchStringArray = searchStringArray.Where(x => x.Length >= 3).ToList(); //  remove words with less than 3 characters
+                searchStringArray = searchStringArray.Where(x => !new string[] { "der", "die", "das", "the" }.Contains(x.ToLower())).ToList(); //  remove words with less than 3 characters
+                searchStringArray = searchStringArray.Select(x => "+" + x + "*").ToList(); // add AND operators+wildcards
+                var searchStringFinal = String.Join(" ", searchStringArray);
+                queryCollection.Add("search", searchStringFinal);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+            try
+            {
+                CQ dom = results.Content;
+                var rows = dom["table.torrent_table > tbody > tr"];
+                var globalFreeleech = dom.Find("legend:contains(\"Freeleech\")+ul > li > b:contains(\"Freeleech\")").Any();
+                foreach (var row in rows.Skip(1))
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 96*60*60;
+
+                    var qRow = row.Cq();
+
+                    var catStr = row.ChildElements.ElementAt(0).FirstElementChild.GetAttribute("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    var qLink = row.ChildElements.ElementAt(2).FirstElementChild.Cq();
+                    release.Link = new Uri(SiteLink + qLink.Attr("href"));
+                    var torrentId = qLink.Attr("href").Split('=').Last();
+
+                    var descCol = row.ChildElements.ElementAt(1);
+                    var qCommentLink = descCol.FirstElementChild.Cq();
+                    var torrentTag = descCol.Cq().Find("span.torrent-tag");
+                    var torrentTags = torrentTag.Elements.Select(x => x.InnerHTML).ToList();
+                    release.Title = qCommentLink.Attr("title");
+                    release.Description = String.Join(", ", torrentTags);
+                    release.Comments = new Uri(SiteLink + "/" + qCommentLink.Attr("href").Replace("&hit=1", ""));
+                    release.Guid = release.Comments;
+
+                    var torrent_details = descCol.ChildElements.Last();
+                    var dateStr = torrent_details.ChildNodes.ElementAt(torrent_details.ChildNodes.Length-3).Cq().Text().Replace(" von ", "").Trim();
+                    DateTime dateGerman;
+                    if (dateStr.StartsWith("Heute "))
+                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]);
+                    else if (dateStr.StartsWith("Gestern "))
+                        dateGerman = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified) + TimeSpan.Parse(dateStr.Split(' ')[1]) - TimeSpan.FromDays(1);
+                    else
+                        dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    release.PublishDate = pubDateUtc.ToLocalTime();
+
+                    var sizeStr = row.ChildElements.ElementAt(5).Cq().Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(row.ChildElements.ElementAt(7).Cq().Text());
+                    release.Peers = ParseUtil.CoerceInt(row.ChildElements.ElementAt(8).Cq().Text()) + release.Seeders;
 
                     var grabs = qRow.Find("td:nth-child(7)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (globalFreeleech)
+                    if (globalFreeleech)
+                        release.DownloadVolumeFactor = 0;
+                    else if (qRow.Find("span.torrent-tag-free").Length >= 1)
                         release.DownloadVolumeFactor = 0;
-                    else if (qRow.Find("span.torrent-tag-free").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+                        release.DownloadVolumeFactor = 1;
+
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Torrentech.cs b/src/Jackett/Indexers/Torrentech.cs
index 9dd30fe77006c747be2b1153c23d43cf65ab39f2..ae69f25c1b6b5221430f898b78cede00f57395a9 100644
--- a/src/Jackett/Indexers/Torrentech.cs
+++ b/src/Jackett/Indexers/Torrentech.cs
@@ -10,12 +10,12 @@ using System;
 using System.Text;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using AngleSharp.Parser.Html;
-using AngleSharp.Dom;
-using System.Text.RegularExpressions;
-using System.Web;
-
+using System.Collections.Specialized;
+using AngleSharp.Parser.Html;
+using AngleSharp.Dom;
+using System.Text.RegularExpressions;
+using System.Web;
+
 namespace Jackett.Indexers
 {
     public class Torrentech : BaseIndexer, IIndexer
@@ -39,7 +39,7 @@ namespace Jackett.Indexers
                    logger: l,
                    p: ps,
                    configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
+        {
             Encoding = Encoding.UTF8;
             Language = "en-us";
             Type = "private";
@@ -60,10 +60,10 @@ namespace Jackett.Indexers
             };
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Logged in as: "), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("Logged in as: "), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
@@ -71,122 +71,122 @@ namespace Jackett.Indexers
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            WebClientStringResult results = null;
-            var queryCollection = new NameValueCollection();
-
-            queryCollection.Add("act", "search");
-            queryCollection.Add("forums", "all");
-            queryCollection.Add("torrents", "1");
-            queryCollection.Add("search_in", "titles");
-            queryCollection.Add("result_type", "topics");
-
-            // if the search string is empty use the getnew view
-            if (string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("CODE", "getnew");
-                queryCollection.Add("active", "1");
+            var searchString = query.GetQueryString();
+
+            WebClientStringResult results = null;
+            var queryCollection = new NameValueCollection();
+
+            queryCollection.Add("act", "search");
+            queryCollection.Add("forums", "all");
+            queryCollection.Add("torrents", "1");
+            queryCollection.Add("search_in", "titles");
+            queryCollection.Add("result_type", "topics");
+
+            // if the search string is empty use the getnew view
+            if (string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("CODE", "getnew");
+                queryCollection.Add("active", "1");
             }
-            else // use the normal search
-            {
-                searchString = searchString.Replace("-", " ");
-                queryCollection.Add("CODE", "01");
-                queryCollection.Add("keywords", searchString);
+            else // use the normal search
+            {
+                searchString = searchString.Replace("-", " ");
+                queryCollection.Add("CODE", "01");
+                queryCollection.Add("keywords", searchString);
             }
 
             var searchUrl = IndexUrl + "?" + queryCollection.GetQueryString();
-            results = await RequestStringWithCookies(searchUrl);
-            if (results.IsRedirect && results.RedirectingTo.Contains("CODE=show"))
-            {
-                results = await RequestStringWithCookies(results.RedirectingTo);
-            }
+            results = await RequestStringWithCookies(searchUrl);
+            if (results.IsRedirect && results.RedirectingTo.Contains("CODE=show"))
+            {
+                results = await RequestStringWithCookies(results.RedirectingTo);
+            }
             try
             {
                 string RowsSelector = "div.borderwrap:has(div.maintitle) > table > tbody > tr:has(a[href*=\"index.php?showtopic=\"])";
 
-                var SearchResultParser = new HtmlParser();
+                var SearchResultParser = new HtmlParser();
                 var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                foreach (var Row in Rows)
+                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                foreach (var Row in Rows)
                 {
-                    try
+                    try
                     {
                         var release = new ReleaseInfo();
 
-                        var StatsElements = Row.QuerySelector("td:nth-child(5)");
-                        var stats = StatsElements.TextContent.Split('·');
-                        if (stats.Length != 3) // not a torrent
-                            continue;
-
-                        release.Seeders = ParseUtil.CoerceInt(stats[0]);
-                        release.Peers = ParseUtil.CoerceInt(stats[1]) + release.Seeders;
+                        var StatsElements = Row.QuerySelector("td:nth-child(5)");
+                        var stats = StatsElements.TextContent.Split('·');
+                        if (stats.Length != 3) // not a torrent
+                            continue;
+
+                        release.Seeders = ParseUtil.CoerceInt(stats[0]);
+                        release.Peers = ParseUtil.CoerceInt(stats[1]) + release.Seeders;
                         release.Grabs = ParseUtil.CoerceInt(stats[2]);
 
-                        release.MinimumRatio = 0.51;
+                        release.MinimumRatio = 0.51;
                         release.MinimumSeedTime = 0;
-
-                        var qDetailsLink = Row.QuerySelector("a[onmouseover][href*=\"index.php?showtopic=\"]");
-                        release.Title = qDetailsLink.TextContent;
-                        release.Comments = new Uri(qDetailsLink.GetAttribute("href"));
-                        release.Link = release.Comments;
-                        release.Guid = release.Link;
-
-                        release.DownloadVolumeFactor = 1;
-                        release.UploadVolumeFactor = 1;
-
-                        var id = HttpUtility.ParseQueryString(release.Comments.Query).Get("showtopic");
-
-                        var desc = Row.QuerySelector("span.desc");
-                        var forange = desc.QuerySelector("font.forange");
-                        if (forange != null)
-                        {
-                            var DownloadVolumeFactor = forange.QuerySelector("i:contains(\"freeleech\")");
-                            if (DownloadVolumeFactor != null)
-                                release.DownloadVolumeFactor = 0;
-
-                            var UploadVolumeFactor = forange.QuerySelector("i:contains(\"x upload]\")");
-                            if (UploadVolumeFactor != null)
-                                release.UploadVolumeFactor = ParseUtil.CoerceDouble(UploadVolumeFactor.TextContent.Split(' ')[0].Substring(1).Replace("x", ""));
-                            forange.Remove();
-                        }
-                        var format = desc.TextContent;
-                        release.Title += " [" + format + "]";
-
-                        var preview = SearchResultDocument.QuerySelector("div#d21-tph-preview-data-" + id);
-                        if (preview != null)
-                        {
-                            release.Description = "";
-                            foreach (var e in preview.ChildNodes)
-                            {
-                                if (e.NodeType == NodeType.Text)
-                                    release.Description += e.NodeValue;
-                                else
-                                    release.Description += e.TextContent + "\n";
-                            }
-                        }
-                        release.Description = HttpUtility.HtmlEncode(release.Description.Trim());
-                        release.Description = release.Description.Replace("\n", "<br>");
-
-                        if (format.Contains("MP3"))
-                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
-                        else if (format.Contains("AAC"))
-                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
-                        else if (format.Contains("Lossless"))
-                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
-                        else
-                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
-
-                        var lastAction = Row.QuerySelector("td:nth-child(9) > span").FirstChild.NodeValue;
-                        release.PublishDate = DateTimeUtil.FromUnknown(lastAction, "UK");
-
-                        releases.Add(release);
-                    }
-                    catch (Exception ex)
-                    {
-                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
+
+                        var qDetailsLink = Row.QuerySelector("a[onmouseover][href*=\"index.php?showtopic=\"]");
+                        release.Title = qDetailsLink.TextContent;
+                        release.Comments = new Uri(qDetailsLink.GetAttribute("href"));
+                        release.Link = release.Comments;
+                        release.Guid = release.Link;
+
+                        release.DownloadVolumeFactor = 1;
+                        release.UploadVolumeFactor = 1;
+
+                        var id = HttpUtility.ParseQueryString(release.Comments.Query).Get("showtopic");
+
+                        var desc = Row.QuerySelector("span.desc");
+                        var forange = desc.QuerySelector("font.forange");
+                        if (forange != null)
+                        {
+                            var DownloadVolumeFactor = forange.QuerySelector("i:contains(\"freeleech\")");
+                            if (DownloadVolumeFactor != null)
+                                release.DownloadVolumeFactor = 0;
+
+                            var UploadVolumeFactor = forange.QuerySelector("i:contains(\"x upload]\")");
+                            if (UploadVolumeFactor != null)
+                                release.UploadVolumeFactor = ParseUtil.CoerceDouble(UploadVolumeFactor.TextContent.Split(' ')[0].Substring(1).Replace("x", ""));
+                            forange.Remove();
+                        }
+                        var format = desc.TextContent;
+                        release.Title += " [" + format + "]";
+
+                        var preview = SearchResultDocument.QuerySelector("div#d21-tph-preview-data-" + id);
+                        if (preview != null)
+                        {
+                            release.Description = "";
+                            foreach (var e in preview.ChildNodes)
+                            {
+                                if (e.NodeType == NodeType.Text)
+                                    release.Description += e.NodeValue;
+                                else
+                                    release.Description += e.TextContent + "\n";
+                            }
+                        }
+                        release.Description = HttpUtility.HtmlEncode(release.Description.Trim());
+                        release.Description = release.Description.Replace("\n", "<br>");
+
+                        if (format.Contains("MP3"))
+                            release.Category = new List<int> { TorznabCatType.AudioMP3.ID };
+                        else if (format.Contains("AAC"))
+                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
+                        else if (format.Contains("Lossless"))
+                            release.Category = new List<int> { TorznabCatType.AudioLossless.ID };
+                        else
+                            release.Category = new List<int> { TorznabCatType.AudioOther.ID };
+
+                        var lastAction = Row.QuerySelector("td:nth-child(9) > span").FirstChild.NodeValue;
+                        release.PublishDate = DateTimeUtil.FromUnknown(lastAction, "UK");
+
+                        releases.Add(release);
                     }
-                }
+                    catch (Exception ex)
+                    {
+                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
+                    }
+                }
             }
             catch (Exception ex)
             {
@@ -196,26 +196,26 @@ namespace Jackett.Indexers
             return releases;
         }
 
-        public override async Task<byte[]> Download(Uri link)
-        {
-            var response = await RequestStringWithCookies(link.ToString());
-            var results = response.Content;
-            var SearchResultParser = new HtmlParser();
-            var SearchResultDocument = SearchResultParser.Parse(results);
-            var downloadSelector = "a[title=\"Download attachment\"]";
-            var DlUri = SearchResultDocument.QuerySelector(downloadSelector);
-            if (DlUri != null)
-            {
-                logger.Debug(string.Format("{0}: Download selector {1} matched:{2}", ID, downloadSelector, DlUri.OuterHtml));
-                var href = DlUri.GetAttribute("href");
-                link = new Uri(href);
-            }
-            else
-            {
-                logger.Error(string.Format("{0}: Download selector {1} didn't match:\n{2}", ID, downloadSelector, results));
-                throw new Exception(string.Format("Download selector {0} didn't match", downloadSelector));
-            }
-            return await base.Download(link);
+        public override async Task<byte[]> Download(Uri link)
+        {
+            var response = await RequestStringWithCookies(link.ToString());
+            var results = response.Content;
+            var SearchResultParser = new HtmlParser();
+            var SearchResultDocument = SearchResultParser.Parse(results);
+            var downloadSelector = "a[title=\"Download attachment\"]";
+            var DlUri = SearchResultDocument.QuerySelector(downloadSelector);
+            if (DlUri != null)
+            {
+                logger.Debug(string.Format("{0}: Download selector {1} matched:{2}", ID, downloadSelector, DlUri.OuterHtml));
+                var href = DlUri.GetAttribute("href");
+                link = new Uri(href);
+            }
+            else
+            {
+                logger.Error(string.Format("{0}: Download selector {1} didn't match:\n{2}", ID, downloadSelector, results));
+                throw new Exception(string.Format("Download selector {0} didn't match", downloadSelector));
+            }
+            return await base.Download(link);
         }
     }
 }
diff --git a/src/Jackett/Indexers/TransmitheNet.cs b/src/Jackett/Indexers/TransmitheNet.cs
index ac304dd03ab5345876fc88dd8795f7ceb7ab9763..c86c44141997181f1174573130b4682476d05650 100644
--- a/src/Jackett/Indexers/TransmitheNet.cs
+++ b/src/Jackett/Indexers/TransmitheNet.cs
@@ -148,16 +148,16 @@ namespace Jackett.Indexers
                     release.Files = ParseUtil.CoerceLong(row.QuerySelector("td > div:contains(\"Files:\")").TextContent.Split(':')[1].Trim());
                     release.Grabs = ParseUtil.CoerceLong(row.QuerySelector("td:nth-last-child(3)").TextContent);
 
-                    if (globalFreeleech)
-                        release.DownloadVolumeFactor = 0;
-                    else if (row.QuerySelector("img[alt=\"Freeleech\"]") != null)
-                        release.DownloadVolumeFactor = 0;
+                    if (globalFreeleech)
+                        release.DownloadVolumeFactor = 0;
+                    else if (row.QuerySelector("img[alt=\"Freeleech\"]") != null)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-
-                    release.UploadVolumeFactor = 1;
-
-
+                        release.DownloadVolumeFactor = 1;
+
+                    release.UploadVolumeFactor = 1;
+
+
                     releases.Add(release);
                 }
             }
diff --git a/src/Jackett/Indexers/XSpeeds.cs b/src/Jackett/Indexers/XSpeeds.cs
index d783f5e801bd913d082442e5493f4b2ba9d0528e..020868d040ad2330855401da375cb85267051d67 100644
--- a/src/Jackett/Indexers/XSpeeds.cs
+++ b/src/Jackett/Indexers/XSpeeds.cs
@@ -1,58 +1,58 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Text.RegularExpressions;
-using System.Xml.Linq;
-using static Jackett.Utils.ParseUtil;
-using static Jackett.Models.IndexerConfig.ConfigurationData;
-
-namespace Jackett.Indexers
-{
-    public class XSpeeds : BaseIndexer, IIndexer
-    {
-        string LandingUrl => SiteLink + "login.php";
-        string LoginUrl => SiteLink + "takelogin.php";
-        string GetRSSKeyUrl => SiteLink + "getrss.php";
-        string SearchUrl => SiteLink + "browse.php";
-        string RSSUrl => SiteLink + "rss.php?secret_key={0}&feedtype=download&timezone=0&showrows=50&categories=all";
-        string CommentUrl => SiteLink + "details.php?id={0}";
-        string DownloadUrl => SiteLink + "download.php?id={0}";
-
-        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
-        {
-            get {return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public XSpeeds(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
-            : base(name: "XSpeeds",
-                description: "XSpeeds",
-                link: "https://www.xspeeds.eu/",
-                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
-                manager: i,
-                client: wc,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
-        {
-            Encoding = Encoding.GetEncoding("UTF-8");
-            Language = "en-us";
-            Type = "private";
-
-            configData.DisplayText.Value = "Expect an initial delay (often around 10 seconds) due to XSpeeds CloudFlare DDoS protection";
-            configData.DisplayText.Name = "Notice";
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Text.RegularExpressions;
+using System.Xml.Linq;
+using static Jackett.Utils.ParseUtil;
+using static Jackett.Models.IndexerConfig.ConfigurationData;
+
+namespace Jackett.Indexers
+{
+    public class XSpeeds : BaseIndexer, IIndexer
+    {
+        string LandingUrl => SiteLink + "login.php";
+        string LoginUrl => SiteLink + "takelogin.php";
+        string GetRSSKeyUrl => SiteLink + "getrss.php";
+        string SearchUrl => SiteLink + "browse.php";
+        string RSSUrl => SiteLink + "rss.php?secret_key={0}&feedtype=download&timezone=0&showrows=50&categories=all";
+        string CommentUrl => SiteLink + "details.php?id={0}";
+        string DownloadUrl => SiteLink + "download.php?id={0}";
+
+        new ConfigurationDataBasicLoginWithRSSAndDisplay configData
+        {
+            get {return (ConfigurationDataBasicLoginWithRSSAndDisplay)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public XSpeeds(IIndexerManagerService i, IWebClient wc, Logger l, IProtectionService ps)
+            : base(name: "XSpeeds",
+                description: "XSpeeds",
+                link: "https://www.xspeeds.eu/",
+                caps: TorznabUtil.CreateDefaultTorznabTVCaps(),
+                manager: i,
+                client: wc,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataBasicLoginWithRSSAndDisplay())
+        {
+            Encoding = Encoding.GetEncoding("UTF-8");
+            Language = "en-us";
+            Type = "private";
+
+            configData.DisplayText.Value = "Expect an initial delay (often around 10 seconds) due to XSpeeds CloudFlare DDoS protection";
+            configData.DisplayText.Name = "Notice";
+
             AddCategoryMapping(70, TorznabCatType.TVAnime); // Anime
             AddCategoryMapping(4, TorznabCatType.PC); // Apps
             AddCategoryMapping(82, TorznabCatType.PCMac); // Mac
@@ -77,8 +77,8 @@ namespace Jackett.Indexers
             AddCategoryMapping(71, TorznabCatType.TV); // PPV
             AddCategoryMapping(54, TorznabCatType.TV); // Soaps
             AddCategoryMapping(20, TorznabCatType.TVSport); // Sports
-            AddCategoryMapping(86, TorznabCatType.TVSport); // MotorSports
-            AddCategoryMapping(89, TorznabCatType.TVSport); // Olympics 2016
+            AddCategoryMapping(86, TorznabCatType.TVSport); // MotorSports
+            AddCategoryMapping(89, TorznabCatType.TVSport); // Olympics 2016
             AddCategoryMapping(88, TorznabCatType.TVSport); // World Cup
             AddCategoryMapping(83, TorznabCatType.Movies); // TOTM
             AddCategoryMapping(21, TorznabCatType.TVSD); // TV Boxsets
@@ -87,275 +87,275 @@ namespace Jackett.Indexers
             AddCategoryMapping(16, TorznabCatType.TVSD); // TV-SD
             AddCategoryMapping(7, TorznabCatType.ConsoleWii); // Wii Games
             AddCategoryMapping(43, TorznabCatType.TVSport); // Wrestling
-            AddCategoryMapping(8, TorznabCatType.ConsoleXbox); // Xbox Games
-
-            // RSS Textual categories
-            AddCategoryMapping("Anime", TorznabCatType.TVAnime);
-            AddCategoryMapping("Apps", TorznabCatType.PC);
-            AddCategoryMapping("Mac", TorznabCatType.PCMac);
-            AddCategoryMapping("Audiobooks", TorznabCatType.AudioAudiobook);
-            AddCategoryMapping("Blu-Ray", TorznabCatType.MoviesBluRay);
-            AddCategoryMapping("Books Magazines", TorznabCatType.Books);
-            AddCategoryMapping("Cams/TS", TorznabCatType.MoviesOther);
-            AddCategoryMapping("Documentaries", TorznabCatType.TVDocumentary);
-            AddCategoryMapping("DVDR", TorznabCatType.MoviesDVD);
-            AddCategoryMapping("Foreign", TorznabCatType.MoviesForeign);
-            AddCategoryMapping("Kids", TorznabCatType.TVOTHER);
-            AddCategoryMapping("MMA", TorznabCatType.TVSport);
-            AddCategoryMapping("Movie Boxsets", TorznabCatType.Movies);
-            AddCategoryMapping("Movies", TorznabCatType.Movies);
-            AddCategoryMapping("Music", TorznabCatType.Audio);
-            AddCategoryMapping("Music Videos", TorznabCatType.AudioVideo);
-            AddCategoryMapping("NDS Games", TorznabCatType.ConsoleNDS);
-            AddCategoryMapping("Other", TorznabCatType.Other);
-            AddCategoryMapping("PC Games", TorznabCatType.PCGames);
-            AddCategoryMapping("Pictures", TorznabCatType.Other);
-            AddCategoryMapping("Playstation", TorznabCatType.ConsolePS4);
-            AddCategoryMapping("PPV", TorznabCatType.TV);
-            AddCategoryMapping("Soaps", TorznabCatType.TV);
-            AddCategoryMapping("Sports", TorznabCatType.TVSport);
-            AddCategoryMapping("MotorSports", TorznabCatType.TVSport);
-            AddCategoryMapping("Olympics 2016", TorznabCatType.TVSport);
-            AddCategoryMapping("World Cup", TorznabCatType.TVSport);
-            AddCategoryMapping("TOTM", TorznabCatType.Movies);
-            AddCategoryMapping("TV Boxsets", TorznabCatType.TVSD);
-            AddCategoryMapping("HD Boxsets", TorznabCatType.TVHD);
-            AddCategoryMapping("TV-HD", TorznabCatType.TVHD);
-            AddCategoryMapping("TV-SD", TorznabCatType.TVSD);
-            AddCategoryMapping("Wii Games", TorznabCatType.ConsoleWii);
-            AddCategoryMapping("Wrestling", TorznabCatType.TVSport);
-            AddCategoryMapping("Xbox Games", TorznabCatType.ConsoleXbox);
-        }
-
+            AddCategoryMapping(8, TorznabCatType.ConsoleXbox); // Xbox Games
+
+            // RSS Textual categories
+            AddCategoryMapping("Anime", TorznabCatType.TVAnime);
+            AddCategoryMapping("Apps", TorznabCatType.PC);
+            AddCategoryMapping("Mac", TorznabCatType.PCMac);
+            AddCategoryMapping("Audiobooks", TorznabCatType.AudioAudiobook);
+            AddCategoryMapping("Blu-Ray", TorznabCatType.MoviesBluRay);
+            AddCategoryMapping("Books Magazines", TorznabCatType.Books);
+            AddCategoryMapping("Cams/TS", TorznabCatType.MoviesOther);
+            AddCategoryMapping("Documentaries", TorznabCatType.TVDocumentary);
+            AddCategoryMapping("DVDR", TorznabCatType.MoviesDVD);
+            AddCategoryMapping("Foreign", TorznabCatType.MoviesForeign);
+            AddCategoryMapping("Kids", TorznabCatType.TVOTHER);
+            AddCategoryMapping("MMA", TorznabCatType.TVSport);
+            AddCategoryMapping("Movie Boxsets", TorznabCatType.Movies);
+            AddCategoryMapping("Movies", TorznabCatType.Movies);
+            AddCategoryMapping("Music", TorznabCatType.Audio);
+            AddCategoryMapping("Music Videos", TorznabCatType.AudioVideo);
+            AddCategoryMapping("NDS Games", TorznabCatType.ConsoleNDS);
+            AddCategoryMapping("Other", TorznabCatType.Other);
+            AddCategoryMapping("PC Games", TorznabCatType.PCGames);
+            AddCategoryMapping("Pictures", TorznabCatType.Other);
+            AddCategoryMapping("Playstation", TorznabCatType.ConsolePS4);
+            AddCategoryMapping("PPV", TorznabCatType.TV);
+            AddCategoryMapping("Soaps", TorznabCatType.TV);
+            AddCategoryMapping("Sports", TorznabCatType.TVSport);
+            AddCategoryMapping("MotorSports", TorznabCatType.TVSport);
+            AddCategoryMapping("Olympics 2016", TorznabCatType.TVSport);
+            AddCategoryMapping("World Cup", TorznabCatType.TVSport);
+            AddCategoryMapping("TOTM", TorznabCatType.Movies);
+            AddCategoryMapping("TV Boxsets", TorznabCatType.TVSD);
+            AddCategoryMapping("HD Boxsets", TorznabCatType.TVHD);
+            AddCategoryMapping("TV-HD", TorznabCatType.TVHD);
+            AddCategoryMapping("TV-SD", TorznabCatType.TVSD);
+            AddCategoryMapping("Wii Games", TorznabCatType.ConsoleWii);
+            AddCategoryMapping("Wrestling", TorznabCatType.TVSport);
+            AddCategoryMapping("Xbox Games", TorznabCatType.ConsoleXbox);
+        }
+
         public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LandingUrl);
-            CQ dom = loginPage.Content;
-            CQ qCaptchaImg = dom.Find("img#regimage").First();
-            if (qCaptchaImg.Length > 0)
-            { 
-
+        {
+            var loginPage = await RequestStringWithCookies(LandingUrl);
+            CQ dom = loginPage.Content;
+            CQ qCaptchaImg = dom.Find("img#regimage").First();
+            if (qCaptchaImg.Length > 0)
+            { 
+
                 var CaptchaUrl = qCaptchaImg.Attr("src");
                 var captchaImage = await RequestBytesWithCookies(CaptchaUrl, loginPage.Cookies, RequestType.GET, LandingUrl);
-
-                var CaptchaImage = new ImageItem { Name = "Captcha Image" };
-                var CaptchaText = new StringItem { Name = "Captcha Text" };
-
-                CaptchaImage.Value = captchaImage.Content;
-
-                configData.AddDynamic("CaptchaImage", CaptchaImage);
-                configData.AddDynamic("CaptchaText", CaptchaText);
-            }
-            else
-            {
-                logger.Debug(string.Format("{0}: No captcha image found", ID));
+
+                var CaptchaImage = new ImageItem { Name = "Captcha Image" };
+                var CaptchaText = new StringItem { Name = "Captcha Text" };
+
+                CaptchaImage.Value = captchaImage.Content;
+
+                configData.AddDynamic("CaptchaImage", CaptchaImage);
+                configData.AddDynamic("CaptchaText", CaptchaText);
+            }
+            else
+            {
+                logger.Debug(string.Format("{0}: No captcha image found", ID));
             }
 
             return configData;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-
-            var pairs = new Dictionary<string, string>
-                        {
-                            {"username", configData.Username.Value},
-                            {"password", configData.Password.Value}
-                        };
-
-            var CaptchaText = (StringItem)configData.GetDynamic("CaptchaText");
-            if (CaptchaText != null)
-            {
-                pairs.Add("imagestring", CaptchaText.Value);
-            }
-
-            //var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink, true);
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SearchUrl, LandingUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"),
-                () =>
-                {
-                    CQ dom = result.Content;
-                    var errorMessage = dom[".left_side table:eq(0) tr:eq(1)"].Text().Trim().Replace("\n\t", " ");
-                    throw new ExceptionWithConfigData(errorMessage, configData);
-                });
-
-            try
-            {
-                // Get RSS key
-                var rssParams = new Dictionary<string, string>
-                                {
-                                    {"feedtype", "download"},
-                                    {"timezone", "0"},
-                                    {"showrows", "50"}
-                                };
-                var rssPage = await PostDataWithCookies(GetRSSKeyUrl, rssParams, result.Cookies);
-                var match = Regex.Match(rssPage.Content, "(?<=secret_key\\=)([a-zA-z0-9]*)");
-                configData.RSSKey.Value = match.Success ? match.Value : string.Empty;
-                if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
-                    throw new Exception("Failed to get RSS Key");
-                SaveConfig();
-            }
-            catch
-            {
-                IsConfigured = false;
-                throw;
-            }
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-            var prevCook = CookieHeader + "";
-
-            // If we have no query use the RSS Page as their server is slow enough at times!
-            if (query.IsTest || string.IsNullOrWhiteSpace(searchString))
-            {
-                
-                var rssPage = await RequestStringWithCookiesAndRetry(string.Format(RSSUrl, configData.RSSKey.Value));
-                try
-                {
-                    if (rssPage.Content.EndsWith("\0")) {
-                        rssPage.Content = rssPage.Content.Substring(0, rssPage.Content.Length - 1);
-                    }
-                    rssPage.Content = RemoveInvalidXmlChars(rssPage.Content);
-                    var rssDoc = XDocument.Parse(rssPage.Content);
-
-                    foreach (var item in rssDoc.Descendants("item"))
-                    {
-                        var title = item.Descendants("title").First().Value;
-                        var description = item.Descendants("description").First().Value;
-                        var link = item.Descendants("link").First().Value;
-                        var category = item.Descendants("category").First().Value;
-                        var date = item.Descendants("pubDate").First().Value;
-
-                        var torrentIdMatch = Regex.Match(link, "(?<=id=)(\\d)*");
-                        var torrentId = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
-                        if (string.IsNullOrWhiteSpace(torrentId))
-                            throw new Exception("Missing torrent id");
-
-                        var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\/\WSeeders:\W(?<seeders>[\d\,]*)\W\/\WLeechers:\W(?<leechers>[\d\,]*)\W\/\WSize:\W(?<size>[\d\.]*\W\S*)");
-                        if (!infoMatch.Success)
-                            throw new Exception("Unable to find info");
-
-                        var release = new ReleaseInfo
-                        {
-                            Title = title,
-                            Description = title,
-                            Guid = new Uri(string.Format(DownloadUrl, torrentId)),
-                            Comments = new Uri(string.Format(CommentUrl, torrentId)),
-                            PublishDate = DateTime.ParseExact(date, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31 
-                            Link = new Uri(string.Format(DownloadUrl, torrentId)),
-                            Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value),
-                            Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value),
-                            Size = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
-                            Category = MapTrackerCatToNewznab(category)
-                        };
-
-                        release.Peers += release.Seeders;
-                        releases.Add(release);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    logger.Error("XSpeeds: Error while parsing the RSS feed:");
-                    logger.Error(rssPage.Content);
-                    throw ex;
-                }
-                
-            }
-            if (query.IsTest || !string.IsNullOrWhiteSpace(searchString))
-            {
-                if (searchString.Length < 3 && !query.IsTest)
-                {
-                    OnParseError("", new Exception("Minimum search length is 3"));
-                    return releases;
-                }
-                var searchParams = new Dictionary<string, string> {
-                    { "do", "search" },
-                    { "keywords",  searchString },
-                    { "search_type", "t_name" },
-                    { "category", "0" },
-                    { "include_dead_torrents", "no" }
-                };
-                var pairs = new Dictionary<string, string> {
-                    { "username", configData.Username.Value },
-                    { "password", configData.Password.Value }
-                };
-
-                var searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);
-                // Occasionally the cookies become invalid, login again if that happens
-                if (searchPage.IsRedirect)
-                {
-                    await ApplyConfiguration(null);
-                    searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);
-                }
-
-                try
-                {
-                    CQ dom = searchPage.Content;
-                    var rows = dom["table#sortabletable > tbody > tr:has(div > a[href*=\"details.php?id=\"])"];
-                    foreach (var row in rows)
-                    {
-                        var release = new ReleaseInfo();
-                        var qRow = row.Cq();
-
-                        var qDetails = qRow.Find("div > a[href*=\"details.php?id=\"]"); // details link, release name get's shortened if it's to long
-                        var qTitle = qRow.Find("td:eq(1) .tooltip-content div:eq(0)"); // use Title from tooltip
-                        if(!qTitle.Any()) // fallback to Details link if there's no tooltip
-                        {
-                            qTitle = qDetails;
-                        }
-                        release.Title = qTitle.Text();
-
-                        release.Guid = new Uri(qRow.Find("td:eq(2) a").Attr("href"));
-                        release.Link = release.Guid;
-                        release.Comments = new Uri(qDetails.Attr("href"));
-                        release.PublishDate = DateTime.ParseExact(qRow.Find("td:eq(1) div").Last().Text().Trim(), "dd-MM-yyyy H:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); //08-08-2015 12:51 
-                        release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text());
-                        release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim());
-                        release.Size = ReleaseInfo.GetBytes(qRow.Find("td:eq(4)").Text().Trim());
-
-                        var qBanner = qRow.Find("td:eq(1) .tooltip-content img").First();
-                        if (qBanner.Length > 0)
-                            release.BannerUrl = new Uri(qBanner.Attr("src"));
-
-                        var cat = row.Cq().Find("td:eq(0) a").First().Attr("href");
-                        var catSplit = cat.LastIndexOf('=');
-                        if (catSplit > -1)
-                            cat = cat.Substring(catSplit + 1);
-                        release.Category = MapTrackerCatToNewznab(cat);
-
-                        var grabs = qRow.Find("td:nth-child(6)").Text();
-                        release.Grabs = ParseUtil.CoerceInt(grabs);
-
-                        if (qRow.Find("img[alt^=\"Free Torrent\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0;
-                        else if (qRow.Find("img[alt^=\"Silver Torrent\"]").Length >= 1)
-                            release.DownloadVolumeFactor = 0.5;
-                        else
-                            release.DownloadVolumeFactor = 1;
-
-                        if (qRow.Find("img[alt^=\"x2 Torrent\"]").Length >= 1)
-                            release.UploadVolumeFactor = 2;
-                        else
-                            release.UploadVolumeFactor = 1;
-
-                        releases.Add(release);
-                    }
-                }
-                catch (Exception ex)
-                {
-                    OnParseError(searchPage.Content, ex);
-                }
-            }
-            if (!CookieHeader.Trim().Equals(prevCook.Trim()))
-            {
-                SaveConfig();
-            }
-            return releases;
-        }
-    }
-}
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+
+            var pairs = new Dictionary<string, string>
+                        {
+                            {"username", configData.Username.Value},
+                            {"password", configData.Password.Value}
+                        };
+
+            var CaptchaText = (StringItem)configData.GetDynamic("CaptchaText");
+            if (CaptchaText != null)
+            {
+                pairs.Add("imagestring", CaptchaText.Value);
+            }
+
+            //var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, SiteLink, true);
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, SearchUrl, LandingUrl, true);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("logout.php"),
+                () =>
+                {
+                    CQ dom = result.Content;
+                    var errorMessage = dom[".left_side table:eq(0) tr:eq(1)"].Text().Trim().Replace("\n\t", " ");
+                    throw new ExceptionWithConfigData(errorMessage, configData);
+                });
+
+            try
+            {
+                // Get RSS key
+                var rssParams = new Dictionary<string, string>
+                                {
+                                    {"feedtype", "download"},
+                                    {"timezone", "0"},
+                                    {"showrows", "50"}
+                                };
+                var rssPage = await PostDataWithCookies(GetRSSKeyUrl, rssParams, result.Cookies);
+                var match = Regex.Match(rssPage.Content, "(?<=secret_key\\=)([a-zA-z0-9]*)");
+                configData.RSSKey.Value = match.Success ? match.Value : string.Empty;
+                if (string.IsNullOrWhiteSpace(configData.RSSKey.Value))
+                    throw new Exception("Failed to get RSS Key");
+                SaveConfig();
+            }
+            catch
+            {
+                IsConfigured = false;
+                throw;
+            }
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchString = query.GetQueryString();
+            var prevCook = CookieHeader + "";
+
+            // If we have no query use the RSS Page as their server is slow enough at times!
+            if (query.IsTest || string.IsNullOrWhiteSpace(searchString))
+            {
+                
+                var rssPage = await RequestStringWithCookiesAndRetry(string.Format(RSSUrl, configData.RSSKey.Value));
+                try
+                {
+                    if (rssPage.Content.EndsWith("\0")) {
+                        rssPage.Content = rssPage.Content.Substring(0, rssPage.Content.Length - 1);
+                    }
+                    rssPage.Content = RemoveInvalidXmlChars(rssPage.Content);
+                    var rssDoc = XDocument.Parse(rssPage.Content);
+
+                    foreach (var item in rssDoc.Descendants("item"))
+                    {
+                        var title = item.Descendants("title").First().Value;
+                        var description = item.Descendants("description").First().Value;
+                        var link = item.Descendants("link").First().Value;
+                        var category = item.Descendants("category").First().Value;
+                        var date = item.Descendants("pubDate").First().Value;
+
+                        var torrentIdMatch = Regex.Match(link, "(?<=id=)(\\d)*");
+                        var torrentId = torrentIdMatch.Success ? torrentIdMatch.Value : string.Empty;
+                        if (string.IsNullOrWhiteSpace(torrentId))
+                            throw new Exception("Missing torrent id");
+
+                        var infoMatch = Regex.Match(description, @"Category:\W(?<cat>.*)\W\/\WSeeders:\W(?<seeders>[\d\,]*)\W\/\WLeechers:\W(?<leechers>[\d\,]*)\W\/\WSize:\W(?<size>[\d\.]*\W\S*)");
+                        if (!infoMatch.Success)
+                            throw new Exception("Unable to find info");
+
+                        var release = new ReleaseInfo
+                        {
+                            Title = title,
+                            Description = title,
+                            Guid = new Uri(string.Format(DownloadUrl, torrentId)),
+                            Comments = new Uri(string.Format(CommentUrl, torrentId)),
+                            PublishDate = DateTime.ParseExact(date, "yyyy-MM-dd H:mm:ss", CultureInfo.InvariantCulture), //2015-08-08 21:20:31 
+                            Link = new Uri(string.Format(DownloadUrl, torrentId)),
+                            Seeders = ParseUtil.CoerceInt(infoMatch.Groups["seeders"].Value),
+                            Peers = ParseUtil.CoerceInt(infoMatch.Groups["leechers"].Value),
+                            Size = ReleaseInfo.GetBytes(infoMatch.Groups["size"].Value),
+                            Category = MapTrackerCatToNewznab(category)
+                        };
+
+                        release.Peers += release.Seeders;
+                        releases.Add(release);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    logger.Error("XSpeeds: Error while parsing the RSS feed:");
+                    logger.Error(rssPage.Content);
+                    throw ex;
+                }
+                
+            }
+            if (query.IsTest || !string.IsNullOrWhiteSpace(searchString))
+            {
+                if (searchString.Length < 3 && !query.IsTest)
+                {
+                    OnParseError("", new Exception("Minimum search length is 3"));
+                    return releases;
+                }
+                var searchParams = new Dictionary<string, string> {
+                    { "do", "search" },
+                    { "keywords",  searchString },
+                    { "search_type", "t_name" },
+                    { "category", "0" },
+                    { "include_dead_torrents", "no" }
+                };
+                var pairs = new Dictionary<string, string> {
+                    { "username", configData.Username.Value },
+                    { "password", configData.Password.Value }
+                };
+
+                var searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);
+                // Occasionally the cookies become invalid, login again if that happens
+                if (searchPage.IsRedirect)
+                {
+                    await ApplyConfiguration(null);
+                    searchPage = await PostDataWithCookiesAndRetry(SearchUrl, searchParams, CookieHeader);
+                }
+
+                try
+                {
+                    CQ dom = searchPage.Content;
+                    var rows = dom["table#sortabletable > tbody > tr:has(div > a[href*=\"details.php?id=\"])"];
+                    foreach (var row in rows)
+                    {
+                        var release = new ReleaseInfo();
+                        var qRow = row.Cq();
+
+                        var qDetails = qRow.Find("div > a[href*=\"details.php?id=\"]"); // details link, release name get's shortened if it's to long
+                        var qTitle = qRow.Find("td:eq(1) .tooltip-content div:eq(0)"); // use Title from tooltip
+                        if(!qTitle.Any()) // fallback to Details link if there's no tooltip
+                        {
+                            qTitle = qDetails;
+                        }
+                        release.Title = qTitle.Text();
+
+                        release.Guid = new Uri(qRow.Find("td:eq(2) a").Attr("href"));
+                        release.Link = release.Guid;
+                        release.Comments = new Uri(qDetails.Attr("href"));
+                        release.PublishDate = DateTime.ParseExact(qRow.Find("td:eq(1) div").Last().Text().Trim(), "dd-MM-yyyy H:mm", CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal); //08-08-2015 12:51 
+                        release.Seeders = ParseUtil.CoerceInt(qRow.Find("td:eq(6)").Text());
+                        release.Peers = release.Seeders + ParseUtil.CoerceInt(qRow.Find("td:eq(7)").Text().Trim());
+                        release.Size = ReleaseInfo.GetBytes(qRow.Find("td:eq(4)").Text().Trim());
+
+                        var qBanner = qRow.Find("td:eq(1) .tooltip-content img").First();
+                        if (qBanner.Length > 0)
+                            release.BannerUrl = new Uri(qBanner.Attr("src"));
+
+                        var cat = row.Cq().Find("td:eq(0) a").First().Attr("href");
+                        var catSplit = cat.LastIndexOf('=');
+                        if (catSplit > -1)
+                            cat = cat.Substring(catSplit + 1);
+                        release.Category = MapTrackerCatToNewznab(cat);
+
+                        var grabs = qRow.Find("td:nth-child(6)").Text();
+                        release.Grabs = ParseUtil.CoerceInt(grabs);
+
+                        if (qRow.Find("img[alt^=\"Free Torrent\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0;
+                        else if (qRow.Find("img[alt^=\"Silver Torrent\"]").Length >= 1)
+                            release.DownloadVolumeFactor = 0.5;
+                        else
+                            release.DownloadVolumeFactor = 1;
+
+                        if (qRow.Find("img[alt^=\"x2 Torrent\"]").Length >= 1)
+                            release.UploadVolumeFactor = 2;
+                        else
+                            release.UploadVolumeFactor = 1;
+
+                        releases.Add(release);
+                    }
+                }
+                catch (Exception ex)
+                {
+                    OnParseError(searchPage.Content, ex);
+                }
+            }
+            if (!CookieHeader.Trim().Equals(prevCook.Trim()))
+            {
+                SaveConfig();
+            }
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/Indexers/Xthor.cs b/src/Jackett/Indexers/Xthor.cs
index ca124d841dcd7824a66434b0afb243f9a31684b2..f1d602e19f458155729178f2814b915296ab7e4f 100644
--- a/src/Jackett/Indexers/Xthor.cs
+++ b/src/Jackett/Indexers/Xthor.cs
@@ -1,608 +1,608 @@
-using System;
-using System.Collections.Generic;
-using System.Collections.Specialized;
-using System.Linq;
-using System.Text;
-using System.Reflection;
-using System.Threading.Tasks;
-using System.Web;
-using Jackett.Models;
-using Jackett.Models.IndexerConfig.Bespoke;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using NLog;
-
-namespace Jackett.Indexers
-{
-    /// <summary>
-    /// Provider for Xthor Private French Tracker
-    /// </summary>
-    public class Xthor : BaseIndexer, IIndexer
-    {
-        private static string ApiEndpoint => "https://api.xthor.bz/";
-        private string TorrentCommentUrl => TorrentDescriptionUrl;
-        private string TorrentDescriptionUrl => SiteLink + "details.php?id={id}";
-        private bool DevMode => ConfigData.DevMode.Value;
-        private bool CacheMode => ConfigData.HardDriveCache.Value;
-        private static string Directory => System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType?.Name + "\\";
-        public Dictionary<string, string> EmulatedBrowserHeaders { get; } = new Dictionary<string, string>();
-        private ConfigurationDataXthor ConfigData => (ConfigurationDataXthor)configData;
-
-        public Xthor(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
-            : base(
-                name: "Xthor",
-                description: "General French Private Tracker",
-                link: "https://xthor.bz/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                downloadBase: "https://xthor.bz/download.php?torrent=",
-                configData: new ConfigurationDataXthor())
-        {
-            Encoding = Encoding.UTF8;
-            Language = "fr-fr";
-            Type = "private";
-
-            // Clean capabilities
-            TorznabCaps.Categories.Clear();
-
-            // Movies
-            AddCategoryMapping(6, TorznabCatType.MoviesSD);             // XVID
-            AddCategoryMapping(7, TorznabCatType.MoviesSD);             // X264
-            AddCategoryMapping(95, TorznabCatType.MoviesSD);            // WEBRIP
-            AddCategoryMapping(5, TorznabCatType.MoviesHD);             // HD 720P
-            AddCategoryMapping(4, TorznabCatType.MoviesHD);             // HD 1080P X264
-            AddCategoryMapping(100, TorznabCatType.MoviesHD);           // HD 1080P X265
-            AddCategoryMapping(94, TorznabCatType.MoviesHD);            // WEBDL
-            AddCategoryMapping(1, TorznabCatType.MoviesBluRay);         // FULL BLURAY
-            AddCategoryMapping(2, TorznabCatType.MoviesBluRay);         // BLURAY REMUX
-            AddCategoryMapping(3, TorznabCatType.MoviesBluRay);         // FULL BLURAY 3D
-            AddCategoryMapping(8, TorznabCatType.MoviesDVD);            // FULL DVD
-            AddCategoryMapping(9, TorznabCatType.MoviesOther);          // VOSTFR
-            AddCategoryMapping(36, TorznabCatType.XXX);                 // XXX
-
-            // Series
-            AddCategoryMapping(14, TorznabCatType.TVSD);                // SD VF
-            AddCategoryMapping(16, TorznabCatType.TVSD);                // SD VF VOSTFR
-            AddCategoryMapping(15, TorznabCatType.TVHD);                // HD VF
-            AddCategoryMapping(17, TorznabCatType.TVHD);                // HD VF VOSTFR
-            AddCategoryMapping(13, TorznabCatType.TVOTHER);             // PACK
-            AddCategoryMapping(98, TorznabCatType.TVOTHER);             // PACK VOSTFR HD
-            AddCategoryMapping(16, TorznabCatType.TVOTHER);             // PACK VOSTFR SD
-            AddCategoryMapping(30, TorznabCatType.TVOTHER);             // EMISSIONS
-            AddCategoryMapping(34, TorznabCatType.TVOTHER);             // EMISSIONS
-            AddCategoryMapping(33, TorznabCatType.TVOTHER);             // SHOWS
-
-            // Anime
-            AddCategoryMapping(31, TorznabCatType.TVAnime);             // MOVIES ANIME
-            AddCategoryMapping(32, TorznabCatType.TVAnime);             // SERIES ANIME
-
-            // Documentaries
-            AddCategoryMapping(12, TorznabCatType.TVDocumentary);       // DOCS
-
-            // Music
-            AddCategoryMapping(20, TorznabCatType.AudioVideo);          // CONCERT
-
-            // Other
-            AddCategoryMapping(21, TorznabCatType.PC);                  // PC
-            AddCategoryMapping(22, TorznabCatType.PCMac);               // PC
-            AddCategoryMapping(25, TorznabCatType.PCGames);             // GAMES
-            AddCategoryMapping(26, TorznabCatType.ConsoleXbox360);      // GAMES
-            AddCategoryMapping(28, TorznabCatType.ConsoleWii);          // GAMES
-            AddCategoryMapping(27, TorznabCatType.ConsolePS3);          // GAMES
-            AddCategoryMapping(29, TorznabCatType.ConsoleNDS);          // GAMES
-            AddCategoryMapping(24, TorznabCatType.BooksEbook);          // EBOOKS
-            AddCategoryMapping(96, TorznabCatType.BooksEbook);          // EBOOKS MAGAZINES
-            AddCategoryMapping(99, TorznabCatType.BooksEbook);          // EBOOKS ANIME
-            AddCategoryMapping(23, TorznabCatType.PCPhoneAndroid);      // ANDROID
-
-            AddCategoryMapping(36, TorznabCatType.XXX);                 // XxX / Films
-            AddCategoryMapping(105, TorznabCatType.XXX);                // XxX / Séries
-            AddCategoryMapping(114, TorznabCatType.XXX);                // XxX / Lesbiennes 
-            AddCategoryMapping(115, TorznabCatType.XXX);                // XxX / Gays
-            AddCategoryMapping(113, TorznabCatType.XXX);                // XxX / Hentai
-        }
-
-        /// <summary>
-        /// Configure our Provider
-        /// </summary>
-        /// <param name="configJson">Our params in Json</param>
-        /// <returns>Configuration state</returns>
-        #pragma warning disable 1998
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        #pragma warning restore 1998
-        {
-            // Provider not yet configured
-            IsConfigured = false;
-
-            // Retrieve config values set by Jackett's user
-            LoadValuesFromJson(configJson);
-
-            // Check & Validate Config
-            ValidateConfig();
-
-            // Setting our data for a better emulated browser (maximum security)
-            // TODO: Encoded Content not supported by Jackett at this time
-            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
-
-            // Clean headers
-            EmulatedBrowserHeaders.Clear();
-
-            // Inject headers
-            EmulatedBrowserHeaders.Add("Accept", "application/json-rpc, application/json");
-            EmulatedBrowserHeaders.Add("Content-Type", "application/json-rpc");
-
-            // Tracker is now configured
-            IsConfigured = true;
-
-            // Saving data
-            SaveConfig();
-
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        /// <summary>
-        /// Execute our search query
-        /// </summary>
-        /// <param name="query">Query</param>
-        /// <returns>Releases</returns>
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            var releases = new List<ReleaseInfo>();
-            var searchTerm = query.GetQueryString();
-
-            // Check cache first so we don't query the server (if search term used or not in dev mode)
-            if(!DevMode && !string.IsNullOrEmpty(searchTerm))
-            {
-                lock (cache)
-                {
-                    // Remove old cache items
-                    CleanCache();
-
-                    // Search in cache
-                    var cachedResult = cache.FirstOrDefault(i => i.Query == searchTerm);
-                    if (cachedResult != null)
-                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
-                }
-            }
-
-            // Build our query
-            var request = BuildQuery(searchTerm, query, ApiEndpoint);
-
-            // Getting results & Store content
-            var results = await QueryExec(request);
-
-            try
-            {
-                // Deserialize our Json Response
-                var xthorResponse = JsonConvert.DeserializeObject<XthorResponse>(results.Content);
-
-                // Check Tracker's State
-                CheckApiState(xthorResponse.error);
-
-                // If contains torrents
-                if (xthorResponse.torrents != null)
-                {
-                    // Adding each torrent row to releases
-                    releases.AddRange(xthorResponse.torrents.Select(torrent => new ReleaseInfo
-                    {
-                        // Mapping data
-                        Category = MapTrackerCatToNewznab(torrent.category.ToString()),
-                        Title = torrent.name, Seeders = torrent.seeders,
-                        Peers = torrent.seeders + torrent.leechers,
-                        MinimumRatio = 1,
-                        MinimumSeedTime = 345600,
-                        PublishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.added),
-                        Size = torrent.size,
-                        Grabs = torrent.times_completed,
-                        Files = torrent.numfiles,
-                        UploadVolumeFactor = 1,
-                        DownloadVolumeFactor = (torrent.freeleech == 1 ? 0 : 1),
-                        Guid = new Uri(TorrentDescriptionUrl.Replace("{id}", torrent.id.ToString())),
-                        Comments = new Uri(TorrentCommentUrl.Replace("{id}", torrent.id.ToString())),
-                        Link = new Uri(torrent.download_link)
-                    }));
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
-            }
-
-            // Return found releases
-            return releases;
-        }
-
-        /// <summary>
-        /// Response from Tracker's API
-        /// </summary>
-        public class XthorResponse
-        {
-            public XthorError error { get; set; }
-            public XthorUser user { get; set; }
-            public List<XthorTorrent> torrents { get; set; }
-        }
-
-        /// <summary>
-        /// State of API
-        /// </summary>
-        public class XthorError
-        {
-            public int code { get; set; }
-            public string descr { get; set; }
-        }
-
-        /// <summary>
-        /// User Informations
-        /// </summary>
-        public class XthorUser
-        {
-            public int id { get; set; }
-            public string username { get; set; }
-            public long uploaded { get; set; }
-            public long downloaded { get; set; }
-            public int uclass { get; set; } // Class is a reserved keyword.
-            public decimal bonus_point { get; set; }
-            public int hits_and_run { get; set; }
-            public string avatar_url { get; set; }
-        }
-
-        /// <summary>
-        /// Torrent Informations
-        /// </summary>
-        public class XthorTorrent
-        {
-            public int id { get; set; }
-            public int category { get; set; }
-            public int seeders { get; set; }
-            public int leechers { get; set; }
-            public string name { get; set; }
-            public int times_completed { get; set; }
-            public long size { get; set; }
-            public int added { get; set; }
-            public int freeleech { get; set; }
-            public int numfiles { get; set; }
-            public string release_group { get; set; }
-            public string download_link { get; set; }
-        }
-
-        /// <summary>
-        /// Build query to process
-        /// </summary>
-        /// <param name="term">Term to search</param>
-        /// <param name="query">Torznab Query for categories mapping</param>
-        /// <param name="url">Search url for provider</param>
-        /// <returns>URL to query for parsing and processing results</returns>
-        private string BuildQuery(string term, TorznabQuery query, string url)
-        {
-            var parameters = new NameValueCollection();
-            var categoriesList = MapTorznabCapsToTrackers(query);
-
-            // Passkey
-            parameters.Add("passkey", ConfigData.PassKey.Value);
-
-            // If search term provided
-            if (!string.IsNullOrWhiteSpace(term))
-            {
-                // Add search term
-                // ReSharper disable once AssignNullToNotNullAttribute
-                parameters.Add("search", HttpUtility.UrlEncode(term));
-            }
-            else
-            {
-                parameters.Add("search", string.Empty);
-                // Showing all torrents (just for output function)
-                term = "all";
-            }
-
-            // Loop on Categories needed
-            switch (categoriesList.Count)
-            {
-                case 0:
-                    // No category
-                    parameters.Add("category", string.Empty);
-                    break;
-                case 1:
-                    // One category
-                    parameters.Add("category", categoriesList[0]);
-                    break;
-                default:
-                    // Multiple Categories
-                    string categories = null;
-                    foreach (var category in categoriesList)
-                    {
-                        // Initiate our categories parameter
-                        if (categoriesList.First() == category)
-                        {
-                            categories = categoriesList[0];
-                        }
-                        // Adding next categories
-                        categories += "+" + category;
-                    }
-                    // Add categories
-                    if (categories != null) parameters.Add("category", categories);
-                    break;
-            }
-
-            // If Only Freeleech Enabled
-            if (ConfigData.Freeleech.Value)
-            {
-                parameters.Add("freeleech", "1");
-            }
-
-            // Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong category param)
-            url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
-
-            Output("\nBuilded query for \"" + term + "\"... " + url);
-
-            // Return our search url
-            return url;
-        }
-
-        /// <summary>
-        /// Switch Method for Querying
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryExec(string request)
-        {
-            WebClientStringResult results;
-
-            // Switch in we are in DEV mode with Hard Drive Cache or not
-            if (DevMode && CacheMode)
-            {
-                // Check Cache before querying and load previous results if available
-                results = await QueryCache(request);
-            }
-            else
-            {
-                // Querying tracker directly
-                results = await QueryTracker(request);
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Cache by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryCache(string request)
-        {
-            WebClientStringResult results;
-
-            // Create Directory if not exist
-            System.IO.Directory.CreateDirectory(Directory);
-
-            // Clean Storage Provider Directory from outdated cached queries
-            CleanCacheStorage();
-
-            // Create fingerprint for request
-            string file = Directory + request.GetHashCode() + ".json";
-
-            // Checking modes states
-            if (System.IO.File.Exists(file))
-            {
-                // File exist... loading it right now !
-                Output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
-                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
-            }
-            else
-            {
-                // No cached file found, querying tracker directly
-                results = await QueryTracker(request);
-
-                // Cached file didn't exist for our query, writing it right now !
-                Output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
-                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
-            }
-            return results;
-        }
-
-        /// <summary>
-        /// Get Torrents Page from Tracker by Query Provided
-        /// </summary>
-        /// <param name="request">URL created by Query Builder</param>
-        /// <returns>Results from query</returns>
-        private async Task<WebClientStringResult> QueryTracker(string request)
-        {
-            // Cache mode not enabled or cached file didn't exist for our query
-            Output("\nQuerying tracker for results....");
-
-            // Build WebRequest for index
-            var myIndexRequest = new WebRequest()
-            {
-                Type = RequestType.GET,
-                Url = request,
-                Encoding = Encoding,
-                Headers = EmulatedBrowserHeaders
-            };
-
-            // Request our first page
-            var results = await webclient.GetString(myIndexRequest);
-
-            // Return results from tracker
-            return results;
-        }
-
-        /// <summary>
-        /// Check API's state
-        /// </summary>
-        /// <param name="state">State of API</param>
-        private void CheckApiState(XthorError state)
-        {
-            // Switch on state
-            switch (state.code)
-            {
-                case 0:
-                    // Everything OK
-                    Output("\nAPI State : Everything OK ... -> " + state.descr);
-                    break;
-                case 1:
-                    // Passkey not found
-                    Output("\nAPI State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
-                    throw new Exception("API State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
-                case 2:
-                    // No results
-                    Output("\nAPI State : No results for query ... -> " + state.descr);
-                    break;
-                case 3:
-                    // Power Saver
-                    Output("\nAPI State : Power Saver mode, only cached query with no parameters available ... -> " + state.descr);
-                    break;
-                case 4:
-                    // DDOS Attack, API disabled
-                    Output("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
-                    throw new Exception("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
-                default:
-                    // Unknown state
-                    Output("\nAPI State : Unknown state, aborting querying ... -> " + state.descr);
-                    throw new Exception("API State : Unknown state, aborting querying ... -> " + state.descr);
-            }
-        }
-
-        /// <summary>
-        /// Clean Hard Drive Cache Storage
-        /// </summary>
-        /// <param name="force">Force Provider Folder deletion</param>
-        private void CleanCacheStorage(bool force = false)
-        {
-            // Check cleaning method
-            if(force)
-            {
-                // Deleting Provider Storage folder and all files recursively
-                Output("\nDeleting Provider Storage folder and all files recursively ...");
-                
-                // Check if directory exist
-                if(System.IO.Directory.Exists(Directory))
-                {
-                    // Delete storage directory of provider
-                    System.IO.Directory.Delete(Directory, true);
-                    Output("-> Storage folder deleted successfully.");
-                }
-                else
-                {
-                    // No directory, so nothing to do
-                    Output("-> No Storage folder found for this provider !");
-                }
-            }
-            else
-            {
-                var i = 0;
-                // Check if there is file older than ... and delete them
-                Output("\nCleaning Provider Storage folder... in progress.");
-                System.IO.Directory.GetFiles(Directory)
-                .Select(f => new System.IO.FileInfo(f))
-                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
-                .ToList()
-                .ForEach(f => {
-                    Output("Deleting cached file << " + f.Name + " >> ... done.");
-                    f.Delete();
-                    i++;
-                    });
-
-                // Inform on what was cleaned during process
-                if(i > 0) {
-                    Output("-> Deleted " + i + " cached files during cleaning.");
-                }
-                else {
-                    Output("-> Nothing deleted during cleaning.");
-                }
-            }
-        }
-
-        /// <summary>
-        /// Output message for logging or developpment (console)
-        /// </summary>
-        /// <param name="message">Message to output</param>
-        /// <param name="level">Level for Logger</param>
-        private void Output(string message, string level = "debug")
-        {
-            // Check if we are in dev mode
-            if(DevMode)
-            {
-                // Output message to console
-                Console.WriteLine(message);
-            }
-            else
-            {
-                // Send message to logger with level
-                switch (level)
-                {
-                    default:
-                        goto case "debug";
-                    case "debug":
-                        // Only if Debug Level Enabled on Jackett
-                        if (Engine.Logger.IsDebugEnabled)
-                        {
-                            logger.Debug(message);
-                        }
-                        break;
-                    case "info":
-                        logger.Info(message);
-                        break;
-                    case "error":
-                        logger.Error(message);
-                        break;
-                }
-            }
-        }
-
-        /// <summary>
-        /// Validate Config entered by user on Jackett
-        /// </summary>
-        private void ValidateConfig()
-        {
-            Output("\nValidating Settings ... \n");
-
-            // Check Passkey Setting
-            if (string.IsNullOrEmpty(ConfigData.PassKey.Value))
-            {
-                throw new ExceptionWithConfigData("You must provide your passkey for this tracker to be allowed to use API !", ConfigData);
-            }
-            else
-            {
-                Output("Validated Setting -- PassKey (auth) => " + ConfigData.PassKey.Value);
-            }
-
-            // Check Dev Cache Settings
-            if (ConfigData.HardDriveCache.Value)
-            {
-                Output("\nValidated Setting -- DEV Hard Drive Cache enabled");
-
-                // Check if Dev Mode enabled !
-                if (!ConfigData.DevMode.Value)
-                {
-                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
-                }
-
-                // Check Cache Keep Time Setting
-                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
-                {
-                    try
-                    {
-                        Output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
-                    }
-                    catch (Exception)
-                    {
-                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
-                    }
-                }
-                else
-                {
-                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
-                }
-            }
-            else
-            {
-                // Delete cache if previously existed
-                CleanCacheStorage(true);
-            }
-        }
-    }
+using System;
+using System.Collections.Generic;
+using System.Collections.Specialized;
+using System.Linq;
+using System.Text;
+using System.Reflection;
+using System.Threading.Tasks;
+using System.Web;
+using Jackett.Models;
+using Jackett.Models.IndexerConfig.Bespoke;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using NLog;
+
+namespace Jackett.Indexers
+{
+    /// <summary>
+    /// Provider for Xthor Private French Tracker
+    /// </summary>
+    public class Xthor : BaseIndexer, IIndexer
+    {
+        private static string ApiEndpoint => "https://api.xthor.bz/";
+        private string TorrentCommentUrl => TorrentDescriptionUrl;
+        private string TorrentDescriptionUrl => SiteLink + "details.php?id={id}";
+        private bool DevMode => ConfigData.DevMode.Value;
+        private bool CacheMode => ConfigData.HardDriveCache.Value;
+        private static string Directory => System.IO.Path.GetTempPath() + "Jackett\\" + MethodBase.GetCurrentMethod().DeclaringType?.Name + "\\";
+        public Dictionary<string, string> EmulatedBrowserHeaders { get; } = new Dictionary<string, string>();
+        private ConfigurationDataXthor ConfigData => (ConfigurationDataXthor)configData;
+
+        public Xthor(IIndexerManagerService i, IWebClient w, Logger l, IProtectionService ps)
+            : base(
+                name: "Xthor",
+                description: "General French Private Tracker",
+                link: "https://xthor.bz/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                downloadBase: "https://xthor.bz/download.php?torrent=",
+                configData: new ConfigurationDataXthor())
+        {
+            Encoding = Encoding.UTF8;
+            Language = "fr-fr";
+            Type = "private";
+
+            // Clean capabilities
+            TorznabCaps.Categories.Clear();
+
+            // Movies
+            AddCategoryMapping(6, TorznabCatType.MoviesSD);             // XVID
+            AddCategoryMapping(7, TorznabCatType.MoviesSD);             // X264
+            AddCategoryMapping(95, TorznabCatType.MoviesSD);            // WEBRIP
+            AddCategoryMapping(5, TorznabCatType.MoviesHD);             // HD 720P
+            AddCategoryMapping(4, TorznabCatType.MoviesHD);             // HD 1080P X264
+            AddCategoryMapping(100, TorznabCatType.MoviesHD);           // HD 1080P X265
+            AddCategoryMapping(94, TorznabCatType.MoviesHD);            // WEBDL
+            AddCategoryMapping(1, TorznabCatType.MoviesBluRay);         // FULL BLURAY
+            AddCategoryMapping(2, TorznabCatType.MoviesBluRay);         // BLURAY REMUX
+            AddCategoryMapping(3, TorznabCatType.MoviesBluRay);         // FULL BLURAY 3D
+            AddCategoryMapping(8, TorznabCatType.MoviesDVD);            // FULL DVD
+            AddCategoryMapping(9, TorznabCatType.MoviesOther);          // VOSTFR
+            AddCategoryMapping(36, TorznabCatType.XXX);                 // XXX
+
+            // Series
+            AddCategoryMapping(14, TorznabCatType.TVSD);                // SD VF
+            AddCategoryMapping(16, TorznabCatType.TVSD);                // SD VF VOSTFR
+            AddCategoryMapping(15, TorznabCatType.TVHD);                // HD VF
+            AddCategoryMapping(17, TorznabCatType.TVHD);                // HD VF VOSTFR
+            AddCategoryMapping(13, TorznabCatType.TVOTHER);             // PACK
+            AddCategoryMapping(98, TorznabCatType.TVOTHER);             // PACK VOSTFR HD
+            AddCategoryMapping(16, TorznabCatType.TVOTHER);             // PACK VOSTFR SD
+            AddCategoryMapping(30, TorznabCatType.TVOTHER);             // EMISSIONS
+            AddCategoryMapping(34, TorznabCatType.TVOTHER);             // EMISSIONS
+            AddCategoryMapping(33, TorznabCatType.TVOTHER);             // SHOWS
+
+            // Anime
+            AddCategoryMapping(31, TorznabCatType.TVAnime);             // MOVIES ANIME
+            AddCategoryMapping(32, TorznabCatType.TVAnime);             // SERIES ANIME
+
+            // Documentaries
+            AddCategoryMapping(12, TorznabCatType.TVDocumentary);       // DOCS
+
+            // Music
+            AddCategoryMapping(20, TorznabCatType.AudioVideo);          // CONCERT
+
+            // Other
+            AddCategoryMapping(21, TorznabCatType.PC);                  // PC
+            AddCategoryMapping(22, TorznabCatType.PCMac);               // PC
+            AddCategoryMapping(25, TorznabCatType.PCGames);             // GAMES
+            AddCategoryMapping(26, TorznabCatType.ConsoleXbox360);      // GAMES
+            AddCategoryMapping(28, TorznabCatType.ConsoleWii);          // GAMES
+            AddCategoryMapping(27, TorznabCatType.ConsolePS3);          // GAMES
+            AddCategoryMapping(29, TorznabCatType.ConsoleNDS);          // GAMES
+            AddCategoryMapping(24, TorznabCatType.BooksEbook);          // EBOOKS
+            AddCategoryMapping(96, TorznabCatType.BooksEbook);          // EBOOKS MAGAZINES
+            AddCategoryMapping(99, TorznabCatType.BooksEbook);          // EBOOKS ANIME
+            AddCategoryMapping(23, TorznabCatType.PCPhoneAndroid);      // ANDROID
+
+            AddCategoryMapping(36, TorznabCatType.XXX);                 // XxX / Films
+            AddCategoryMapping(105, TorznabCatType.XXX);                // XxX / Séries
+            AddCategoryMapping(114, TorznabCatType.XXX);                // XxX / Lesbiennes 
+            AddCategoryMapping(115, TorznabCatType.XXX);                // XxX / Gays
+            AddCategoryMapping(113, TorznabCatType.XXX);                // XxX / Hentai
+        }
+
+        /// <summary>
+        /// Configure our Provider
+        /// </summary>
+        /// <param name="configJson">Our params in Json</param>
+        /// <returns>Configuration state</returns>
+        #pragma warning disable 1998
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        #pragma warning restore 1998
+        {
+            // Provider not yet configured
+            IsConfigured = false;
+
+            // Retrieve config values set by Jackett's user
+            LoadValuesFromJson(configJson);
+
+            // Check & Validate Config
+            ValidateConfig();
+
+            // Setting our data for a better emulated browser (maximum security)
+            // TODO: Encoded Content not supported by Jackett at this time
+            // emulatedBrowserHeaders.Add("Accept-Encoding", "gzip, deflate");
+
+            // Clean headers
+            EmulatedBrowserHeaders.Clear();
+
+            // Inject headers
+            EmulatedBrowserHeaders.Add("Accept", "application/json-rpc, application/json");
+            EmulatedBrowserHeaders.Add("Content-Type", "application/json-rpc");
+
+            // Tracker is now configured
+            IsConfigured = true;
+
+            // Saving data
+            SaveConfig();
+
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        /// <summary>
+        /// Execute our search query
+        /// </summary>
+        /// <param name="query">Query</param>
+        /// <returns>Releases</returns>
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            var releases = new List<ReleaseInfo>();
+            var searchTerm = query.GetQueryString();
+
+            // Check cache first so we don't query the server (if search term used or not in dev mode)
+            if(!DevMode && !string.IsNullOrEmpty(searchTerm))
+            {
+                lock (cache)
+                {
+                    // Remove old cache items
+                    CleanCache();
+
+                    // Search in cache
+                    var cachedResult = cache.FirstOrDefault(i => i.Query == searchTerm);
+                    if (cachedResult != null)
+                        return cachedResult.Results.Select(s => (ReleaseInfo)s.Clone()).ToArray();
+                }
+            }
+
+            // Build our query
+            var request = BuildQuery(searchTerm, query, ApiEndpoint);
+
+            // Getting results & Store content
+            var results = await QueryExec(request);
+
+            try
+            {
+                // Deserialize our Json Response
+                var xthorResponse = JsonConvert.DeserializeObject<XthorResponse>(results.Content);
+
+                // Check Tracker's State
+                CheckApiState(xthorResponse.error);
+
+                // If contains torrents
+                if (xthorResponse.torrents != null)
+                {
+                    // Adding each torrent row to releases
+                    releases.AddRange(xthorResponse.torrents.Select(torrent => new ReleaseInfo
+                    {
+                        // Mapping data
+                        Category = MapTrackerCatToNewznab(torrent.category.ToString()),
+                        Title = torrent.name, Seeders = torrent.seeders,
+                        Peers = torrent.seeders + torrent.leechers,
+                        MinimumRatio = 1,
+                        MinimumSeedTime = 345600,
+                        PublishDate = DateTimeUtil.UnixTimestampToDateTime(torrent.added),
+                        Size = torrent.size,
+                        Grabs = torrent.times_completed,
+                        Files = torrent.numfiles,
+                        UploadVolumeFactor = 1,
+                        DownloadVolumeFactor = (torrent.freeleech == 1 ? 0 : 1),
+                        Guid = new Uri(TorrentDescriptionUrl.Replace("{id}", torrent.id.ToString())),
+                        Comments = new Uri(TorrentCommentUrl.Replace("{id}", torrent.id.ToString())),
+                        Link = new Uri(torrent.download_link)
+                    }));
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError("Error, unable to parse result \n" + ex.StackTrace, ex);
+            }
+
+            // Return found releases
+            return releases;
+        }
+
+        /// <summary>
+        /// Response from Tracker's API
+        /// </summary>
+        public class XthorResponse
+        {
+            public XthorError error { get; set; }
+            public XthorUser user { get; set; }
+            public List<XthorTorrent> torrents { get; set; }
+        }
+
+        /// <summary>
+        /// State of API
+        /// </summary>
+        public class XthorError
+        {
+            public int code { get; set; }
+            public string descr { get; set; }
+        }
+
+        /// <summary>
+        /// User Informations
+        /// </summary>
+        public class XthorUser
+        {
+            public int id { get; set; }
+            public string username { get; set; }
+            public long uploaded { get; set; }
+            public long downloaded { get; set; }
+            public int uclass { get; set; } // Class is a reserved keyword.
+            public decimal bonus_point { get; set; }
+            public int hits_and_run { get; set; }
+            public string avatar_url { get; set; }
+        }
+
+        /// <summary>
+        /// Torrent Informations
+        /// </summary>
+        public class XthorTorrent
+        {
+            public int id { get; set; }
+            public int category { get; set; }
+            public int seeders { get; set; }
+            public int leechers { get; set; }
+            public string name { get; set; }
+            public int times_completed { get; set; }
+            public long size { get; set; }
+            public int added { get; set; }
+            public int freeleech { get; set; }
+            public int numfiles { get; set; }
+            public string release_group { get; set; }
+            public string download_link { get; set; }
+        }
+
+        /// <summary>
+        /// Build query to process
+        /// </summary>
+        /// <param name="term">Term to search</param>
+        /// <param name="query">Torznab Query for categories mapping</param>
+        /// <param name="url">Search url for provider</param>
+        /// <returns>URL to query for parsing and processing results</returns>
+        private string BuildQuery(string term, TorznabQuery query, string url)
+        {
+            var parameters = new NameValueCollection();
+            var categoriesList = MapTorznabCapsToTrackers(query);
+
+            // Passkey
+            parameters.Add("passkey", ConfigData.PassKey.Value);
+
+            // If search term provided
+            if (!string.IsNullOrWhiteSpace(term))
+            {
+                // Add search term
+                // ReSharper disable once AssignNullToNotNullAttribute
+                parameters.Add("search", HttpUtility.UrlEncode(term));
+            }
+            else
+            {
+                parameters.Add("search", string.Empty);
+                // Showing all torrents (just for output function)
+                term = "all";
+            }
+
+            // Loop on Categories needed
+            switch (categoriesList.Count)
+            {
+                case 0:
+                    // No category
+                    parameters.Add("category", string.Empty);
+                    break;
+                case 1:
+                    // One category
+                    parameters.Add("category", categoriesList[0]);
+                    break;
+                default:
+                    // Multiple Categories
+                    string categories = null;
+                    foreach (var category in categoriesList)
+                    {
+                        // Initiate our categories parameter
+                        if (categoriesList.First() == category)
+                        {
+                            categories = categoriesList[0];
+                        }
+                        // Adding next categories
+                        categories += "+" + category;
+                    }
+                    // Add categories
+                    if (categories != null) parameters.Add("category", categories);
+                    break;
+            }
+
+            // If Only Freeleech Enabled
+            if (ConfigData.Freeleech.Value)
+            {
+                parameters.Add("freeleech", "1");
+            }
+
+            // Building our query -- Cannot use GetQueryString due to UrlEncode (generating wrong category param)
+            url += "?" + string.Join("&", parameters.AllKeys.Select(a => a + "=" + parameters[a]));
+
+            Output("\nBuilded query for \"" + term + "\"... " + url);
+
+            // Return our search url
+            return url;
+        }
+
+        /// <summary>
+        /// Switch Method for Querying
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryExec(string request)
+        {
+            WebClientStringResult results;
+
+            // Switch in we are in DEV mode with Hard Drive Cache or not
+            if (DevMode && CacheMode)
+            {
+                // Check Cache before querying and load previous results if available
+                results = await QueryCache(request);
+            }
+            else
+            {
+                // Querying tracker directly
+                results = await QueryTracker(request);
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Cache by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryCache(string request)
+        {
+            WebClientStringResult results;
+
+            // Create Directory if not exist
+            System.IO.Directory.CreateDirectory(Directory);
+
+            // Clean Storage Provider Directory from outdated cached queries
+            CleanCacheStorage();
+
+            // Create fingerprint for request
+            string file = Directory + request.GetHashCode() + ".json";
+
+            // Checking modes states
+            if (System.IO.File.Exists(file))
+            {
+                // File exist... loading it right now !
+                Output("Loading results from hard drive cache ..." + request.GetHashCode() + ".json");
+                results = JsonConvert.DeserializeObject<WebClientStringResult>(System.IO.File.ReadAllText(file));
+            }
+            else
+            {
+                // No cached file found, querying tracker directly
+                results = await QueryTracker(request);
+
+                // Cached file didn't exist for our query, writing it right now !
+                Output("Writing results to hard drive cache ..." + request.GetHashCode() + ".json");
+                System.IO.File.WriteAllText(file, JsonConvert.SerializeObject(results));
+            }
+            return results;
+        }
+
+        /// <summary>
+        /// Get Torrents Page from Tracker by Query Provided
+        /// </summary>
+        /// <param name="request">URL created by Query Builder</param>
+        /// <returns>Results from query</returns>
+        private async Task<WebClientStringResult> QueryTracker(string request)
+        {
+            // Cache mode not enabled or cached file didn't exist for our query
+            Output("\nQuerying tracker for results....");
+
+            // Build WebRequest for index
+            var myIndexRequest = new WebRequest()
+            {
+                Type = RequestType.GET,
+                Url = request,
+                Encoding = Encoding,
+                Headers = EmulatedBrowserHeaders
+            };
+
+            // Request our first page
+            var results = await webclient.GetString(myIndexRequest);
+
+            // Return results from tracker
+            return results;
+        }
+
+        /// <summary>
+        /// Check API's state
+        /// </summary>
+        /// <param name="state">State of API</param>
+        private void CheckApiState(XthorError state)
+        {
+            // Switch on state
+            switch (state.code)
+            {
+                case 0:
+                    // Everything OK
+                    Output("\nAPI State : Everything OK ... -> " + state.descr);
+                    break;
+                case 1:
+                    // Passkey not found
+                    Output("\nAPI State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
+                    throw new Exception("API State : Error, Passkey not found in tracker's database, aborting... -> " + state.descr);
+                case 2:
+                    // No results
+                    Output("\nAPI State : No results for query ... -> " + state.descr);
+                    break;
+                case 3:
+                    // Power Saver
+                    Output("\nAPI State : Power Saver mode, only cached query with no parameters available ... -> " + state.descr);
+                    break;
+                case 4:
+                    // DDOS Attack, API disabled
+                    Output("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
+                    throw new Exception("\nAPI State : Tracker is under DDOS attack, API disabled, aborting ... -> " + state.descr);
+                default:
+                    // Unknown state
+                    Output("\nAPI State : Unknown state, aborting querying ... -> " + state.descr);
+                    throw new Exception("API State : Unknown state, aborting querying ... -> " + state.descr);
+            }
+        }
+
+        /// <summary>
+        /// Clean Hard Drive Cache Storage
+        /// </summary>
+        /// <param name="force">Force Provider Folder deletion</param>
+        private void CleanCacheStorage(bool force = false)
+        {
+            // Check cleaning method
+            if(force)
+            {
+                // Deleting Provider Storage folder and all files recursively
+                Output("\nDeleting Provider Storage folder and all files recursively ...");
+                
+                // Check if directory exist
+                if(System.IO.Directory.Exists(Directory))
+                {
+                    // Delete storage directory of provider
+                    System.IO.Directory.Delete(Directory, true);
+                    Output("-> Storage folder deleted successfully.");
+                }
+                else
+                {
+                    // No directory, so nothing to do
+                    Output("-> No Storage folder found for this provider !");
+                }
+            }
+            else
+            {
+                var i = 0;
+                // Check if there is file older than ... and delete them
+                Output("\nCleaning Provider Storage folder... in progress.");
+                System.IO.Directory.GetFiles(Directory)
+                .Select(f => new System.IO.FileInfo(f))
+                .Where(f => f.LastAccessTime < DateTime.Now.AddMilliseconds(-Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value)))
+                .ToList()
+                .ForEach(f => {
+                    Output("Deleting cached file << " + f.Name + " >> ... done.");
+                    f.Delete();
+                    i++;
+                    });
+
+                // Inform on what was cleaned during process
+                if(i > 0) {
+                    Output("-> Deleted " + i + " cached files during cleaning.");
+                }
+                else {
+                    Output("-> Nothing deleted during cleaning.");
+                }
+            }
+        }
+
+        /// <summary>
+        /// Output message for logging or developpment (console)
+        /// </summary>
+        /// <param name="message">Message to output</param>
+        /// <param name="level">Level for Logger</param>
+        private void Output(string message, string level = "debug")
+        {
+            // Check if we are in dev mode
+            if(DevMode)
+            {
+                // Output message to console
+                Console.WriteLine(message);
+            }
+            else
+            {
+                // Send message to logger with level
+                switch (level)
+                {
+                    default:
+                        goto case "debug";
+                    case "debug":
+                        // Only if Debug Level Enabled on Jackett
+                        if (Engine.Logger.IsDebugEnabled)
+                        {
+                            logger.Debug(message);
+                        }
+                        break;
+                    case "info":
+                        logger.Info(message);
+                        break;
+                    case "error":
+                        logger.Error(message);
+                        break;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Validate Config entered by user on Jackett
+        /// </summary>
+        private void ValidateConfig()
+        {
+            Output("\nValidating Settings ... \n");
+
+            // Check Passkey Setting
+            if (string.IsNullOrEmpty(ConfigData.PassKey.Value))
+            {
+                throw new ExceptionWithConfigData("You must provide your passkey for this tracker to be allowed to use API !", ConfigData);
+            }
+            else
+            {
+                Output("Validated Setting -- PassKey (auth) => " + ConfigData.PassKey.Value);
+            }
+
+            // Check Dev Cache Settings
+            if (ConfigData.HardDriveCache.Value)
+            {
+                Output("\nValidated Setting -- DEV Hard Drive Cache enabled");
+
+                // Check if Dev Mode enabled !
+                if (!ConfigData.DevMode.Value)
+                {
+                    throw new ExceptionWithConfigData("Hard Drive is enabled but not in DEV MODE, Please enable DEV MODE !", ConfigData);
+                }
+
+                // Check Cache Keep Time Setting
+                if (!string.IsNullOrEmpty(ConfigData.HardDriveCacheKeepTime.Value))
+                {
+                    try
+                    {
+                        Output("Validated Setting -- Cache Keep Time (ms) => " + Convert.ToInt32(ConfigData.HardDriveCacheKeepTime.Value));
+                    }
+                    catch (Exception)
+                    {
+                        throw new ExceptionWithConfigData("Please enter a numeric hard drive keep time in ms !", ConfigData);
+                    }
+                }
+                else
+                {
+                    throw new ExceptionWithConfigData("Hard Drive Cache enabled, Please enter a maximum keep time for cache !", ConfigData);
+                }
+            }
+            else
+            {
+                // Delete cache if previously existed
+                CleanCacheStorage(true);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/cgpeers.cs b/src/Jackett/Indexers/cgpeers.cs
index 84615c4e3c1c6c9c810d8644989e083f38d87239..501fbe61458b17d1801cf0cdef4917815953c1a2 100644
--- a/src/Jackett/Indexers/cgpeers.cs
+++ b/src/Jackett/Indexers/cgpeers.cs
@@ -2,8 +2,8 @@
 using NLog;
 using Jackett.Services;
 using Jackett.Utils.Clients;
-using Jackett.Indexers.Abstract;
-
+using Jackett.Indexers.Abstract;
+
 namespace Jackett.Indexers
 {
     public class CGPeers : GazelleTracker, IIndexer
@@ -21,13 +21,13 @@ namespace Jackett.Indexers
             Language = "en-us";
             Type = "private";
 
-            AddCategoryMapping(1, TorznabCatType.PCISO, "Full Applications");
-            AddCategoryMapping(2, TorznabCatType.PC0day, "Plugins");
-            AddCategoryMapping(3, TorznabCatType.Other, "Tutorials");
-            AddCategoryMapping(4, TorznabCatType.Other, "Models");
-            AddCategoryMapping(5, TorznabCatType.Other, "Materials");
-            AddCategoryMapping(6, TorznabCatType.OtherMisc, "Misc");
-            AddCategoryMapping(7, TorznabCatType.Other, "GameDev");
+            AddCategoryMapping(1, TorznabCatType.PCISO, "Full Applications");
+            AddCategoryMapping(2, TorznabCatType.PC0day, "Plugins");
+            AddCategoryMapping(3, TorznabCatType.Other, "Tutorials");
+            AddCategoryMapping(4, TorznabCatType.Other, "Models");
+            AddCategoryMapping(5, TorznabCatType.Other, "Materials");
+            AddCategoryMapping(6, TorznabCatType.OtherMisc, "Misc");
+            AddCategoryMapping(7, TorznabCatType.Other, "GameDev");
         }
     }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/myAmity.cs b/src/Jackett/Indexers/myAmity.cs
index 758238787a7c5dbcc0f0395922a004fbc47e81ba..8bc14b18730799ddeecd0675108d02bf550cd539 100644
--- a/src/Jackett/Indexers/myAmity.cs
+++ b/src/Jackett/Indexers/myAmity.cs
@@ -10,9 +10,9 @@ using CsQuery;
 using System;
 using System.Globalization;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using System.Text;
-
+using System.Collections.Specialized;
+using System.Text;
+
 namespace Jackett.Indexers
 {
     public class myAmity : BaseIndexer, IIndexer
@@ -41,23 +41,23 @@ namespace Jackett.Indexers
             Language = "de-de";
             Type = "private";
 
-            AddCategoryMapping(20, TorznabCatType.PC); // Apps - PC
-            AddCategoryMapping(24, TorznabCatType.AudioAudiobook); // Audio - Hoerbuch/-spiel
-            AddCategoryMapping(22, TorznabCatType.Audio); // Audio - Musik
-            AddCategoryMapping(52, TorznabCatType.Movies3D); // Filme - 3D
-            AddCategoryMapping(51, TorznabCatType.MoviesBluRay); // Filme - BluRay Complete
-            AddCategoryMapping(1,  TorznabCatType.MoviesDVD); // Filme - DVD
-            AddCategoryMapping(54, TorznabCatType.MoviesHD); // Filme - HD/1080p
-            AddCategoryMapping(3,  TorznabCatType.MoviesHD); // Filme - HD/720p
-            AddCategoryMapping(48, TorznabCatType.XXX); // Filme - Heimatfilme.XXX
-            AddCategoryMapping(50, TorznabCatType.Movies); // Filme - x264/H.264
-            AddCategoryMapping(2,  TorznabCatType.MoviesSD); // Filme - XViD
-            AddCategoryMapping(11, TorznabCatType.Console); // Games - Konsolen
-            AddCategoryMapping(10, TorznabCatType.PCGames); // Games - PC
-            AddCategoryMapping(53, TorznabCatType.Other); // International - Complete
-            AddCategoryMapping(36, TorznabCatType.Books); // Sonstige - E-Books
-            AddCategoryMapping(38, TorznabCatType.Other); // Sonstige - Handy
-            AddCategoryMapping(7,  TorznabCatType.TVDocumentary); // TV/HDTV - Dokus
+            AddCategoryMapping(20, TorznabCatType.PC); // Apps - PC
+            AddCategoryMapping(24, TorznabCatType.AudioAudiobook); // Audio - Hoerbuch/-spiel
+            AddCategoryMapping(22, TorznabCatType.Audio); // Audio - Musik
+            AddCategoryMapping(52, TorznabCatType.Movies3D); // Filme - 3D
+            AddCategoryMapping(51, TorznabCatType.MoviesBluRay); // Filme - BluRay Complete
+            AddCategoryMapping(1,  TorznabCatType.MoviesDVD); // Filme - DVD
+            AddCategoryMapping(54, TorznabCatType.MoviesHD); // Filme - HD/1080p
+            AddCategoryMapping(3,  TorznabCatType.MoviesHD); // Filme - HD/720p
+            AddCategoryMapping(48, TorznabCatType.XXX); // Filme - Heimatfilme.XXX
+            AddCategoryMapping(50, TorznabCatType.Movies); // Filme - x264/H.264
+            AddCategoryMapping(2,  TorznabCatType.MoviesSD); // Filme - XViD
+            AddCategoryMapping(11, TorznabCatType.Console); // Games - Konsolen
+            AddCategoryMapping(10, TorznabCatType.PCGames); // Games - PC
+            AddCategoryMapping(53, TorznabCatType.Other); // International - Complete
+            AddCategoryMapping(36, TorznabCatType.Books); // Sonstige - E-Books
+            AddCategoryMapping(38, TorznabCatType.Other); // Sonstige - Handy
+            AddCategoryMapping(7,  TorznabCatType.TVDocumentary); // TV/HDTV - Dokus
             AddCategoryMapping(8,  TorznabCatType.TV); // TV/HDTV - Serien
         }
 
@@ -71,53 +71,53 @@ namespace Jackett.Indexers
                 { "password", configData.Password.Value }
             };
 
-            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
-
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Cookies.Contains("pass=") && !result.Cookies.Contains("deleted"), () =>
-            {
-                CQ dom = result.Content;
-                var errorMessage = dom["div.myFrame-content"].Html();
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, null, true, null, LoginUrl, true);
+
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Cookies.Contains("pass=") && !result.Cookies.Contains("deleted"), () =>
+            {
+                CQ dom = result.Content;
+                var errorMessage = dom["div.myFrame-content"].Html();
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
 
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
-            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
-            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
-            TimeSpan delta = new TimeSpan(1, 0, 0);
-            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
-            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
+            TimeZoneInfo.TransitionTime startTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 3, 0, 0), 3, 5, DayOfWeek.Sunday);
+            TimeZoneInfo.TransitionTime endTransition = TimeZoneInfo.TransitionTime.CreateFloatingDateRule(new DateTime(1, 1, 1, 4, 0, 0), 10, 5, DayOfWeek.Sunday);
+            TimeSpan delta = new TimeSpan(1, 0, 0);
+            TimeZoneInfo.AdjustmentRule adjustment = TimeZoneInfo.AdjustmentRule.CreateAdjustmentRule(new DateTime(1999, 10, 1), DateTime.MaxValue.Date, delta, startTransition, endTransition);
+            TimeZoneInfo.AdjustmentRule[] adjustments = { adjustment };
             TimeZoneInfo germanyTz = TimeZoneInfo.CreateCustomTimeZone("W. Europe Standard Time", new TimeSpan(1, 0, 0), "(GMT+01:00) W. Europe Standard Time", "W. Europe Standard Time", "W. Europe DST Time", adjustments);
 
             var releases = new List<ReleaseInfo>();
             
-            var searchString = query.GetQueryString();
-            var searchUrl = BrowseUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("freeleech", "0");
-            queryCollection.Add("inclexternal", "0");
-            queryCollection.Add("lang", "0");
-
-            if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
+            var searchString = query.GetQueryString();
+            var searchUrl = BrowseUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("freeleech", "0");
+            queryCollection.Add("inclexternal", "0");
+            queryCollection.Add("lang", "0");
+
+            if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
             searchUrl += "?" + queryCollection.GetQueryString();
 
             var response = await RequestStringWithCookies(searchUrl);
-            if (response.IsRedirect)
-            {
-                // re-login
-                await ApplyConfiguration(null);
-                response = await RequestStringWithCookies(searchUrl);
+            if (response.IsRedirect)
+            {
+                // re-login
+                await ApplyConfiguration(null);
+                response = await RequestStringWithCookies(searchUrl);
             }
 
             var results = response.Content;
@@ -129,48 +129,48 @@ namespace Jackett.Indexers
                 foreach (var row in rows)
                 {
                     var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
+                    release.MinimumRatio = 1;
                     release.MinimumSeedTime = 90 * 60;
 
-                    var qRow = row.Cq();
-
-                    var qDetailsLink = qRow.Find("a[href^=torrents-details.php?id=]").First();
-                    release.Title = qDetailsLink.Attr("title");
-
-                    if (!query.MatchQueryStringAND(release.Title))
-                        continue;
-
-                    var qCatLink = qRow.Find("a[href^=torrents.php?cat=]").First();
-                    var qDLLink = qRow.Find("a[href^=download.php]").First();
-                    var qSeeders = qRow.Find("td:eq(6)");
-                    var qLeechers = qRow.Find("td:eq(7)");
-                    var qDateStr = qRow.Find("td:eq(9)").First();
-                    var qSize = qRow.Find("td:eq(4)").First();
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    var qRow = row.Cq();
+
+                    var qDetailsLink = qRow.Find("a[href^=torrents-details.php?id=]").First();
+                    release.Title = qDetailsLink.Attr("title");
+
+                    if (!query.MatchQueryStringAND(release.Title))
+                        continue;
+
+                    var qCatLink = qRow.Find("a[href^=torrents.php?cat=]").First();
+                    var qDLLink = qRow.Find("a[href^=download.php]").First();
+                    var qSeeders = qRow.Find("td:eq(6)");
+                    var qLeechers = qRow.Find("td:eq(7)");
+                    var qDateStr = qRow.Find("td:eq(9)").First();
+                    var qSize = qRow.Find("td:eq(4)").First();
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDLLink.Attr("href"));
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
                     release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
 
                     var dateStr = qDateStr.Text().Trim();
-                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
-
-                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
+                    DateTime dateGerman = DateTime.SpecifyKind(DateTime.ParseExact(dateStr, "dd.MM.yy HH:mm:ss", CultureInfo.InvariantCulture), DateTimeKind.Unspecified);
+
+                    DateTime pubDateUtc = TimeZoneInfo.ConvertTimeToUtc(dateGerman, germanyTz);
                     release.PublishDate = pubDateUtc.ToLocalTime();
 
                     var grabs = qRow.Find("td:nth-child(6)").Text();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (qRow.Find("img[src=\"images/free.gif\"]").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (qRow.Find("img[src=\"images/free.gif\"]").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
                         release.DownloadVolumeFactor = 1;
 
diff --git a/src/Jackett/Indexers/notwhatcd.cs b/src/Jackett/Indexers/notwhatcd.cs
index ba6e7e3f025f6efc41c925e1dbc43655b4d965b2..cfec3298f17f2d54b6adc657d7140e746a8623ce 100644
--- a/src/Jackett/Indexers/notwhatcd.cs
+++ b/src/Jackett/Indexers/notwhatcd.cs
@@ -2,8 +2,8 @@
 using NLog;
 using Jackett.Services;
 using Jackett.Utils.Clients;
-using Jackett.Indexers.Abstract;
-
+using Jackett.Indexers.Abstract;
+
 namespace Jackett.Indexers
 {
     public class notwhatcd : GazelleTracker, IIndexer
@@ -22,12 +22,12 @@ namespace Jackett.Indexers
             Type = "private";
 
             AddCategoryMapping(1, TorznabCatType.Audio, "Music");
-            AddCategoryMapping(2, TorznabCatType.PC, "Applications");
-            AddCategoryMapping(3, TorznabCatType.Books, "E-Books");
-            AddCategoryMapping(4, TorznabCatType.AudioAudiobook, "Audiobooks");
-            AddCategoryMapping(5, TorznabCatType.Movies, "E-Learning Videos");
-            AddCategoryMapping(6, TorznabCatType.TV, "Comedy");
-            AddCategoryMapping(7, TorznabCatType.Books, "Comics");
+            AddCategoryMapping(2, TorznabCatType.PC, "Applications");
+            AddCategoryMapping(3, TorznabCatType.Books, "E-Books");
+            AddCategoryMapping(4, TorznabCatType.AudioAudiobook, "Audiobooks");
+            AddCategoryMapping(5, TorznabCatType.Movies, "E-Learning Videos");
+            AddCategoryMapping(6, TorznabCatType.TV, "Comedy");
+            AddCategoryMapping(7, TorznabCatType.Books, "Comics");
         }
     }
 }
\ No newline at end of file
diff --git a/src/Jackett/Indexers/rutracker.cs b/src/Jackett/Indexers/rutracker.cs
index 1a6f0fa68b4466cfc4de620b221c701bca3b66dc..79b4c7311f6cd461862595f9809fb9ea13eb4c0a 100644
--- a/src/Jackett/Indexers/rutracker.cs
+++ b/src/Jackett/Indexers/rutracker.cs
@@ -9,9 +9,9 @@ using System.Collections.Generic;
 using System;
 using System.Text;
 using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-using AngleSharp.Parser.Html;
-
+using System.Collections.Specialized;
+using AngleSharp.Parser.Html;
+
 namespace Jackett.Indexers
 {
     public class RuTracker : BaseIndexer, IIndexer
@@ -38,1422 +38,1422 @@ namespace Jackett.Indexers
                    logger: l,
                    p: ps,
                    configData: new ConfigurationDataCaptchaLogin())
-        {
+        {
             Encoding = Encoding.GetEncoding("windows-1251");
-            Language = "ru-ru";
-            Type = "semi-private";
-
-            // Новости
-            AddCategoryMapping(2317, TorznabCatType.Other, "NEW YEAR'S SECTION");
-            AddCategoryMapping(1241, TorznabCatType.Other, " | - New competitions");
-            AddCategoryMapping(2338, TorznabCatType.TV, " | - Entertainment shows and Documentaries");
-            AddCategoryMapping(1464, TorznabCatType.Movies, " | - Movies and Cartoons");
-            AddCategoryMapping(860, TorznabCatType.Books, " | - Books, Journals, Notes");
-            AddCategoryMapping(1340, TorznabCatType.Audio, " | - Music");
-            AddCategoryMapping(1346, TorznabCatType.AudioVideo, " | - Music video");
-            AddCategoryMapping(1239, TorznabCatType.Console, " | - Games");
-            AddCategoryMapping(1299, TorznabCatType.Other, " | - Miscellaneous (postcards, wallpapers, video, etc.).");
-            AddCategoryMapping(1289, TorznabCatType.Other, "Rutracker Awards (events and competitions)");
-            AddCategoryMapping(1579, TorznabCatType.Other, "| - Photo club. The whole world is in the palm of your hand.");
-            AddCategoryMapping(2214, TorznabCatType.Other, " | - Rutracker Awards (distribution)");
-
-            // Кино, Видео и ТВ
-            AddCategoryMapping(7, TorznabCatType.MoviesForeign, "Foreign movies");
-            AddCategoryMapping(187, TorznabCatType.MoviesForeign, " | - Classic of world cinema");
-            AddCategoryMapping(2090, TorznabCatType.MoviesForeign, " | - Movies before 1990");
-            AddCategoryMapping(2221, TorznabCatType.MoviesForeign, " | - Movies 1991-2000");
-            AddCategoryMapping(2091, TorznabCatType.MoviesForeign, " | - Movies 2001-2005");
-            AddCategoryMapping(2092, TorznabCatType.MoviesForeign, " | - Movies 2006-2010");
-            AddCategoryMapping(2093, TorznabCatType.MoviesForeign, " | - Movies 2011-2015");
-            AddCategoryMapping(2200, TorznabCatType.MoviesForeign, " | - Movies 2016");
-            AddCategoryMapping(934, TorznabCatType.MoviesForeign, " | - Asian movies");
-            AddCategoryMapping(505, TorznabCatType.MoviesForeign, " | - Indian Cinema");
-            AddCategoryMapping(212, TorznabCatType.MoviesForeign, " | - Movie Collections");
-            AddCategoryMapping(2459, TorznabCatType.MoviesForeign, " | - Shorts");
-            AddCategoryMapping(1235, TorznabCatType.MoviesForeign, " | - Grindhouse");
-            AddCategoryMapping(185, TorznabCatType.MoviesForeign, " | - Soundtracks and Translations");
-            AddCategoryMapping(22, TorznabCatType.Movies, "our film");
-            AddCategoryMapping(941, TorznabCatType.Movies, " | - Cinema of the USSR");
-            AddCategoryMapping(1666, TorznabCatType.Movies, " | - Children's domestic films");
-            AddCategoryMapping(376, TorznabCatType.Movies, " | - Author Debuts");
-            AddCategoryMapping(124, TorznabCatType.Movies, "Art-house cinema and author");
-            AddCategoryMapping(1543, TorznabCatType.Movies, " | - Shorts (Art-house cinema and author)");
-            AddCategoryMapping(709, TorznabCatType.Movies, " | - Documentaries (Art-house cinema and author)");
-            AddCategoryMapping(1577, TorznabCatType.Movies, " | - Animation (Art-house cinema and author)");
-            AddCategoryMapping(511, TorznabCatType.Movies, "Theater");
-            AddCategoryMapping(656, TorznabCatType.Movies, "| - Benefit. Master of Arts domestic theater and cinema");
-            AddCategoryMapping(93, TorznabCatType.Movies, "DVD Video");
-            AddCategoryMapping(905, TorznabCatType.Movies, " | - Classic of world cinema (DVD Video)");
-            AddCategoryMapping(1576, TorznabCatType.Movies, " | - Asian movies (DVD Video)");
-            AddCategoryMapping(101, TorznabCatType.Movies, " | - Foreign movies (DVD)");
-            AddCategoryMapping(100, TorznabCatType.Movies, " | - Our cinema (DVD)");
-            AddCategoryMapping(572, TorznabCatType.Movies, " | - Art-house and auteur cinema (DVD)");
-            AddCategoryMapping(2220, TorznabCatType.Movies, " | - Indian Cinema DVD and HD Video");
-            AddCategoryMapping(1670, TorznabCatType.Movies, " |- Грайндхаус DVD и HD Video");
-            AddCategoryMapping(2198, TorznabCatType.MoviesHD, "HD Video");
-            AddCategoryMapping(2199, TorznabCatType.MoviesHD, " | - Classic of world cinema (HD Video)");
-            AddCategoryMapping(313, TorznabCatType.MoviesHD, " | - Foreign movies (HD Video)");
-            AddCategoryMapping(2201, TorznabCatType.MoviesHD, " | - Asian movies (HD Video)");
-            AddCategoryMapping(312, TorznabCatType.MoviesHD, " | - Our cinema (HD Video)");
-            AddCategoryMapping(2339, TorznabCatType.MoviesHD, " | - Art-house and auteur cinema (HD Video)");
-            AddCategoryMapping(352, TorznabCatType.Movies3D, "3D / Stereo Film, Video, TV & Sports");
-            AddCategoryMapping(549, TorznabCatType.Movies3D, " | - 3D Movies");
-            AddCategoryMapping(1213, TorznabCatType.Movies3D, " | - 3D Animation");
-            AddCategoryMapping(2109, TorznabCatType.Movies3D, " | - 3D Documentary");
-            AddCategoryMapping(514, TorznabCatType.Movies3D, " | - 3D Спорт");
-            AddCategoryMapping(2097, TorznabCatType.Movies3D, " | - 3D Clips, Music Videos, Movie Trailers");
-            AddCategoryMapping(4, TorznabCatType.Movies, "Cartoons");
-            AddCategoryMapping(2343, TorznabCatType.Movies, " | - Animation (Announcements HD Video)");
-            AddCategoryMapping(930, TorznabCatType.Movies, " | - Animation (HD Video)");
-            AddCategoryMapping(2365, TorznabCatType.Movies, " | - Short Film (HD Video)");
-            AddCategoryMapping(1900, TorznabCatType.Movies, " | - Domestic cartoons (DVD)");
-            AddCategoryMapping(521, TorznabCatType.Movies, " | - Foreign cartoons (DVD)");
-            AddCategoryMapping(2258, TorznabCatType.Movies, " | - Foreign Short Film (DVD)");
-            AddCategoryMapping(208, TorznabCatType.Movies, " | - Domestic cartoons");
-            AddCategoryMapping(539, TorznabCatType.Movies, " | - Domestic full-length cartoons");
-            AddCategoryMapping(209, TorznabCatType.Movies, " | - Foreign cartoons");
-            AddCategoryMapping(484, TorznabCatType.Movies, " | - Foreign short cartoons");
-            AddCategoryMapping(822, TorznabCatType.Movies, " | - Cartoon Collection");
-            AddCategoryMapping(921, TorznabCatType.TV, "Serial cartoons");
-            AddCategoryMapping(922, TorznabCatType.TV, " | - Avatar");
-            AddCategoryMapping(1247, TorznabCatType.TV, " | - Griffiny / Family guy");
-            AddCategoryMapping(923, TorznabCatType.TV, " | - SpongeBob SquarePants");
-            AddCategoryMapping(924, TorznabCatType.TV, " | - The Simpsons");
-            AddCategoryMapping(1991, TorznabCatType.TV, " | - Skubi-du / Scooby-Doo");
-            AddCategoryMapping(925, TorznabCatType.TV, " | - Tom and Jerry");
-            AddCategoryMapping(1165, TorznabCatType.TV, " | - Transformers");
-            AddCategoryMapping(1245, TorznabCatType.TV, " | - DuckTales / DuckTales");
-            AddCategoryMapping(928, TorznabCatType.TV, " | - Futurama / Futurama");
-            AddCategoryMapping(926, TorznabCatType.TV, " | - Spider-Man / The Spectacular Spider-Man");
-            AddCategoryMapping(1246, TorznabCatType.TV, " | - Turtles Mutant Ninja / Teenage Mutant Ninja Turtles");
-            AddCategoryMapping(1250, TorznabCatType.TV, " |- Чип и Дейл / Chip And Dale");
-            AddCategoryMapping(927, TorznabCatType.TV, " | - South Park / South Park");
-            AddCategoryMapping(1248, TorznabCatType.TV, " | - For sub-standard hands");
-            AddCategoryMapping(33, TorznabCatType.TVAnime, "Anime");
-            AddCategoryMapping(281, TorznabCatType.TVAnime, " | - Manga");
-            AddCategoryMapping(1386, TorznabCatType.TVAnime, " | - Wallpapers, artbook, and others.");
-            AddCategoryMapping(1387, TorznabCatType.TVAnime, " | -. AMV and other rollers");
-            AddCategoryMapping(1388, TorznabCatType.TVAnime, " |- OST (lossless)");
-            AddCategoryMapping(282, TorznabCatType.TVAnime, " | - OST (mp3 and others lossy-format)");
-            AddCategoryMapping(599, TorznabCatType.TVAnime, " | - Anime (DVD)");
-            AddCategoryMapping(1105, TorznabCatType.TVAnime, " |- Аниме (HD Video)");
-            AddCategoryMapping(1389, TorznabCatType.TVAnime, " | - Anime (main subsection)");
-            AddCategoryMapping(1391, TorznabCatType.TVAnime, " | - Anime (pleerny subsection)");
-            AddCategoryMapping(2491, TorznabCatType.TVAnime, " | - Anime (QC subsection)");
-            AddCategoryMapping(404, TorznabCatType.TVAnime, " | - Pokemony");
-            AddCategoryMapping(1390, TorznabCatType.TVAnime, " | - Naruto");
-            AddCategoryMapping(1642, TorznabCatType.TVAnime, " | - Trade");
-            AddCategoryMapping(893, TorznabCatType.TVAnime, " | - Japanese cartoons");
-            AddCategoryMapping(1478, TorznabCatType.TVAnime, " | - For sub-standard hands");
-
-            // Документалистика и юмор
-            AddCategoryMapping(670, TorznabCatType.TVDocumentary, "Faith and Religion");
-            AddCategoryMapping(1475, TorznabCatType.TVDocumentary, " | - Christianity");
-            AddCategoryMapping(2107, TorznabCatType.TVDocumentary, " | - Islam");
-            AddCategoryMapping(294, TorznabCatType.TVDocumentary, " | - Religions of India, Tibet and East Asia");
-            AddCategoryMapping(1453, TorznabCatType.TVDocumentary, " | - Cults and new religious movements");
-            AddCategoryMapping(46, TorznabCatType.TVDocumentary, "Documentary movies and TV shows");
-            AddCategoryMapping(103, TorznabCatType.TVDocumentary, " | - Documentary (DVD)");
-            AddCategoryMapping(671, TorznabCatType.TVDocumentary, "| - Biographies. Personality and idols");
-            AddCategoryMapping(2177, TorznabCatType.TVDocumentary, " | - Cinema and animation");
-            AddCategoryMapping(2538, TorznabCatType.TVDocumentary, " | - Art, Art History");
-            AddCategoryMapping(2159, TorznabCatType.TVDocumentary, " | - Music");
-            AddCategoryMapping(251, TorznabCatType.TVDocumentary, " | - Kriminalynaya documentary");
-            AddCategoryMapping(98, TorznabCatType.TVDocumentary, " | - Secrets of the Ages / Special Services / Conspiracy Theory");
-            AddCategoryMapping(97, TorznabCatType.TVDocumentary, " | - Military");
-            AddCategoryMapping(851, TorznabCatType.TVDocumentary, " | - World War II");
-            AddCategoryMapping(2178, TorznabCatType.TVDocumentary, " | - Accidents / Accidents / Disasters");
-            AddCategoryMapping(821, TorznabCatType.TVDocumentary, " | - Aviation");
-            AddCategoryMapping(2076, TorznabCatType.TVDocumentary, " | - Space");
-            AddCategoryMapping(56, TorznabCatType.TVDocumentary, " | - Scientific-popular movies");
-            AddCategoryMapping(2123, TorznabCatType.TVDocumentary, " | - Flora and fauna");
-            AddCategoryMapping(876, TorznabCatType.TVDocumentary, " | - Travel and Tourism");
-            AddCategoryMapping(2380, TorznabCatType.TVDocumentary, " | - Social talk show");
-            AddCategoryMapping(1467, TorznabCatType.TVDocumentary, " | - Information-analytical and socio-political etc. ..");
-            AddCategoryMapping(1469, TorznabCatType.TVDocumentary, " | - Architecture and Construction");
-            AddCategoryMapping(672, TorznabCatType.TVDocumentary, " | - All about home, life and design");
-            AddCategoryMapping(249, TorznabCatType.TVDocumentary, " |- BBC");
-            AddCategoryMapping(552, TorznabCatType.TVDocumentary, " |- Discovery");
-            AddCategoryMapping(500, TorznabCatType.TVDocumentary, " |- National Geographic");
-            AddCategoryMapping(2112, TorznabCatType.TVDocumentary, " | - History: Ancient World / Antiquity / Middle Ages");
-            AddCategoryMapping(1327, TorznabCatType.TVDocumentary, " | - History: modern and contemporary times");
-            AddCategoryMapping(1468, TorznabCatType.TVDocumentary, " | - The Age of the USSR");
-            AddCategoryMapping(1280, TorznabCatType.TVDocumentary, " | - The Battle of psychics / Theory improbability / Seekers / G ..");
-            AddCategoryMapping(752, TorznabCatType.TVDocumentary, " | - Russian sensation / Program Maximum / Profession report ..");
-            AddCategoryMapping(1114, TorznabCatType.TVDocumentary, " | - Paranormal");
-            AddCategoryMapping(2168, TorznabCatType.TVDocumentary, " | - Alternative history and science");
-            AddCategoryMapping(2160, TorznabCatType.TVDocumentary, " | - Vnezhanrovaya documentary");
-            AddCategoryMapping(2176, TorznabCatType.TVDocumentary, " | - Other / nekonditsiya");
-            AddCategoryMapping(314, TorznabCatType.TVDocumentary, "Documentary (HD Video)");
-            AddCategoryMapping(2323, TorznabCatType.TVDocumentary, " | - Information-analytical and socio-political etc. ..");
-            AddCategoryMapping(1278, TorznabCatType.TVDocumentary, "| - Biographies. Personality and idols (HD Video)");
-            AddCategoryMapping(1281, TorznabCatType.TVDocumentary, " | - Military Science (HD Video)");
-            AddCategoryMapping(2110, TorznabCatType.TVDocumentary, " | - Natural History, Science and Technology (HD Video)");
-            AddCategoryMapping(979, TorznabCatType.TVDocumentary, " | - Travel and Tourism (HD Video)");
-            AddCategoryMapping(2169, TorznabCatType.TVDocumentary, " |- Флора и фауна (HD Video)");
-            AddCategoryMapping(2166, TorznabCatType.TVDocumentary, " | - History (HD Video)");
-            AddCategoryMapping(2164, TorznabCatType.TVDocumentary, " |- BBC, Discovery, National Geographic (HD Video)");
-            AddCategoryMapping(2163, TorznabCatType.TVDocumentary, " | - Kriminalynaya documentary (HD Video)");
-            AddCategoryMapping(24, TorznabCatType.TV, "Entertaining TV programs and shows, fun and humor");
-            AddCategoryMapping(1959, TorznabCatType.TV, " | - Mind games and quizzes");
-            AddCategoryMapping(939, TorznabCatType.TV, " | - Reality and talk show host / category / impressions");
-            AddCategoryMapping(1481, TorznabCatType.TV, " | - Children's TV Show");
-            AddCategoryMapping(113, TorznabCatType.TV, " | - KVN");
-            AddCategoryMapping(115, TorznabCatType.TV, " | - Post KVN");
-            AddCategoryMapping(882, TorznabCatType.TV, " | - Distorting Mirror / town / in the town");
-            AddCategoryMapping(1482, TorznabCatType.TV, " | - Ice show");
-            AddCategoryMapping(393, TorznabCatType.TV, " | - Musical Show");
-            AddCategoryMapping(1569, TorznabCatType.TV, " | - Dinner Party");
-            AddCategoryMapping(373, TorznabCatType.TV, " | - Good Jokes");
-            AddCategoryMapping(1186, TorznabCatType.TV, " | - Evening Quarter");
-            AddCategoryMapping(137, TorznabCatType.TV, " | - Movies with a funny transfer (parody)");
-            AddCategoryMapping(2537, TorznabCatType.TV, " |- Stand-up comedy");
-            AddCategoryMapping(532, TorznabCatType.TV, " | - Ukrainian Shows");
-            AddCategoryMapping(827, TorznabCatType.TV, " | - Dance shows, concerts, performances");
-            AddCategoryMapping(1484, TorznabCatType.TV, " | - The Circus");
-            AddCategoryMapping(1485, TorznabCatType.TV, " | - The School for Scandal");
-            AddCategoryMapping(114, TorznabCatType.TV, " | - Satirist, and humorists");
-            AddCategoryMapping(1332, TorznabCatType.TV, " | - Humorous Audio Transmissions");
-            AddCategoryMapping(1495, TorznabCatType.TV, " | - Audio and video clips (Jokes and humor)");
-
-            // Спорт
-            AddCategoryMapping(255, TorznabCatType.TVSport, "Sports tournaments, films and programs");
-            AddCategoryMapping(256, TorznabCatType.TVSport, " | - Motorsports");
-            AddCategoryMapping(1986, TorznabCatType.TVSport, " | - Motorsports");
-            AddCategoryMapping(660, TorznabCatType.TVSport, " | - Formula-1 2016");
-            AddCategoryMapping(1551, TorznabCatType.TVSport, " | - Formula-1 2012-2015");
-            AddCategoryMapping(626, TorznabCatType.TVSport, " | - Formula 1");
-            AddCategoryMapping(262, TorznabCatType.TVSport, " | - Cycling");
-            AddCategoryMapping(1326, TorznabCatType.TVSport, " | - Volleyball / Handball");
-            AddCategoryMapping(978, TorznabCatType.TVSport, " | - Billiards");
-            AddCategoryMapping(1287, TorznabCatType.TVSport, " | - Poker");
-            AddCategoryMapping(1188, TorznabCatType.TVSport, " | - Bodybuilding / Power Sports");
-            AddCategoryMapping(1667, TorznabCatType.TVSport, " | - Boxing");
-            AddCategoryMapping(1675, TorznabCatType.TVSport, " | - Classical arts");
-            AddCategoryMapping(257, TorznabCatType.TVSport, " | - MMA and K-1");
-            AddCategoryMapping(875, TorznabCatType.TVSport, " | - College Football");
-            AddCategoryMapping(263, TorznabCatType.TVSport, " | - Rugby");
-            AddCategoryMapping(2073, TorznabCatType.TVSport, " | - Baseball");
-            AddCategoryMapping(550, TorznabCatType.TVSport, " | - Tennis");
-            AddCategoryMapping(2124, TorznabCatType.TVSport, " | - Badminton / Table Tennis");
-            AddCategoryMapping(1470, TorznabCatType.TVSport, " | - Gymnastics / Dance Competitions");
-            AddCategoryMapping(528, TorznabCatType.TVSport, " | - Athletics / Water Sports");
-            AddCategoryMapping(486, TorznabCatType.TVSport, " | - Winter Sports");
-            AddCategoryMapping(854, TorznabCatType.TVSport, " | - Figure skating");
-            AddCategoryMapping(2079, TorznabCatType.TVSport, " | - Biathlon");
-            AddCategoryMapping(260, TorznabCatType.TVSport, " | - Extreme");
-            AddCategoryMapping(1319, TorznabCatType.TVSport, " | - Sports (video)");
-            AddCategoryMapping(1608, TorznabCatType.TVSport, "football");
-            AddCategoryMapping(1952, TorznabCatType.TVSport, " | - Russia 2016-2017");
-            AddCategoryMapping(2075, TorznabCatType.TVSport, " | - Russia 2015-2016");
-            AddCategoryMapping(1613, TorznabCatType.TVSport, " | - Russia / USSR");
-            AddCategoryMapping(1614, TorznabCatType.TVSport, " | - England");
-            AddCategoryMapping(1623, TorznabCatType.TVSport, " | - Spain");
-            AddCategoryMapping(1615, TorznabCatType.TVSport, " | - Italy");
-            AddCategoryMapping(1630, TorznabCatType.TVSport, " | - Germany");
-            AddCategoryMapping(2425, TorznabCatType.TVSport, " | - France");
-            AddCategoryMapping(2514, TorznabCatType.TVSport, " | - Ukraine");
-            AddCategoryMapping(1616, TorznabCatType.TVSport, " | - Other national championships and cups");
-            AddCategoryMapping(2014, TorznabCatType.TVSport, " | - International Events");
-            AddCategoryMapping(2171, TorznabCatType.TVSport, " | - European Cups 2016-2017");
-            AddCategoryMapping(1491, TorznabCatType.TVSport, " | - European Cups 2015-2016");
-            AddCategoryMapping(1987, TorznabCatType.TVSport, " | - European Cups 2011-2015");
-            AddCategoryMapping(1617, TorznabCatType.TVSport, " | - European Cups");
-            AddCategoryMapping(1610, TorznabCatType.TVSport, " | - European Football Championship 2016");
-            AddCategoryMapping(1620, TorznabCatType.TVSport, " | - European Championships");
-            AddCategoryMapping(1668, TorznabCatType.TVSport, " | - World Cup 2018");
-            AddCategoryMapping(1621, TorznabCatType.TVSport, " | - World Championships");
-            AddCategoryMapping(1998, TorznabCatType.TVSport, " | - Friendly tournaments and matches");
-            AddCategoryMapping(1343, TorznabCatType.TVSport, " | - The survey and analytical programs 2014-2017");
-            AddCategoryMapping(751, TorznabCatType.TVSport, " | - The survey and analytical programs");
-            AddCategoryMapping(1697, TorznabCatType.TVSport, " | - Mini football / Football");
-            AddCategoryMapping(2004, TorznabCatType.TVSport, "basketball");
-            AddCategoryMapping(2001, TorznabCatType.TVSport, " | - International Competitions");
-            AddCategoryMapping(2002, TorznabCatType.TVSport, " |- NBA / NCAA (до 2000 г.)");
-            AddCategoryMapping(283, TorznabCatType.TVSport, " | - NBA / NCAA (2000-2010 biennium).");
-            AddCategoryMapping(1997, TorznabCatType.TVSport, " | - NBA / NCAA (2010-2017 biennium).");
-            AddCategoryMapping(2003, TorznabCatType.TVSport, " | - European club basketball");
-            AddCategoryMapping(2009, TorznabCatType.TVSport, "Hockey");
-            AddCategoryMapping(2010, TorznabCatType.TVSport, " | - Hockey / Bandy");
-            AddCategoryMapping(2006, TorznabCatType.TVSport, " | - International Events");
-            AddCategoryMapping(2007, TorznabCatType.TVSport, " | - KHL");
-            AddCategoryMapping(2005, TorznabCatType.TVSport, " | - NHL (until 2011/12)");
-            AddCategoryMapping(259, TorznabCatType.TVSport, " | - NHL (2013)");
-            AddCategoryMapping(2008, TorznabCatType.TVSport, " | - USSR - Canada");
-            AddCategoryMapping(126, TorznabCatType.TVSport, " | - Documentaries and Analysis");
-            AddCategoryMapping(845, TorznabCatType.TVSport, "Wrestling");
-            AddCategoryMapping(343, TorznabCatType.TVSport, " |- Professional Wrestling");
-            AddCategoryMapping(2111, TorznabCatType.TVSport, " |- Independent Wrestling");
-            AddCategoryMapping(1527, TorznabCatType.TVSport, " |- International Wrestling");
-            AddCategoryMapping(2069, TorznabCatType.TVSport, " |- Oldschool Wrestling");
-            AddCategoryMapping(1323, TorznabCatType.TVSport, " |- Documentary Wrestling");
-
-            // Сериалы
-            AddCategoryMapping(9, TorznabCatType.TV, "Russion serials");
-            AddCategoryMapping(104, TorznabCatType.TV, " | - Secrets of the investigation");
-            AddCategoryMapping(1408, TorznabCatType.TV, " | - National Security Agent");
-            AddCategoryMapping(1535, TorznabCatType.TV, " | - Lawyer");
-            AddCategoryMapping(91, TorznabCatType.TV, " | - Gangster Petersburg");
-            AddCategoryMapping(1356, TorznabCatType.TV, " | - Return of Mukhtar");
-            AddCategoryMapping(990, TorznabCatType.TV, " | - Hounds");
-            AddCategoryMapping(856, TorznabCatType.TV, " | - Capercaillie / Pyatnitskii / Karpov");
-            AddCategoryMapping(188, TorznabCatType.TV, " | - Darya Dontsova");
-            AddCategoryMapping(310, TorznabCatType.TV, " | - Kadetstvo / Kremlëvskie kursanty");
-            AddCategoryMapping(202, TorznabCatType.TV, " | - Kamenskaya");
-            AddCategoryMapping(935, TorznabCatType.TV, " | - Code of Honor");
-            AddCategoryMapping(172, TorznabCatType.TV, " | - A cop-in-law");
-            AddCategoryMapping(805, TorznabCatType.TV, " | - Cop War");
-            AddCategoryMapping(80, TorznabCatType.TV, " | - My Fair Nanny");
-            AddCategoryMapping(119, TorznabCatType.TV, " | - Careful, Modern!");
-            AddCategoryMapping(812, TorznabCatType.TV, " | - Web");
-            AddCategoryMapping(175, TorznabCatType.TV, " | - After");
-            AddCategoryMapping(79, TorznabCatType.TV, " | - Soldiers and others.");
-            AddCategoryMapping(123, TorznabCatType.TV, " | - Stopping Power / Cops / Opera");
-            AddCategoryMapping(189, TorznabCatType.TV, "Foreign TV series");
-            AddCategoryMapping(842, TorznabCatType.TV, " | - News and TV shows in the display stage");
-            AddCategoryMapping(235, TorznabCatType.TV, " | - TV Shows US and Canada");
-            AddCategoryMapping(242, TorznabCatType.TV, " | - TV Shows UK and Ireland");
-            AddCategoryMapping(819, TorznabCatType.TV, " | - Scandinavian series");
-            AddCategoryMapping(1531, TorznabCatType.TV, " | - Spanish series");
-            AddCategoryMapping(721, TorznabCatType.TV, " | - Italian series");
-            AddCategoryMapping(1102, TorznabCatType.TV, " | - European series");
-            AddCategoryMapping(1120, TorznabCatType.TV, " | - TV Shows in Africa, Middle East");
-            AddCategoryMapping(1214, TorznabCatType.TV, " | - TV Shows Australia and New Zealand");
-            AddCategoryMapping(387, TorznabCatType.TV, " | - Serials joint production of several countries");
-            AddCategoryMapping(1359, TorznabCatType.TV, " | - Web series, webisodes and TV series for the pilot episode ..");
-            AddCategoryMapping(271, TorznabCatType.TV, " | - 24 hours / 24");
-            AddCategoryMapping(273, TorznabCatType.TV, " |- Альф / ALF");
-            AddCategoryMapping(743, TorznabCatType.TV, " | - Grey's Anatomy / Grey's Anatomy + Private Practice / Priv ..");
-            AddCategoryMapping(184, TorznabCatType.TV, " | - Buffy - the Vampire Slayer / Buffy + Angel / Angel");
-            AddCategoryMapping(194, TorznabCatType.TV, " | - Bludlivaya California / Californication");
-            AddCategoryMapping(85, TorznabCatType.TV, " |- Вавилон 5 / Babylon 5");
-            AddCategoryMapping(1171, TorznabCatType.TV, " |- Викинги / Vikings");
-            AddCategoryMapping(1417, TorznabCatType.TV, " | - Breaking Bad / Breaking Bad");
-            AddCategoryMapping(1144, TorznabCatType.TV, " | - The Return of Sherlock Holmes / Return of Sherlock Holmes");
-            AddCategoryMapping(595, TorznabCatType.TV, " |- Герои / Heroes");
-            AddCategoryMapping(1288, TorznabCatType.TV, " | - Dexter / Dexter");
-            AddCategoryMapping(1605, TorznabCatType.TV, " | - Two and a Half Men / Two and a Half Men");
-            AddCategoryMapping(1694, TorznabCatType.TV, " |- Династия / Dynasty");
-            AddCategoryMapping(1690, TorznabCatType.TV, " | - The Vampire Diaries / The Vampire Diaries + True Blood ..");
-            AddCategoryMapping(820, TorznabCatType.TV, " |- Доктор Кто / Doctor Who + Торчвуд / Torchwood");
-            AddCategoryMapping(625, TorznabCatType.TV, " |- Доктор Хаус / House M.D.");
-            AddCategoryMapping(84, TorznabCatType.TV, " | - Druzyya / Friends + Joey / Joey");
-            AddCategoryMapping(623, TorznabCatType.TV, " | - Fringe / Fringe");
-            AddCategoryMapping(1798, TorznabCatType.TV, "| - Stargate: Atlantis; Universe / Stargate: Atlanti ..");
-            AddCategoryMapping(106, TorznabCatType.TV, " | - Stargate: SG-1 / Stargate: SG1");
-            AddCategoryMapping(166, TorznabCatType.TV, " | - Battlestar Galactica / Battlestar Galactica + Copper ..");
-            AddCategoryMapping(236, TorznabCatType.TV, " | - Star Trek / Star Trek");
-            AddCategoryMapping(1449, TorznabCatType.TV, " |- Игра престолов / Game of Thrones");
-            AddCategoryMapping(507, TorznabCatType.TV, " | - How I Met Your Mother The Big Bang Theory +");
-            AddCategoryMapping(504, TorznabCatType.TV, " |- Клан Сопрано / The Sopranos");
-            AddCategoryMapping(536, TorznabCatType.TV, " |- Клиника / Scrubs");
-            AddCategoryMapping(173, TorznabCatType.TV, " | - Коломбо / Columbo");
-            AddCategoryMapping(918, TorznabCatType.TV, " | - Inspector Rex / Komissar Rex");
-            AddCategoryMapping(920, TorznabCatType.TV, " | - Bones / Bones");
-            AddCategoryMapping(203, TorznabCatType.TV, " | - Weeds / Weeds");
-            AddCategoryMapping(1243, TorznabCatType.TV, "| - Cool Walker. Justice in Texas / Walker, Texas Ran ..");
-            AddCategoryMapping(140, TorznabCatType.TV, " | - Masters of Horror / Masters of Horror");
-            AddCategoryMapping(636, TorznabCatType.TV, " | - Mentalist / The Mentalist + Castle / Castle");
-            AddCategoryMapping(606, TorznabCatType.TV, " | - Crime / CSI Location: Crime Scene Investigation");
-            AddCategoryMapping(776, TorznabCatType.TV, " |- Мисс Марпл / Miss Marple");
-            AddCategoryMapping(181, TorznabCatType.TV, "| - NCIS; Los Angeles; New Orleans");
-            AddCategoryMapping(1499, TorznabCatType.TV, " | - Murder, She Wrote / Murder, She Wrote + Perry Mason ..");
-            AddCategoryMapping(81, TorznabCatType.TV, " | - Survivors / LOST");
-            AddCategoryMapping(266, TorznabCatType.TV, " | - Desperate Housewives / Desperate Housewives");
-            AddCategoryMapping(252, TorznabCatType.TV, " | - Jailbreak / Prison Break");
-            AddCategoryMapping(196, TorznabCatType.TV, " |- Санта Барбара / Santa Barbara");
-            AddCategoryMapping(372, TorznabCatType.TV, " | - Supernatural / Supernatural");
-            AddCategoryMapping(110, TorznabCatType.TV, " | - The X-Files / The X-Files");
-            AddCategoryMapping(193, TorznabCatType.TV, " | - Sex and the City / Sex And The City");
-            AddCategoryMapping(237, TorznabCatType.TV, " | - Sliding / Sliders");
-            AddCategoryMapping(265, TorznabCatType.TV, " | - Ambulance / ER");
-            AddCategoryMapping(1117, TorznabCatType.TV, " | - Octopus / La Piovra");
-            AddCategoryMapping(497, TorznabCatType.TV, " | - Smallville / Smallville");
-            AddCategoryMapping(121, TorznabCatType.TV, " | - Twin Peaks / Twin Peaks");
-            AddCategoryMapping(134, TorznabCatType.TV, " | - Hercule Poirot / Hercule Poirot");
-            AddCategoryMapping(195, TorznabCatType.TV, " | - For sub-standard hands");
-            AddCategoryMapping(2366, TorznabCatType.TV, "Foreign TV shows (HD Video)");
-            AddCategoryMapping(2401, TorznabCatType.TV, " |- Блудливая Калифорния / Californication (HD Video)");
-            AddCategoryMapping(2390, TorznabCatType.TV, " | - Two and a Half Men / Two and a Half Men (HD Video)");
-            AddCategoryMapping(1669, TorznabCatType.TV, " |- Викинги / Vikings (HD Video)");
-            AddCategoryMapping(2391, TorznabCatType.TV, " |- Декстер / Dexter (HD Video)");
-            AddCategoryMapping(2392, TorznabCatType.TV, " | - Friends / Friends (HD Video)");
-            AddCategoryMapping(2407, TorznabCatType.TV, " |- Доктор Кто / Doctor Who; Торчвуд / Torchwood (HD Video)");
-            AddCategoryMapping(2393, TorznabCatType.TV, " |- Доктор Хаус / House M.D. (HD Video)");
-            AddCategoryMapping(2370, TorznabCatType.TV, " | - Fringe / Fringe (HD Video)");
-            AddCategoryMapping(2394, TorznabCatType.TV, "| - Stargate: a C1; Atlantis; The Universe (HD Video)");
-            AddCategoryMapping(2408, TorznabCatType.TV, "| - Battlestar Galactica / Battlestar Galactica; Capri ..");
-            AddCategoryMapping(2395, TorznabCatType.TV, " | - Star Trek / Star Trek (HD Video)");
-            AddCategoryMapping(2396, TorznabCatType.TV, "| - How I Met Your Mother; The Big Bang Theory (HD Vi ..");
-            AddCategoryMapping(2397, TorznabCatType.TV, " |- Кости / Bones (HD Video)");
-            AddCategoryMapping(2398, TorznabCatType.TV, " | - Weeds / Weeds (HD Video)");
-            AddCategoryMapping(2399, TorznabCatType.TV, "| - Mentalist / The Mentalist; Castle / Castle (HD Video)");
-            AddCategoryMapping(2400, TorznabCatType.TV, " | - Crime / CSI Location: Crime Scene Investigation (HD ..");
-            AddCategoryMapping(2402, TorznabCatType.TV, " | - Survivors / LOST (HD Video)");
-            AddCategoryMapping(2403, TorznabCatType.TV, " | - Jailbreak / Prison Break (HD Video)");
-            AddCategoryMapping(2404, TorznabCatType.TV, " |- Сверхъестественное / Supernatural (HD Video)");
-            AddCategoryMapping(2405, TorznabCatType.TV, " | - The X-Files / The X-Files (HD Video)");
-            AddCategoryMapping(2406, TorznabCatType.TV, " |- Тайны Смолвиля / Smallville (HD Video)");
-            AddCategoryMapping(911, TorznabCatType.TV, "Soaps Latin America, Turkey and India");
-            AddCategoryMapping(1493, TorznabCatType.TV, " | - Actors and actresses of Latin American soap operas");
-            AddCategoryMapping(1301, TorznabCatType.TV, " | - Indian series");
-            AddCategoryMapping(704, TorznabCatType.TV, " | - Turkish serials");
-            AddCategoryMapping(1940, TorznabCatType.TV, " | - Official brief version of Latin American soap operas");
-            AddCategoryMapping(1574, TorznabCatType.TV, " | - Latin American soap operas with the voice acting (folders distribution)");
-            AddCategoryMapping(1539, TorznabCatType.TV, " | - Latin American serials with subtitles");
-            AddCategoryMapping(1500, TorznabCatType.TV, " |- OST");
-            AddCategoryMapping(823, TorznabCatType.TV, " | - Богатые тоже плачут / The Rich Also Cry");
-            AddCategoryMapping(1006, TorznabCatType.TV, " | - Вдова бланко / La Viuda de Blanco");
-            AddCategoryMapping(877, TorznabCatType.TV, " | - Великолепный век / Magnificent Century");
-            AddCategoryMapping(972, TorznabCatType.TV, " | - In the name of love / Por Amor");
-            AddCategoryMapping(781, TorznabCatType.TV, " | - A girl named Fate / Milagros");
-            AddCategoryMapping(1300, TorznabCatType.TV, " |- Дикий ангел / Muneca Brava");
-            AddCategoryMapping(1803, TorznabCatType.TV, " | - Донья Барбара / Female Barbara");
-            AddCategoryMapping(1298, TorznabCatType.TV, " | - Дороги Индии / Passage to India");
-            AddCategoryMapping(825, TorznabCatType.TV, " | - Durnuška Betti / Yo Soy Betty la Fea");
-            AddCategoryMapping(1606, TorznabCatType.TV, " | - The wife of Judas (wine of love) / La Mujer de Judas");
-            AddCategoryMapping(1458, TorznabCatType.TV, " | - Cruel Angel / Anjo Mau");
-            AddCategoryMapping(1463, TorznabCatType.TV, " | - Замарашка / Cara Sucia");
-            AddCategoryMapping(1459, TorznabCatType.TV, " | - A Cinderella Story (Beautiful Loser) / Bella Calamidade ..");
-            AddCategoryMapping(1461, TorznabCatType.TV, " | - Kacorri / Kachorra");
-            AddCategoryMapping(718, TorznabCatType.TV, " |- Клон / O Clone");
-            AddCategoryMapping(1498, TorznabCatType.TV, " | - Клятва / The Oath");
-            AddCategoryMapping(907, TorznabCatType.TV, " | - Lalo / Lalola");
-            AddCategoryMapping(992, TorznabCatType.TV, " | - Morena Clara / Clara Morena");
-            AddCategoryMapping(607, TorznabCatType.TV, " | - Mi Segunda Madre / Mi segunda Madre");
-            AddCategoryMapping(594, TorznabCatType.TV, " | - The rebellious spirit / Rebelde Way");
-            AddCategoryMapping(775, TorznabCatType.TV, " | - Наследница / The Heiress");
-            AddCategoryMapping(534, TorznabCatType.TV, " | - Nobody but you / Tu o Nadie");
-            AddCategoryMapping(1462, TorznabCatType.TV, " | - Падре Корахе / Father Courage");
-            AddCategoryMapping(1678, TorznabCatType.TV, " | - Падший ангел / Mas Sabe el Diablo");
-            AddCategoryMapping(904, TorznabCatType.TV, " | - Предательство / The Betrayal");
-            AddCategoryMapping(1460, TorznabCatType.TV, " | - Призрак Элены / The Phantom of Elena");
-            AddCategoryMapping(816, TorznabCatType.TV, " | - Live your life / Viver a vida");
-            AddCategoryMapping(815, TorznabCatType.TV, " | - Just Maria / Simplemente Maria");
-            AddCategoryMapping(325, TorznabCatType.TV, " | - Rabыnya Isaura / Escrava Isaura");
-            AddCategoryMapping(1457, TorznabCatType.TV, " | - Реванш 2000 / Retaliation 2000");
-            AddCategoryMapping(1692, TorznabCatType.TV, " | - Family Ties / Lacos de Familia");
-            AddCategoryMapping(1540, TorznabCatType.TV, " | - Perfect Beauty / Beleza pura");
-            AddCategoryMapping(694, TorznabCatType.TV, " | - Secrets of Love / Los Misterios del Amor");
-            AddCategoryMapping(1949, TorznabCatType.TV, " | - Фаворитка / A Favorita");
-            AddCategoryMapping(1541, TorznabCatType.TV, " | - Цыганская кровь / Soy gitano");
-            AddCategoryMapping(1941, TorznabCatType.TV, " | - Шторм / Storm");
-            AddCategoryMapping(1537, TorznabCatType.TV, " | - For sub-standard hands");
-            AddCategoryMapping(2100, TorznabCatType.TV, "Asian series");
-            AddCategoryMapping(717, TorznabCatType.TV, " | - Chinese serials with subtitles");
-            AddCategoryMapping(915, TorznabCatType.TV, " | - Korean TV shows with voice acting");
-            AddCategoryMapping(1242, TorznabCatType.TV, " | - Korean serials with subtitles");
-            AddCategoryMapping(2412, TorznabCatType.TV, " | - Other Asian series with the voice acting");
-            AddCategoryMapping(1938, TorznabCatType.TV, " | - Taiwanese serials with subtitles");
-            AddCategoryMapping(2104, TorznabCatType.TV, " | - Japanese serials with subtitles");
-            AddCategoryMapping(1939, TorznabCatType.TV, " | - Japanese TV series with the voice acting");
-            AddCategoryMapping(2102, TorznabCatType.TV, " | -. VMV and other videos");
-            AddCategoryMapping(2103, TorznabCatType.TV, " |- OST");
-
-            // Книги и журналы
-            AddCategoryMapping(1411, TorznabCatType.Books, " | - Scanning, processing skanov");
-            AddCategoryMapping(21, TorznabCatType.Books, "books");
-            AddCategoryMapping(2157, TorznabCatType.Books, " | - Film, TV, animation");
-            AddCategoryMapping(765, TorznabCatType.Books, " | - Design, Graphic Design");
-            AddCategoryMapping(2019, TorznabCatType.Books, " | - Photography and video");
-            AddCategoryMapping(31, TorznabCatType.Books, " | - Magazines and newspapers (general section)");
-            AddCategoryMapping(1427, TorznabCatType.Books, " | - Esoteric Tarot, Feng Shui");
-            AddCategoryMapping(2422, TorznabCatType.Books, " | - Astrology");
-            AddCategoryMapping(2195, TorznabCatType.Books, "| - Beauty. Care. housekeeping");
-            AddCategoryMapping(2521, TorznabCatType.Books, "| - Fashion. Style. Etiquette");
-            AddCategoryMapping(2223, TorznabCatType.Books, " | - Travel and Tourism");
-            AddCategoryMapping(2447, TorznabCatType.Books, " | - Celebrity idols");
-            AddCategoryMapping(39, TorznabCatType.Books, " | - Miscellaneous");
-            AddCategoryMapping(1101, TorznabCatType.Books, "For children, parents and teachers");
-            AddCategoryMapping(745, TorznabCatType.Books, " | - Textbooks for kindergarten and primary school (..");
-            AddCategoryMapping(1689, TorznabCatType.Books, " | - Textbooks for high school (grades 5-11)");
-            AddCategoryMapping(2336, TorznabCatType.Books, " | - Teachers and educators");
-            AddCategoryMapping(2337, TorznabCatType.Books, " | - Scientific-popular and informative literature (for children ..");
-            AddCategoryMapping(1353, TorznabCatType.Books, " | - Leisure and creativity");
-            AddCategoryMapping(1400, TorznabCatType.Books, " | - Education and development");
-            AddCategoryMapping(1415, TorznabCatType.Books, "| - Hood. lit-ra for preschool and elementary grades");
-            AddCategoryMapping(2046, TorznabCatType.Books, "| - Hood. lit-ra for the middle and upper classes");
-            AddCategoryMapping(1802, TorznabCatType.Books, "Sports, physical training, martial arts");
-            AddCategoryMapping(2189, TorznabCatType.Books, " | - Football");
-            AddCategoryMapping(2190, TorznabCatType.Books, " | - Hockey");
-            AddCategoryMapping(2443, TorznabCatType.Books, " | - Team sports");
-            AddCategoryMapping(1477, TorznabCatType.Books, "| - Athletics. Swimming. Gymnastics. Weightlifting...");
-            AddCategoryMapping(669, TorznabCatType.Books, "| - Motorsport. Motorcycling. cycle racing");
-            AddCategoryMapping(2196, TorznabCatType.Books, "| - Chess. Checkers");
-            AddCategoryMapping(2056, TorznabCatType.Books, " | - Martial Arts, Martial Arts");
-            AddCategoryMapping(1436, TorznabCatType.Books, " | - Extreme");
-            AddCategoryMapping(2191, TorznabCatType.Books, " | - Fitness, fitness, bodybuilding");
-            AddCategoryMapping(2477, TorznabCatType.Books, " | - Sports press");
-            AddCategoryMapping(1680, TorznabCatType.Books, "Humanitarian sciences");
-            AddCategoryMapping(1684, TorznabCatType.Books, "| - Arts. Cultural");
-            AddCategoryMapping(2446, TorznabCatType.Books, "| - Folklore. Epic. Mythology");
-            AddCategoryMapping(2524, TorznabCatType.Books, " | - Literature");
-            AddCategoryMapping(2525, TorznabCatType.Books, " | - Linguistics");
-            AddCategoryMapping(995, TorznabCatType.Books, " | - Philosophy");
-            AddCategoryMapping(2022, TorznabCatType.Books, " | - Political Science");
-            AddCategoryMapping(2471, TorznabCatType.Books, " | - Sociology");
-            AddCategoryMapping(2375, TorznabCatType.Books, " | - Journalism, Journalism");
-            AddCategoryMapping(764, TorznabCatType.Books, " | - Business, Management");
-            AddCategoryMapping(1685, TorznabCatType.Books, " | - Marketing");
-            AddCategoryMapping(1688, TorznabCatType.Books, " | - Economy");
-            AddCategoryMapping(2472, TorznabCatType.Books, " | - Finance");
-            AddCategoryMapping(1687, TorznabCatType.Books, "| - Jurisprudence. Right. criminalistics");
-            AddCategoryMapping(2020, TorznabCatType.Books, "Historical sciences");
-            AddCategoryMapping(1349, TorznabCatType.Books, " | - Philosophy and Methodology of Historical Science");
-            AddCategoryMapping(1967, TorznabCatType.Books, " | - Historical sources");
-            AddCategoryMapping(2049, TorznabCatType.Books, " | - Historic Person");
-            AddCategoryMapping(1681, TorznabCatType.Books, " | - Alternative historical theories");
-            AddCategoryMapping(2319, TorznabCatType.Books, " | - Archaeology");
-            AddCategoryMapping(2434, TorznabCatType.Books, "| - Ancient World. Antiquity");
-            AddCategoryMapping(1683, TorznabCatType.Books, " | - The Middle Ages");
-            AddCategoryMapping(2444, TorznabCatType.Books, " | - History of modern and contemporary");
-            AddCategoryMapping(2427, TorznabCatType.Books, " | - European History");
-            AddCategoryMapping(2452, TorznabCatType.Books, " | - History of Asia and Africa");
-            AddCategoryMapping(2445, TorznabCatType.Books, " | - History of America, Australia, Oceania");
-            AddCategoryMapping(2435, TorznabCatType.Books, " | - History of Russia");
-            AddCategoryMapping(2436, TorznabCatType.Books, " | - The Age of the USSR");
-            AddCategoryMapping(2453, TorznabCatType.Books, " | - History of the countries of the former USSR");
-            AddCategoryMapping(2320, TorznabCatType.Books, " | - Ethnography, anthropology");
-            AddCategoryMapping(1801, TorznabCatType.Books, "| - International relations. Diplomacy");
-            AddCategoryMapping(2023, TorznabCatType.Books, "Accurate, natural and engineering sciences");
-            AddCategoryMapping(2024, TorznabCatType.Books, " | - Aviation / Cosmonautics");
-            AddCategoryMapping(2026, TorznabCatType.Books, " | - Physics");
-            AddCategoryMapping(2192, TorznabCatType.Books, " | - Astronomy");
-            AddCategoryMapping(2027, TorznabCatType.Books, " | - Biology / Ecology");
-            AddCategoryMapping(295, TorznabCatType.Books, " | - Chemistry / Biochemistry");
-            AddCategoryMapping(2028, TorznabCatType.Books, " | - Mathematics");
-            AddCategoryMapping(2029, TorznabCatType.Books, " | - Geography / Geology / Geodesy");
-            AddCategoryMapping(1325, TorznabCatType.Books, " | - Electronics / Radio");
-            AddCategoryMapping(2386, TorznabCatType.Books, " | - Diagrams and service manuals (original documents)");
-            AddCategoryMapping(2031, TorznabCatType.Books, " | - Architecture / Construction / Engineering networks");
-            AddCategoryMapping(2030, TorznabCatType.Books, " | - Engineering");
-            AddCategoryMapping(2526, TorznabCatType.Books, " | - Welding / Soldering / Non-Destructive Testing");
-            AddCategoryMapping(2527, TorznabCatType.Books, " | - Automation / Robotics");
-            AddCategoryMapping(2254, TorznabCatType.Books, " | - Metallurgy / Materials");
-            AddCategoryMapping(2376, TorznabCatType.Books, " | - Mechanics, strength of materials");
-            AddCategoryMapping(2054, TorznabCatType.Books, " | - Power engineering / electrical");
-            AddCategoryMapping(770, TorznabCatType.Books, " | - Oil, Gas and Chemicals");
-            AddCategoryMapping(2476, TorznabCatType.Books, " | - Agriculture and food industry");
-            AddCategoryMapping(2494, TorznabCatType.Books, " | - Railway case");
-            AddCategoryMapping(1528, TorznabCatType.Books, " | - Normative documentation");
-            AddCategoryMapping(2032, TorznabCatType.Books, " | - Journals: scientific, popular, radio and others.");
-            AddCategoryMapping(768, TorznabCatType.Books, "Warfare");
-            AddCategoryMapping(2099, TorznabCatType.Books, " | - Militaria");
-            AddCategoryMapping(2021, TorznabCatType.Books, " | - Military History");
-            AddCategoryMapping(2437, TorznabCatType.Books, " | - History of the Second World War");
-            AddCategoryMapping(1447, TorznabCatType.Books, " | - Military equipment");
-            AddCategoryMapping(2468, TorznabCatType.Books, " | - Small arms");
-            AddCategoryMapping(2469, TorznabCatType.Books, " | - Educational literature");
-            AddCategoryMapping(2470, TorznabCatType.Books, " | - Special forces of the world");
-            AddCategoryMapping(1686, TorznabCatType.Books, "Faith and Religion");
-            AddCategoryMapping(2215, TorznabCatType.Books, " | - Christianity");
-            AddCategoryMapping(2216, TorznabCatType.Books, " | - Islam");
-            AddCategoryMapping(2217, TorznabCatType.Books, " | - Religions of India, Tibet and East Asia / Judaism");
-            AddCategoryMapping(2218, TorznabCatType.Books, " | - Non-traditional religious, spiritual and mystical teachings ..");
-            AddCategoryMapping(2252, TorznabCatType.Books, "| - Religion. History of Religions. Atheism");
-            AddCategoryMapping(767, TorznabCatType.Books, "psychology");
-            AddCategoryMapping(2515, TorznabCatType.Books, " | - General and Applied Psychology");
-            AddCategoryMapping(2516, TorznabCatType.Books, " | - Psychotherapy and Counseling");
-            AddCategoryMapping(2517, TorznabCatType.Books, " | - Psychodiagnostics and psyhokorrektsyya");
-            AddCategoryMapping(2518, TorznabCatType.Books, " | - Social psychology and psychology of relationships");
-            AddCategoryMapping(2519, TorznabCatType.Books, " | - Training and Coaching");
-            AddCategoryMapping(2520, TorznabCatType.Books, " | - Personal development and self-improvement");
-            AddCategoryMapping(1696, TorznabCatType.Books, " | - Popular Psychology");
-            AddCategoryMapping(2253, TorznabCatType.Books, "| - Sexology. Relations between the sexes");
-            AddCategoryMapping(2033, TorznabCatType.Books, "Collecting, hobby and hobbies");
-            AddCategoryMapping(1412, TorznabCatType.Books, "| - Collecting and auxiliary ist. discipline");
-            AddCategoryMapping(1446, TorznabCatType.Books, " | - Embroidery");
-            AddCategoryMapping(753, TorznabCatType.Books, " | - Knitting");
-            AddCategoryMapping(2037, TorznabCatType.Books, " | - Sewing, Patchwork");
-            AddCategoryMapping(2224, TorznabCatType.Books, " | - Lace");
-            AddCategoryMapping(2194, TorznabCatType.Books, "| - Beading. Yuvelirika. Jewellery wire.");
-            AddCategoryMapping(2418, TorznabCatType.Books, " | - Paper Art");
-            AddCategoryMapping(1410, TorznabCatType.Books, " | - Other arts and crafts");
-            AddCategoryMapping(2034, TorznabCatType.Books, " | - Pets and aquariums");
-            AddCategoryMapping(2433, TorznabCatType.Books, " | - Hunting and fishing");
-            AddCategoryMapping(1961, TorznabCatType.Books, " | - Cooking (Book)");
-            AddCategoryMapping(2432, TorznabCatType.Books, " | - Cooking (newspapers and magazines)");
-            AddCategoryMapping(565, TorznabCatType.Books, " | - Modelling");
-            AddCategoryMapping(1523, TorznabCatType.Books, " | - Farmland / Floriculture");
-            AddCategoryMapping(1575, TorznabCatType.Books, " | - Repair, private construction, design of interiors");
-            AddCategoryMapping(1520, TorznabCatType.Books, " | - Woodworking");
-            AddCategoryMapping(2424, TorznabCatType.Books, " | - Board Games");
-            AddCategoryMapping(769, TorznabCatType.Books, " | - Other Hobbies");
-            AddCategoryMapping(2038, TorznabCatType.Books, "Fiction");
-            AddCategoryMapping(2043, TorznabCatType.Books, " | - Russian literature");
-            AddCategoryMapping(2042, TorznabCatType.Books, " | - Foreign literature (up to 1900)");
-            AddCategoryMapping(2041, TorznabCatType.Books, " | - Foreign literature (XX and XXI century)");
-            AddCategoryMapping(2044, TorznabCatType.Books, " | - Detective, Action");
-            AddCategoryMapping(2039, TorznabCatType.Books, " | - Female Novel");
-            AddCategoryMapping(2045, TorznabCatType.Books, " | - Domestic science fiction / fantasy / mystic");
-            AddCategoryMapping(2080, TorznabCatType.Books, " | - International science fiction / fantasy / mystic");
-            AddCategoryMapping(2047, TorznabCatType.Books, " | - Adventure");
-            AddCategoryMapping(2193, TorznabCatType.Books, " | - Literary Magazines");
-            AddCategoryMapping(1418, TorznabCatType.Books, "Computer books");
-            AddCategoryMapping(1422, TorznabCatType.Books, " | - Software from Microsoft");
-            AddCategoryMapping(1423, TorznabCatType.Books, " | - Other software");
-            AddCategoryMapping(1424, TorznabCatType.Books, " |- Mac OS; Linux, FreeBSD и прочие *NIX");
-            AddCategoryMapping(1445, TorznabCatType.Books, " | - RDBMS");
-            AddCategoryMapping(1425, TorznabCatType.Books, " | - Web Design and Programming");
-            AddCategoryMapping(1426, TorznabCatType.Books, " | - Programming");
-            AddCategoryMapping(1428, TorznabCatType.Books, " | - Graphics, Video Processing");
-            AddCategoryMapping(1429, TorznabCatType.Books, " | - Network / VoIP");
-            AddCategoryMapping(1430, TorznabCatType.Books, " | - Hacking and Security");
-            AddCategoryMapping(1431, TorznabCatType.Books, " | - Iron (book on a PC)");
-            AddCategoryMapping(1433, TorznabCatType.Books, " | - Engineering and scientific programs");
-            AddCategoryMapping(1432, TorznabCatType.Books, " | - Computer magazines and annexes");
-            AddCategoryMapping(2202, TorznabCatType.Books, " | - Disc applications to gaming magazines");
-            AddCategoryMapping(862, TorznabCatType.Books, "Comics");
-            AddCategoryMapping(2461, TorznabCatType.Books, " | - Comics in Russian");
-            AddCategoryMapping(2462, TorznabCatType.Books, " | - Marvel Comics publishing");
-            AddCategoryMapping(2463, TorznabCatType.Books, " | - DC Comics publishing");
-            AddCategoryMapping(2464, TorznabCatType.Books, " | - Comics from other publishers");
-            AddCategoryMapping(2473, TorznabCatType.Books, " | - Comics in other languages");
-            AddCategoryMapping(2465, TorznabCatType.Books, " | - Manga (in foreign languages)");
-            AddCategoryMapping(2048, TorznabCatType.Books, "Collections of books and libraries");
-            AddCategoryMapping(1238, TorznabCatType.Books, " | - Library (mirror network libraries / collections)");
-            AddCategoryMapping(2055, TorznabCatType.Books, " | - Thematic collections (collections)");
-            AddCategoryMapping(754, TorznabCatType.Books, " | - Multidisciplinary collections (collections)");
-            AddCategoryMapping(2114, TorznabCatType.Books, "Multimedia and online publications");
-            AddCategoryMapping(2438, TorznabCatType.Books, " | - Multimedia Encyclopedia");
-            AddCategoryMapping(2439, TorznabCatType.Books, " | - Interactive tutorials and educational materials");
-            AddCategoryMapping(2440, TorznabCatType.Books, " | - Educational publications for children");
-            AddCategoryMapping(2441, TorznabCatType.Books, "| - Cooking. Floriculture. housekeeping");
-            AddCategoryMapping(2442, TorznabCatType.Books, "| - Culture. Art. History");
-
-            // Обучение иностранным языкам
-            AddCategoryMapping(2362, TorznabCatType.Books, "Foreign Language for Adults");
-            AddCategoryMapping(1265, TorznabCatType.Books, " | - English (for adults)");
-            AddCategoryMapping(1266, TorznabCatType.Books, " | - German");
-            AddCategoryMapping(1267, TorznabCatType.Books, " | - French");
-            AddCategoryMapping(1358, TorznabCatType.Books, " | - Spanish");
-            AddCategoryMapping(2363, TorznabCatType.Books, " | - Italian");
-            AddCategoryMapping(1268, TorznabCatType.Books, " | - Other European languages");
-            AddCategoryMapping(1673, TorznabCatType.Books, " | - Arabic");
-            AddCategoryMapping(1269, TorznabCatType.Books, " | - Chinese");
-            AddCategoryMapping(1270, TorznabCatType.Books, " | - Japanese");
-            AddCategoryMapping(1275, TorznabCatType.Books, " | - Other Asian languages");
-            AddCategoryMapping(2364, TorznabCatType.Books, " | - Russian as a foreign language");
-            AddCategoryMapping(1276, TorznabCatType.Books, " | - Multilanguage collections");
-            AddCategoryMapping(1274, TorznabCatType.Books, " | - Other (foreign languages)");
-            AddCategoryMapping(2094, TorznabCatType.Books, " | - LIM-courses");
-            AddCategoryMapping(1264, TorznabCatType.Books, "Foreign languages &#8203;&#8203;for children");
-            AddCategoryMapping(2358, TorznabCatType.Books, " | - English (for children)");
-            AddCategoryMapping(2359, TorznabCatType.Books, " | - Other European languages &#8203;&#8203;(for children)");
-            AddCategoryMapping(2360, TorznabCatType.Books, " | - Eastern languages &#8203;&#8203;(for children)");
-            AddCategoryMapping(2361, TorznabCatType.Books, " | - School textbooks, exam (for children)");
-            AddCategoryMapping(2057, TorznabCatType.Books, "Fiction");
-            AddCategoryMapping(2355, TorznabCatType.Books, " | - Fiction in English");
-            AddCategoryMapping(2474, TorznabCatType.Books, " | - Fiction French");
-            AddCategoryMapping(2356, TorznabCatType.Books, " | - Fiction in other European languages");
-            AddCategoryMapping(2357, TorznabCatType.Books, " | - Fiction in oriental languages");
-            AddCategoryMapping(2413, TorznabCatType.Books, "Audio Books in foreign languages");
-            AddCategoryMapping(1501, TorznabCatType.Books, " | - Audiobooks in English");
-            AddCategoryMapping(1580, TorznabCatType.Books, " | - Audiobooks in German");
-            AddCategoryMapping(525, TorznabCatType.Books, " | - Audiobooks in other languages");
-
-            // Обучающее видео
-            AddCategoryMapping(610, TorznabCatType.Books, "Video tutorials and interactive training DVD");
-            AddCategoryMapping(1568, TorznabCatType.Books, " | - Cooking");
-            AddCategoryMapping(1542, TorznabCatType.Books, " | - Sport");
-            AddCategoryMapping(2335, TorznabCatType.Books, " | - Fitness - Cardio, Strength Training");
-            AddCategoryMapping(1544, TorznabCatType.Books, " | - Fitness - Mind and Body");
-            AddCategoryMapping(1545, TorznabCatType.Books, " | - Extreme");
-            AddCategoryMapping(1546, TorznabCatType.Books, " | - Bodybuilding");
-            AddCategoryMapping(1549, TorznabCatType.Books, " | - Health Practice");
-            AddCategoryMapping(1597, TorznabCatType.Books, " | - Yoga");
-            AddCategoryMapping(1552, TorznabCatType.Books, " | - Video and Snapshots");
-            AddCategoryMapping(1550, TorznabCatType.Books, " | - Personal care");
-            AddCategoryMapping(1553, TorznabCatType.Books, " | - Drawing");
-            AddCategoryMapping(1554, TorznabCatType.Books, " | - Playing the guitar");
-            AddCategoryMapping(617, TorznabCatType.Books, " | - Percussion");
-            AddCategoryMapping(1555, TorznabCatType.Books, " | - Other musical instruments");
-            AddCategoryMapping(2017, TorznabCatType.Books, " | - Play the bass guitar");
-            AddCategoryMapping(1257, TorznabCatType.Books, " | - Ballroom dancing");
-            AddCategoryMapping(1258, TorznabCatType.Books, " | - Belly Dance");
-            AddCategoryMapping(2208, TorznabCatType.Books, " | - The street and club dancing");
-            AddCategoryMapping(677, TorznabCatType.Books, " | - Dancing, miscellaneous");
-            AddCategoryMapping(1255, TorznabCatType.Books, " | - Hunting");
-            AddCategoryMapping(1479, TorznabCatType.Books, " | - Fishing and spearfishing");
-            AddCategoryMapping(1261, TorznabCatType.Books, " | - Tricks and stunts");
-            AddCategoryMapping(614, TorznabCatType.Books, " | - Education");
-            AddCategoryMapping(1259, TorznabCatType.Books, " | - Business, Economics and Finance");
-            AddCategoryMapping(2065, TorznabCatType.Books, " | - Pregnancy, childbirth, motherhood");
-            AddCategoryMapping(1254, TorznabCatType.Books, " | - Training videos for children");
-            AddCategoryMapping(1260, TorznabCatType.Books, " | - Psychology");
-            AddCategoryMapping(2209, TorznabCatType.Books, " | - Esoteric, self-development");
-            AddCategoryMapping(2210, TorznabCatType.Books, " | - Van, dating");
-            AddCategoryMapping(1547, TorznabCatType.Books, " | - Construction, repair and design");
-            AddCategoryMapping(1548, TorznabCatType.Books, " | - Wood and metal");
-            AddCategoryMapping(2211, TorznabCatType.Books, " | - Plants and Animals");
-            AddCategoryMapping(615, TorznabCatType.Books, " | - Miscellaneous");
-            AddCategoryMapping(1581, TorznabCatType.Books, "Martial Arts (Video Tutorials)");
-            AddCategoryMapping(1590, TorznabCatType.Books, " | - Aikido and Aiki-jutsu");
-            AddCategoryMapping(1587, TorznabCatType.Books, " | - Vin Chun");
-            AddCategoryMapping(1594, TorznabCatType.Books, " | - Jiu-Jitsu");
-            AddCategoryMapping(1591, TorznabCatType.Books, " | - Judo and Sambo");
-            AddCategoryMapping(1588, TorznabCatType.Books, " | - Karate");
-            AddCategoryMapping(1596, TorznabCatType.Books, " | - Knife Fight");
-            AddCategoryMapping(1585, TorznabCatType.Books, " | - Work with weapon");
-            AddCategoryMapping(1586, TorznabCatType.Books, " | - Russian style");
-            AddCategoryMapping(2078, TorznabCatType.Books, " | - Dogfight");
-            AddCategoryMapping(1929, TorznabCatType.Books, " | - Mixed styles");
-            AddCategoryMapping(1593, TorznabCatType.Books, " | - Percussion styles");
-            AddCategoryMapping(1592, TorznabCatType.Books, " | - This is a");
-            AddCategoryMapping(1595, TorznabCatType.Books, " | - Miscellaneous");
-            AddCategoryMapping(1556, TorznabCatType.Books, "Computer video tutorials and interactive training DVD");
-            AddCategoryMapping(1560, TorznabCatType.Books, " | - Networks and Security");
-            AddCategoryMapping(1561, TorznabCatType.Books, " | - OS and Microsoft Server Software");
-            AddCategoryMapping(1653, TorznabCatType.Books, " | - Microsoft Office program");
-            AddCategoryMapping(1570, TorznabCatType.Books, " | - OS and UNIX family program");
-            AddCategoryMapping(1654, TorznabCatType.Books, " | - Adobe Photoshop");
-            AddCategoryMapping(1655, TorznabCatType.Books, " |- Autodesk Maya");
-            AddCategoryMapping(1656, TorznabCatType.Books, " | - Autodesk 3ds Max");
-            AddCategoryMapping(1930, TorznabCatType.Books, " |- Autodesk Softimage (XSI)");
-            AddCategoryMapping(1931, TorznabCatType.Books, " |- ZBrush");
-            AddCategoryMapping(1932, TorznabCatType.Books, " |- Flash, Flex и ActionScript");
-            AddCategoryMapping(1562, TorznabCatType.Books, " | - 2D-графика");
-            AddCategoryMapping(1563, TorznabCatType.Books, " | - 3D-графика");
-            AddCategoryMapping(1626, TorznabCatType.Books, " | - Engineering and scientific programs");
-            AddCategoryMapping(1564, TorznabCatType.Books, " | - Web-design");
-            AddCategoryMapping(1565, TorznabCatType.Books, " | - Programming");
-            AddCategoryMapping(1559, TorznabCatType.Books, " | - Software for Mac OS");
-            AddCategoryMapping(1566, TorznabCatType.Books, " | - Working with video");
-            AddCategoryMapping(1573, TorznabCatType.Books, " | - Working with sound");
-            AddCategoryMapping(1567, TorznabCatType.Books, " | - Other (Computer video tutorials)");
-
-            // Аудиокниги
-            AddCategoryMapping(2326, TorznabCatType.Audio, "Auditions, history, memoirs");
-            AddCategoryMapping(574, TorznabCatType.Audio, " | - [Audio] Auditions and readings");
-            AddCategoryMapping(1036, TorznabCatType.Audio, " | - [Audio] Lots of great people");
-            AddCategoryMapping(400, TorznabCatType.Audio, " | - [Audio] Historical Book");
-            AddCategoryMapping(2389, TorznabCatType.Audio, "Science fiction, fantasy, mystery, horror, fanfiction");
-            AddCategoryMapping(2388, TorznabCatType.Audio, " | - [Audio] Foreign fiction, fantasy, mystery, horror, ..");
-            AddCategoryMapping(2387, TorznabCatType.Audio, " | - [Audio] Russian fiction, fantasy, mystery, horror, ..");
-            AddCategoryMapping(2348, TorznabCatType.Audio, " | - [Audio] Puzzle / Miscellaneous Science Fiction, Fantasy, Mystery, too ..");
-            AddCategoryMapping(2327, TorznabCatType.Audio, "Fiction");
-            AddCategoryMapping(695, TorznabCatType.Audio, " | - [Audio] Poetry");
-            AddCategoryMapping(399, TorznabCatType.Audio, " | - [Audio] Foreign literature");
-            AddCategoryMapping(402, TorznabCatType.Audio, " | - [Audio] Russian literature");
-            AddCategoryMapping(490, TorznabCatType.Audio, " | - [Audio] Children's Books");
-            AddCategoryMapping(499, TorznabCatType.Audio, " | - [Audio] Detectives, Adventure, Thriller, Action");
-            AddCategoryMapping(2324, TorznabCatType.Audio, "religion");
-            AddCategoryMapping(2325, TorznabCatType.Audio, " | - [Audio] Orthodoxy");
-            AddCategoryMapping(2342, TorznabCatType.Audio, " | - [Audio] Islam");
-            AddCategoryMapping(530, TorznabCatType.Audio, " | - [Audio] Other traditional religion");
-            AddCategoryMapping(2152, TorznabCatType.Audio, " | - [Audio] Non-traditional religious and philosophical teachings");
-            AddCategoryMapping(2328, TorznabCatType.Audio, "other literature");
-            AddCategoryMapping(403, TorznabCatType.Audio, " | - [Audio] academic and popular literature");
-            AddCategoryMapping(1279, TorznabCatType.Audio, " | - [Audio] lossless-audio books");
-            AddCategoryMapping(716, TorznabCatType.Audio, " | - [Audio] Business");
-            AddCategoryMapping(2165, TorznabCatType.Audio, " | - [Audio] Miscellaneous");
-            AddCategoryMapping(401, TorznabCatType.Audio, " | - [Audio], sub-standard distribution");
-
-            // Все по авто и мото
-            AddCategoryMapping(1964, TorznabCatType.Books, "Repair and maintenance of vehicles");
-            AddCategoryMapping(1973, TorznabCatType.Books, " | - Original catalogs on selection of spare parts");
-            AddCategoryMapping(1974, TorznabCatType.Books, " | - Non-original spare parts catalogs for selection");
-            AddCategoryMapping(1975, TorznabCatType.Books, " | - Diagnostic and repair programs");
-            AddCategoryMapping(1976, TorznabCatType.Books, " | - Tuning, chip tuning, tuning");
-            AddCategoryMapping(1977, TorznabCatType.Books, " | - Books for the repair / maintenance / operation of the vehicle");
-            AddCategoryMapping(1203, TorznabCatType.Books, " | - Multimediyki repair / maintenance / operation of the vehicle");
-            AddCategoryMapping(1978, TorznabCatType.Books, " | - Accounting, utilities, etc.");
-            AddCategoryMapping(1979, TorznabCatType.Books, " | - Virtual Driving School");
-            AddCategoryMapping(1980, TorznabCatType.Books, " | - Video lessons on driving vehicles");
-            AddCategoryMapping(1981, TorznabCatType.Books, " | - Tutorials repair vehicles");
-            AddCategoryMapping(1970, TorznabCatType.Books, " | - Journals by car / moto");
-            AddCategoryMapping(334, TorznabCatType.Books, " | - Water transport");
-            AddCategoryMapping(1202, TorznabCatType.Books, "Movies and transfer by car / moto");
-            AddCategoryMapping(1985, TorznabCatType.Books, " | - Documentary / educational films");
-            AddCategoryMapping(1982, TorznabCatType.Books, " | - Entertainment shows");
-            AddCategoryMapping(2151, TorznabCatType.Books, " |- Top Gear/Топ Гир");
-            AddCategoryMapping(1983, TorznabCatType.Books, " | - Test Drive / Reviews / Motor");
-            AddCategoryMapping(1984, TorznabCatType.Books, " | - Tuning / Fast and the Furious");
-
-            // Музыка
-            AddCategoryMapping(409, TorznabCatType.Audio, "Classical and contemporary academic music");
-            AddCategoryMapping(1660, TorznabCatType.Audio, " | - In-house digitizing (Classical Music)");
-            AddCategoryMapping(1164, TorznabCatType.Audio, " | - Multi-channel music (classical and modern classics in ..");
-            AddCategoryMapping(1884, TorznabCatType.Audio, " | - Hi-Res stereo (classic and modern classic in obrabot ..");
-            AddCategoryMapping(445, TorznabCatType.Audio, " | - Classical music (Video)");
-            AddCategoryMapping(984, TorznabCatType.Audio, " | - Classical music (DVD and HD Video)");
-            AddCategoryMapping(702, TorznabCatType.Audio, " | - Opera (Video)");
-            AddCategoryMapping(983, TorznabCatType.Audio, " |- Опера (DVD и HD Видео)");
-            AddCategoryMapping(1990, TorznabCatType.Audio, " | - Ballet and contemporary dance (Video, DVD and HD Video)");
-            AddCategoryMapping(560, TorznabCatType.Audio, " | - Complete collection of works and multi-disc edition (lossl ..");
-            AddCategoryMapping(794, TorznabCatType.Audio, " |- Опера (lossless)");
-            AddCategoryMapping(556, TorznabCatType.Audio, " | - Vocal music (lossless)");
-            AddCategoryMapping(2307, TorznabCatType.Audio, " | - Horovaya Music (lossless)");
-            AddCategoryMapping(557, TorznabCatType.Audio, " | - Orchestral music (lossless)");
-            AddCategoryMapping(2308, TorznabCatType.Audio, " | - Concerto for Orchestra Instrument (lossless)");
-            AddCategoryMapping(558, TorznabCatType.Audio, " | - Chamber instrumental music (lossless)");
-            AddCategoryMapping(793, TorznabCatType.Audio, " | - Solo instrumental music (lossless)");
-            AddCategoryMapping(436, TorznabCatType.Audio, " | - Complete collection of works and multi-disc edition (lossy ..");
-            AddCategoryMapping(2309, TorznabCatType.Audio, " | - Vocal and choral music (lossy)");
-            AddCategoryMapping(2310, TorznabCatType.Audio, " | - Orchestral music (lossy)");
-            AddCategoryMapping(2311, TorznabCatType.Audio, " | - Chamber and solo instrumental music (lossy)");
-            AddCategoryMapping(969, TorznabCatType.Audio, " | - Classics in modern processing, Classical Crossover (l ..");
-            AddCategoryMapping(1125, TorznabCatType.Audio, "Folklore, Folk and World Music");
-            AddCategoryMapping(1130, TorznabCatType.Audio, " |- Восточноевропейский фолк (lossy)");
-            AddCategoryMapping(1131, TorznabCatType.Audio, " | - Eastern European Folk (lossless)");
-            AddCategoryMapping(1132, TorznabCatType.Audio, " |- Западноевропейский фолк (lossy)");
-            AddCategoryMapping(1133, TorznabCatType.Audio, " |- Западноевропейский фолк (lossless)");
-            AddCategoryMapping(2084, TorznabCatType.Audio, " | - Klezmer and Jewish folklore (lossy and lossless)");
-            AddCategoryMapping(1128, TorznabCatType.Audio, " | - World Music Siberia, Central Asia and East Asia (loss ..");
-            AddCategoryMapping(1129, TorznabCatType.Audio, " | - World Music Siberia, Central Asia and East Asia (loss ..");
-            AddCategoryMapping(1856, TorznabCatType.Audio, " | - World Music India (lossy)");
-            AddCategoryMapping(2430, TorznabCatType.Audio, " | - World Music India (lossless)");
-            AddCategoryMapping(1283, TorznabCatType.Audio, " | - World Music Africa and the Middle East (lossy)");
-            AddCategoryMapping(2085, TorznabCatType.Audio, " | - World Music Africa and the Middle East (lossless)");
-            AddCategoryMapping(1282, TorznabCatType.Audio, " | - Ethnic Music of the Caucasus and Transcaucasia (lossy and lossless ..");
-            AddCategoryMapping(1284, TorznabCatType.Audio, " | - World Music Americas (lossy)");
-            AddCategoryMapping(1285, TorznabCatType.Audio, " | - World Music Americas (lossless)");
-            AddCategoryMapping(1138, TorznabCatType.Audio, " | - World Music Australia, the Pacific and Indian oceans ..");
-            AddCategoryMapping(1136, TorznabCatType.Audio, " |- Country, Bluegrass (lossy)");
-            AddCategoryMapping(1137, TorznabCatType.Audio, " |- Country, Bluegrass (lossless)");
-            AddCategoryMapping(1141, TorznabCatType.Audio, " | - Folklore, Folk and World Music (Video)");
-            AddCategoryMapping(1142, TorznabCatType.Audio, " | - Folklore, Folk and World Music (DVD Video)");
-            AddCategoryMapping(2530, TorznabCatType.Audio, " | - Folklore, Folk and World Music (HD Video)");
-            AddCategoryMapping(506, TorznabCatType.Audio, " | - Folklore, Folk and World Music (own otsif ..");
-            AddCategoryMapping(1849, TorznabCatType.Audio, "New Age, Relax, Meditative & Flamenco");
-            AddCategoryMapping(1126, TorznabCatType.Audio, " |- NewAge & Meditative (lossy)");
-            AddCategoryMapping(1127, TorznabCatType.Audio, " |- NewAge & Meditative (lossless)");
-            AddCategoryMapping(1134, TorznabCatType.Audio, " | - Flamenco and acoustic guitar (lossy)");
-            AddCategoryMapping(1135, TorznabCatType.Audio, " | - Flamenco and acoustic guitar (lossless)");
-            AddCategoryMapping(2352, TorznabCatType.Audio, " |- New Age, Relax, Meditative & Flamenco (Видео)");
-            AddCategoryMapping(2351, TorznabCatType.Audio, " |- New Age, Relax, Meditative & Flamenco (DVD и HD Видео)");
-            AddCategoryMapping(855, TorznabCatType.Audio, " | - Sounds of Nature");
-            AddCategoryMapping(408, TorznabCatType.Audio, "Рэп, Хип-Хоп, R'n'B");
-            AddCategoryMapping(441, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop (lossy)");
-            AddCategoryMapping(1173, TorznabCatType.Audio, " |- Отечественный R'n'B (lossy)");
-            AddCategoryMapping(1486, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop, R'n'B (lossless)");
-            AddCategoryMapping(1172, TorznabCatType.Audio, " |- Зарубежный R'n'B (lossy)");
-            AddCategoryMapping(446, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (lossy)");
-            AddCategoryMapping(909, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (lossless)");
-            AddCategoryMapping(1665, TorznabCatType.Audio, " |- Зарубежный R'n'B (lossless)");
-            AddCategoryMapping(1835, TorznabCatType.Audio, " | - Rap, Hip-Hop, R'n'B (own digitization)");
-            AddCategoryMapping(1189, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop (Video)");
-            AddCategoryMapping(1455, TorznabCatType.Audio, " | - Domestic R'n'B (Video)");
-            AddCategoryMapping(442, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (Video)");
-            AddCategoryMapping(1174, TorznabCatType.Audio, " | - Foreign R'n'B (Video)");
-            AddCategoryMapping(1107, TorznabCatType.Audio, " |- Рэп, Хип-Хоп, R'n'B (DVD Video)");
-            AddCategoryMapping(2529, TorznabCatType.Audio, " |- Рэп, Хип-Хоп, R'n'B (HD Видео)");
-            AddCategoryMapping(1760, TorznabCatType.Audio, "Reggae, Ska, Dub");
-            AddCategoryMapping(1764, TorznabCatType.Audio, " | - Rocksteady, Early Reggae, Ska-Jazz, Trad.Ska (lossy и lo ..");
-            AddCategoryMapping(1766, TorznabCatType.Audio, " |- Punky-Reggae, Rocksteady-Punk, Ska Revival (lossy)");
-            AddCategoryMapping(1767, TorznabCatType.Audio, " | - 3rd Wave Ska (lossy)");
-            AddCategoryMapping(1769, TorznabCatType.Audio, " | - Ska-Punk, Ska-Core (lossy)");
-            AddCategoryMapping(1765, TorznabCatType.Audio, " |- Reggae (lossy)");
-            AddCategoryMapping(1771, TorznabCatType.Audio, " |- Dub (lossy)");
-            AddCategoryMapping(1770, TorznabCatType.Audio, " |- Dancehall, Raggamuffin (lossy)");
-            AddCategoryMapping(1768, TorznabCatType.Audio, " |- Reggae, Dancehall, Dub (lossless)");
-            AddCategoryMapping(1774, TorznabCatType.Audio, " | - Ska Ska-Punk, Ska-Jazz (lossless)");
-            AddCategoryMapping(1772, TorznabCatType.Audio, " | - Domestic reggae, dub (lossy and lossless)");
-            AddCategoryMapping(1773, TorznabCatType.Audio, " | - Patriotic ska music (lossy and lossless)");
-            AddCategoryMapping(2233, TorznabCatType.Audio, " | - Reggae, Ska, Dub (компиляции) (lossy и lossless)");
-            AddCategoryMapping(2232, TorznabCatType.Audio, " | - Reggae, Ska, Dub (own digitization)");
-            AddCategoryMapping(1775, TorznabCatType.Audio, " | - Reggae, Ska, Dub (Видео)");
-            AddCategoryMapping(1777, TorznabCatType.Audio, " | - Reggae, Ska, Dub (DVD и HD Video)");
-            AddCategoryMapping(416, TorznabCatType.Audio, "Soundtracks and Karaoke");
-            AddCategoryMapping(782, TorznabCatType.Audio, " | - Karaoke (Audio)");
-            AddCategoryMapping(2377, TorznabCatType.Audio, " | - Karaoke (Video)");
-            AddCategoryMapping(468, TorznabCatType.Audio, " |- Минусовки (lossy и lossless)");
-            AddCategoryMapping(1625, TorznabCatType.Audio, " | - Soundtracks (own digitization)");
-            AddCategoryMapping(691, TorznabCatType.Audio, " | - Soundtracks for domestic films (lossless)");
-            AddCategoryMapping(469, TorznabCatType.Audio, " | - Soundtracks for domestic films (lossy)");
-            AddCategoryMapping(786, TorznabCatType.Audio, " | - Soundtracks for foreign films (lossless)");
-            AddCategoryMapping(785, TorznabCatType.Audio, " | - Soundtracks for foreign films (lossy)");
-            AddCategoryMapping(796, TorznabCatType.Audio, " | - Informal soundtracks for films and TV series (lossy)");
-            AddCategoryMapping(784, TorznabCatType.Audio, " | - Soundtracks for games (lossless)");
-            AddCategoryMapping(783, TorznabCatType.Audio, " | - Soundtracks for games (lossy)");
-            AddCategoryMapping(2331, TorznabCatType.Audio, " | - Informal soundtracks for games (lossy)");
-            AddCategoryMapping(2431, TorznabCatType.Audio, " | - The arrangements of music from the game (lossy and lossless)");
-            AddCategoryMapping(1397, TorznabCatType.Audio, " | - Hi-Res stereo and multi-channel music (Soundtracks)");
-            AddCategoryMapping(1215, TorznabCatType.Audio, "Chanson, Author and military songs");
-            AddCategoryMapping(1220, TorznabCatType.Audio, " | - The domestic chanson (lossless)");
-            AddCategoryMapping(1221, TorznabCatType.Audio, " | - The domestic chanson (lossy)");
-            AddCategoryMapping(1334, TorznabCatType.Audio, " | - Compilations domestic chanson (lossy)");
-            AddCategoryMapping(1216, TorznabCatType.Audio, " | - War Song (lossless)");
-            AddCategoryMapping(1223, TorznabCatType.Audio, " | - War Song (lossy)");
-            AddCategoryMapping(1224, TorznabCatType.Audio, " | - Chanson (lossless)");
-            AddCategoryMapping(1225, TorznabCatType.Audio, " | - Chanson (lossy)");
-            AddCategoryMapping(1226, TorznabCatType.Audio, " |- Менестрели и ролевики (lossy и lossless)");
-            AddCategoryMapping(1217, TorznabCatType.Audio, " | - In-house digitizing (Chanson, and Bards) lossles ..");
-            AddCategoryMapping(1227, TorznabCatType.Audio, " | - Video (Chanson, and Bards)");
-            AddCategoryMapping(1228, TorznabCatType.Audio, " | - DVD Video (Chanson, and Bards)");
-            AddCategoryMapping(413, TorznabCatType.Audio, "Music of other genres");
-            AddCategoryMapping(974, TorznabCatType.Audio, " | - In-house digitizing (Music from other genres)");
-            AddCategoryMapping(463, TorznabCatType.Audio, " | - Patriotic music of other genres (lossy)");
-            AddCategoryMapping(464, TorznabCatType.Audio, " | - Patriotic music of other genres (lossless)");
-            AddCategoryMapping(466, TorznabCatType.Audio, " | - International music of other genres (lossy)");
-            AddCategoryMapping(465, TorznabCatType.Audio, " | - International music of other genres (lossless)");
-            AddCategoryMapping(2018, TorznabCatType.Audio, " | - Music for ballroom dancing (lossy and lossless)");
-            AddCategoryMapping(1396, TorznabCatType.Audio, " | - Orthodox chants (lossy)");
-            AddCategoryMapping(1395, TorznabCatType.Audio, " | - Orthodox chants (lossless)");
-            AddCategoryMapping(1351, TorznabCatType.Audio, " | - A collection of songs for children (lossy and lossless)");
-            AddCategoryMapping(475, TorznabCatType.Audio, " | - Video (Music from other genres)");
-            AddCategoryMapping(988, TorznabCatType.Audio, " | - DVD Video (Music from other genres)");
-            AddCategoryMapping(880, TorznabCatType.Audio, " | - The Musical (lossy and lossless)");
-            AddCategoryMapping(655, TorznabCatType.Audio, " | - The Musical (Video and DVD Video)");
-            AddCategoryMapping(965, TorznabCatType.Audio, " | - Informal and vnezhanrovye collections (lossy)");
-            AddCategoryMapping(919, TorznabCatType.Audio, "Sheet Music literature");
-            AddCategoryMapping(944, TorznabCatType.Audio, " | - Academic Music (Notes and Media CD)");
-            AddCategoryMapping(980, TorznabCatType.Audio, " | - Other destinations (notes, tablature)");
-            AddCategoryMapping(946, TorznabCatType.Audio, " | - Tutorials and Schools");
-            AddCategoryMapping(977, TorznabCatType.Audio, " | - Songbooks (Songbooks)");
-            AddCategoryMapping(2074, TorznabCatType.Audio, " | - Music Literature and Theory");
-            AddCategoryMapping(2349, TorznabCatType.Audio, " | - Music Magazines");
-
-            // Популярная музыка
-            AddCategoryMapping(2495, TorznabCatType.Audio, "Domestic Pop");
-            AddCategoryMapping(424, TorznabCatType.Audio, " | - Patriotic Pop (lossy)");
-            AddCategoryMapping(1361, TorznabCatType.Audio, " | - Patriotic Pop music (collections) (lossy)");
-            AddCategoryMapping(425, TorznabCatType.Audio, " | - Patriotic Pop (lossless)");
-            AddCategoryMapping(1635, TorznabCatType.Audio, " | - Soviet pop music, retro (lossy)");
-            AddCategoryMapping(1634, TorznabCatType.Audio, " | - Soviet pop music, retro (lossless)");
-            AddCategoryMapping(2497, TorznabCatType.Audio, "Foreign pop music");
-            AddCategoryMapping(428, TorznabCatType.Audio, " | - Foreign pop music (lossy)");
-            AddCategoryMapping(1362, TorznabCatType.Audio, " | - Foreign pop music (collections) (lossy)");
-            AddCategoryMapping(429, TorznabCatType.Audio, " | - International Pop (lossless)");
-            AddCategoryMapping(1219, TorznabCatType.Audio, " | - Foreign chanson (lossy)");
-            AddCategoryMapping(1452, TorznabCatType.Audio, " | - Foreign chanson (lossless)");
-            AddCategoryMapping(1331, TorznabCatType.Audio, " | - East Asian pop music (lossy)");
-            AddCategoryMapping(1330, TorznabCatType.Audio, " | - East Asian Pop (lossless)");
-            AddCategoryMapping(2499, TorznabCatType.Audio, "Eurodance, Disco, Hi-NRG");
-            AddCategoryMapping(2503, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (lossy)");
-            AddCategoryMapping(2504, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (сборники) (lossy)");
-            AddCategoryMapping(2502, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (lossless)");
-            AddCategoryMapping(2501, TorznabCatType.Audio, " |- Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossy)");
-            AddCategoryMapping(2505, TorznabCatType.Audio, " | - Disco, Italo-Disco, Euro-Disco, Hi-NRG (сборники) (lossy ..");
-            AddCategoryMapping(2500, TorznabCatType.Audio, " |- Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossless)");
-            AddCategoryMapping(2507, TorznabCatType.Audio, "Видео, DVD Video, HD Video (поп-музыка)");
-            AddCategoryMapping(1121, TorznabCatType.Audio, " | - Patriotic Pop (Video)");
-            AddCategoryMapping(1122, TorznabCatType.Audio, " | - Patriotic Pop (DVD Video)");
-            AddCategoryMapping(2510, TorznabCatType.Audio, " | - Soviet pop music, retro (video)");
-            AddCategoryMapping(2509, TorznabCatType.Audio, " | - Soviet pop music, retro (DVD Video)");
-            AddCategoryMapping(431, TorznabCatType.Audio, " | - Foreign pop music (Video)");
-            AddCategoryMapping(986, TorznabCatType.Audio, " | - Foreign pop music (DVD Video)");
-            AddCategoryMapping(2532, TorznabCatType.Audio, " |- Eurodance, Disco (видео)");
-            AddCategoryMapping(2531, TorznabCatType.Audio, " |- Eurodance, Disco (DVD Video)");
-            AddCategoryMapping(2378, TorznabCatType.Audio, " | - East Asian pop music (Video)");
-            AddCategoryMapping(2379, TorznabCatType.Audio, " | - East Asian pop music (DVD Video)");
-            AddCategoryMapping(2383, TorznabCatType.Audio, " | - Foreign chanson (Video)");
-            AddCategoryMapping(2384, TorznabCatType.Audio, " | - Foreign chanson (DVD Video)");
-            AddCategoryMapping(2088, TorznabCatType.Audio, " | - Patriotic Pop (National concerts, video dock.) ..");
-            AddCategoryMapping(2089, TorznabCatType.Audio, " | - Foreign pop music (National concerts, video dock.) (Bu ..");
-            AddCategoryMapping(2426, TorznabCatType.Audio, " | - Patriotic Pop Music, Chanson, Eurodance, Disco (HD V ..");
-            AddCategoryMapping(2508, TorznabCatType.Audio, " | - International Pop Music, Chanson, Eurodance, Disco (HD Vide ..");
-            AddCategoryMapping(2512, TorznabCatType.Audio, "The multi-channel music and own digitization (pop music)");
-            AddCategoryMapping(1444, TorznabCatType.Audio, " | - Foreign pop music (own digitization)");
-            AddCategoryMapping(1785, TorznabCatType.Audio, " | - Eastern pop music (own digitization)");
-            AddCategoryMapping(239, TorznabCatType.Audio, " | - Patriotic Pop (own digitization)");
-            AddCategoryMapping(450, TorznabCatType.Audio, " | - Instrumental Pop (own digitization)");
-            AddCategoryMapping(1163, TorznabCatType.Audio, " | - Multi-channel music (pop music)");
-            AddCategoryMapping(1885, TorznabCatType.Audio, " |- Hi-Res stereo (Поп-музыка)");
-
-            // Джазовая и Блюзовая музыка
-            AddCategoryMapping(2267, TorznabCatType.Audio, "foreign jazz");
-            AddCategoryMapping(2277, TorznabCatType.Audio, " |- Early Jazz, Swing, Gypsy (lossless)");
-            AddCategoryMapping(2278, TorznabCatType.Audio, " |- Bop (lossless)");
-            AddCategoryMapping(2279, TorznabCatType.Audio, " |- Mainstream Jazz, Cool (lossless)");
-            AddCategoryMapping(2280, TorznabCatType.Audio, " |- Jazz Fusion (lossless)");
-            AddCategoryMapping(2281, TorznabCatType.Audio, " |- World Fusion, Ethnic Jazz (lossless)");
-            AddCategoryMapping(2282, TorznabCatType.Audio, " |- Avant-Garde Jazz, Free Improvisation (lossless)");
-            AddCategoryMapping(2353, TorznabCatType.Audio, " |- Modern Creative, Third Stream (lossless)");
-            AddCategoryMapping(2284, TorznabCatType.Audio, " |- Smooth, Jazz-Pop (lossless)");
-            AddCategoryMapping(2285, TorznabCatType.Audio, " |- Vocal Jazz (lossless)");
-            AddCategoryMapping(2283, TorznabCatType.Audio, " |- Funk, Soul, R&B (lossless)");
-            AddCategoryMapping(2286, TorznabCatType.Audio, " | - Compilations foreign jazz (lossless)");
-            AddCategoryMapping(2287, TorznabCatType.Audio, " | - Foreign jazz (lossy)");
-            AddCategoryMapping(2268, TorznabCatType.Audio, "foreign blues");
-            AddCategoryMapping(2293, TorznabCatType.Audio, " |- Blues (Texas, Chicago, Modern and Others) (lossless)");
-            AddCategoryMapping(2292, TorznabCatType.Audio, " |- Blues-rock (lossless)");
-            AddCategoryMapping(2290, TorznabCatType.Audio, " |- Roots, Pre-War Blues, Early R&B, Gospel (lossless)");
-            AddCategoryMapping(2289, TorznabCatType.Audio, " | - Foreign blues (collections; Tribute VA) (lossless)");
-            AddCategoryMapping(2288, TorznabCatType.Audio, " | - Foreign blues (lossy)");
-            AddCategoryMapping(2269, TorznabCatType.Audio, "Domestic jazz and blues");
-            AddCategoryMapping(2297, TorznabCatType.Audio, " | - Domestic Jazz (lossless)");
-            AddCategoryMapping(2295, TorznabCatType.Audio, " | - Domestic jazz (lossy)");
-            AddCategoryMapping(2296, TorznabCatType.Audio, " | - Domestic Blues (lossless)");
-            AddCategoryMapping(2298, TorznabCatType.Audio, " | - Domestic Blues (lossy)");
-            AddCategoryMapping(2270, TorznabCatType.Audio, "The multi-channel music and own digitization (Jazz and Blues)");
-            AddCategoryMapping(2303, TorznabCatType.Audio, " | - Multi-channel music (Jazz and Blues)");
-            AddCategoryMapping(2302, TorznabCatType.Audio, " | - Hi-Res stereo (Jazz and Blues)");
-            AddCategoryMapping(2301, TorznabCatType.Audio, " | - In-house digitizing (Jazz and Blues)");
-            AddCategoryMapping(2271, TorznabCatType.Audio, "Video, DVD Video, HD Video (Jazz and Blues)");
-            AddCategoryMapping(2305, TorznabCatType.Audio, " | - Jazz and Blues (Video)");
-            AddCategoryMapping(2304, TorznabCatType.Audio, " | - Jazz and Blues (DVD Video)");
-            AddCategoryMapping(2306, TorznabCatType.Audio, " | - Jazz and Blues (HD Video)");
-
-            // Рок-музыка
-            AddCategoryMapping(1698, TorznabCatType.Audio, "foreign Rock");
-            AddCategoryMapping(1702, TorznabCatType.Audio, " |- Classic Rock & Hard Rock (lossless)");
-            AddCategoryMapping(1703, TorznabCatType.Audio, " |- Classic Rock & Hard Rock (lossy)");
-            AddCategoryMapping(1704, TorznabCatType.Audio, " |- Progressive & Art-Rock (lossless)");
-            AddCategoryMapping(1705, TorznabCatType.Audio, " |- Progressive & Art-Rock (lossy)");
-            AddCategoryMapping(1706, TorznabCatType.Audio, " |- Folk-Rock (lossless)");
-            AddCategoryMapping(1707, TorznabCatType.Audio, " |- Folk-Rock (lossy)");
-            AddCategoryMapping(2329, TorznabCatType.Audio, " |- AOR (Melodic Hard Rock, Arena rock) (lossless)");
-            AddCategoryMapping(2330, TorznabCatType.Audio, " |- AOR (Melodic Hard Rock, Arena rock) (lossy)");
-            AddCategoryMapping(1708, TorznabCatType.Audio, " |- Pop-Rock & Soft Rock (lossless)");
-            AddCategoryMapping(1709, TorznabCatType.Audio, " |- Pop-Rock & Soft Rock (lossy)");
-            AddCategoryMapping(1710, TorznabCatType.Audio, " |- Instrumental Guitar Rock (lossless)");
-            AddCategoryMapping(1711, TorznabCatType.Audio, " |- Instrumental Guitar Rock (lossy)");
-            AddCategoryMapping(1712, TorznabCatType.Audio, " |- Rockabilly, Psychobilly, Rock'n'Roll (lossless)");
-            AddCategoryMapping(1713, TorznabCatType.Audio, " |- Rockabilly, Psychobilly, Rock'n'Roll (lossy)");
-            AddCategoryMapping(731, TorznabCatType.Audio, " | - Compilations foreign rock (lossless)");
-            AddCategoryMapping(1799, TorznabCatType.Audio, " | - Compilations foreign rock (lossy)");
-            AddCategoryMapping(1714, TorznabCatType.Audio, " | - East Asian Rock (lossless)");
-            AddCategoryMapping(1715, TorznabCatType.Audio, " | - East Asian rock (lossy)");
-            AddCategoryMapping(1716, TorznabCatType.Audio, "foreign Metal");
-            AddCategoryMapping(1796, TorznabCatType.Audio, " |- Avant-garde, Experimental Metal (lossless)");
-            AddCategoryMapping(1797, TorznabCatType.Audio, " |- Avant-garde, Experimental Metal (lossy)");
-            AddCategoryMapping(1719, TorznabCatType.Audio, " |- Black (lossless)");
-            AddCategoryMapping(1778, TorznabCatType.Audio, " |- Black (lossy)");
-            AddCategoryMapping(1779, TorznabCatType.Audio, " |- Death, Doom (lossless)");
-            AddCategoryMapping(1780, TorznabCatType.Audio, " |- Death, Doom (lossy)");
-            AddCategoryMapping(1720, TorznabCatType.Audio, " |- Folk, Pagan, Viking (lossless)");
-            AddCategoryMapping(798, TorznabCatType.Audio, " |- Folk, Pagan, Viking (lossy)");
-            AddCategoryMapping(1724, TorznabCatType.Audio, " |- Gothic Metal (lossless)");
-            AddCategoryMapping(1725, TorznabCatType.Audio, " |- Gothic Metal (lossy)");
-            AddCategoryMapping(1730, TorznabCatType.Audio, " |- Grind, Brutal Death (lossless)");
-            AddCategoryMapping(1731, TorznabCatType.Audio, " |- Grind, Brutal Death (lossy)");
-            AddCategoryMapping(1726, TorznabCatType.Audio, " |- Heavy, Power, Progressive (lossless)");
-            AddCategoryMapping(1727, TorznabCatType.Audio, " |- Heavy, Power, Progressive (lossy)");
-            AddCategoryMapping(1815, TorznabCatType.Audio, " |- Sludge, Stoner, Post-Metal (lossless)");
-            AddCategoryMapping(1816, TorznabCatType.Audio, " |- Sludge, Stoner, Post-Metal (lossy)");
-            AddCategoryMapping(1728, TorznabCatType.Audio, " |- Thrash, Speed (lossless)");
-            AddCategoryMapping(1729, TorznabCatType.Audio, " |- Thrash, Speed (lossy)");
-            AddCategoryMapping(2230, TorznabCatType.Audio, " | - Compilations (lossless)");
-            AddCategoryMapping(2231, TorznabCatType.Audio, " | - Compilations (lossy)");
-            AddCategoryMapping(1732, TorznabCatType.Audio, "Foreign Alternative, Punk, Independent");
-            AddCategoryMapping(1736, TorznabCatType.Audio, " |- Alternative & Nu-metal (lossless)");
-            AddCategoryMapping(1737, TorznabCatType.Audio, " |- Alternative & Nu-metal (lossy)");
-            AddCategoryMapping(1738, TorznabCatType.Audio, " |- Punk (lossless)");
-            AddCategoryMapping(1739, TorznabCatType.Audio, " |- Punk (lossy)");
-            AddCategoryMapping(1740, TorznabCatType.Audio, " |- Hardcore (lossless)");
-            AddCategoryMapping(1741, TorznabCatType.Audio, " |- Hardcore (lossy)");
-            AddCategoryMapping(1742, TorznabCatType.Audio, " |- Indie, Post-Rock & Post-Punk (lossless)");
-            AddCategoryMapping(1743, TorznabCatType.Audio, " |- Indie, Post-Rock & Post-Punk (lossy)");
-            AddCategoryMapping(1744, TorznabCatType.Audio, " |- Industrial & Post-industrial (lossless)");
-            AddCategoryMapping(1745, TorznabCatType.Audio, " |- Industrial & Post-industrial (lossy)");
-            AddCategoryMapping(1746, TorznabCatType.Audio, " |- Emocore, Post-hardcore, Metalcore (lossless)");
-            AddCategoryMapping(1747, TorznabCatType.Audio, " |- Emocore, Post-hardcore, Metalcore (lossy)");
-            AddCategoryMapping(1748, TorznabCatType.Audio, " |- Gothic Rock & Dark Folk (lossless)");
-            AddCategoryMapping(1749, TorznabCatType.Audio, " |- Gothic Rock & Dark Folk (lossy)");
-            AddCategoryMapping(2175, TorznabCatType.Audio, " |- Avant-garde, Experimental Rock (lossless)");
-            AddCategoryMapping(2174, TorznabCatType.Audio, " |- Avant-garde, Experimental Rock (lossy)");
-            AddCategoryMapping(722, TorznabCatType.Audio, "Domestic Rock");
-            AddCategoryMapping(737, TorznabCatType.Audio, " | - Rock, Punk, Alternative (lossless)");
-            AddCategoryMapping(738, TorznabCatType.Audio, " | - Rock, Punk, Alternative (lossy)");
-            AddCategoryMapping(739, TorznabCatType.Audio, " |- Металл (lossless)");
-            AddCategoryMapping(740, TorznabCatType.Audio, " |- Металл (lossy)");
-            AddCategoryMapping(951, TorznabCatType.Audio, " | - Rock in the languages &#8203;&#8203;of xUSSR (lossless)");
-            AddCategoryMapping(952, TorznabCatType.Audio, " | - Rock in the languages &#8203;&#8203;of xUSSR (lossy)");
-            AddCategoryMapping(1752, TorznabCatType.Audio, "The multi-channel music and own digitization (Rock)");
-            AddCategoryMapping(1756, TorznabCatType.Audio, " | - Foreign rock (own digitization)");
-            AddCategoryMapping(1758, TorznabCatType.Audio, " | - Domestic Rock (own digitization)");
-            AddCategoryMapping(1757, TorznabCatType.Audio, " | - Multi-channel music (rock)");
-            AddCategoryMapping(1755, TorznabCatType.Audio, " |- Hi-Res stereo (рок)");
-            AddCategoryMapping(453, TorznabCatType.Audio, " | - Conversions Quadraphonic (multichannel music)");
-            AddCategoryMapping(1170, TorznabCatType.Audio, " | - Conversions SACD (multi-channel music)");
-            AddCategoryMapping(1759, TorznabCatType.Audio, " | - Conversions from the Blu-Ray (multichannel music)");
-            AddCategoryMapping(1852, TorznabCatType.Audio, " |- Апмиксы-Upmixes/Даунмиксы-Downmix (многоканальная и Hi-R..");
-            AddCategoryMapping(1781, TorznabCatType.Audio, "Видео, DVD Video, HD Video (Рок-музыка)");
-            AddCategoryMapping(1782, TorznabCatType.Audio, " |- Rock (Видео)");
-            AddCategoryMapping(1783, TorznabCatType.Audio, " |- Rock (DVD Video)");
-            AddCategoryMapping(2261, TorznabCatType.Audio, " | - Rock (Unofficial DVD Video)");
-            AddCategoryMapping(1787, TorznabCatType.Audio, " |- Metal (Видео)");
-            AddCategoryMapping(1788, TorznabCatType.Audio, " |- Metal (DVD Video)");
-            AddCategoryMapping(2262, TorznabCatType.Audio, " | - Metal (Unofficial DVD Video)");
-            AddCategoryMapping(1789, TorznabCatType.Audio, " |- Alternative, Punk, Independent (Видео)");
-            AddCategoryMapping(1790, TorznabCatType.Audio, " |- Alternative, Punk, Independent (DVD Video)");
-            AddCategoryMapping(2263, TorznabCatType.Audio, " |- Alternative, Punk, Independent (Неофициальные DVD Video)");
-            AddCategoryMapping(1791, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative (Video)");
-            AddCategoryMapping(1792, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative (DVD Video)");
-            AddCategoryMapping(1793, TorznabCatType.Audio, " | - Domestic Metal (Video)");
-            AddCategoryMapping(1794, TorznabCatType.Audio, " | - Domestic Metal (DVD Video)");
-            AddCategoryMapping(2264, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative, Metal (Neofitsial ..");
-            AddCategoryMapping(1795, TorznabCatType.Audio, " | - Rock (HD Video)");
-
-            // Электронная музыка
-            AddCategoryMapping(1821, TorznabCatType.Audio, "Trance, Goa Trance, Psy-Trance, PsyChill, Ambient, Dub");
-            AddCategoryMapping(1844, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance (lossless)");
-            AddCategoryMapping(1822, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance (lossy)");
-            AddCategoryMapping(1894, TorznabCatType.Audio, " |- PsyChill, Ambient, Dub (lossless)");
-            AddCategoryMapping(1895, TorznabCatType.Audio, " |- PsyChill, Ambient, Dub (lossy)");
-            AddCategoryMapping(460, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance, PsyChill, Ambient, Dub (Live Set..");
-            AddCategoryMapping(1818, TorznabCatType.Audio, " |- Trance (lossless)");
-            AddCategoryMapping(1819, TorznabCatType.Audio, " |- Trance (lossy)");
-            AddCategoryMapping(1847, TorznabCatType.Audio, " |- Trance (Singles, EPs) (lossy)");
-            AddCategoryMapping(1824, TorznabCatType.Audio, " |- Trance (Radioshows, Podcasts, Live Sets, Mixes) (lossy)");
-            AddCategoryMapping(1807, TorznabCatType.Audio, "House, Techno, Hardcore, Hardstyle, Jumpstyle");
-            AddCategoryMapping(1829, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (lossless)");
-            AddCategoryMapping(1830, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (lossy)");
-            AddCategoryMapping(1831, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (vinyl, web)");
-            AddCategoryMapping(1857, TorznabCatType.Audio, " |- House (lossless)");
-            AddCategoryMapping(1859, TorznabCatType.Audio, " |- House (Radioshow, Podcast, Liveset, Mixes)");
-            AddCategoryMapping(1858, TorznabCatType.Audio, " |- House (lossy)");
-            AddCategoryMapping(840, TorznabCatType.Audio, " | - House (Promorelyzы, collections of)");
-            AddCategoryMapping(1860, TorznabCatType.Audio, " |- House (Singles, EPs) (lossy)");
-            AddCategoryMapping(1825, TorznabCatType.Audio, " |- Techno (lossless)");
-            AddCategoryMapping(1826, TorznabCatType.Audio, " |- Techno (lossy)");
-            AddCategoryMapping(1827, TorznabCatType.Audio, " |- Techno (Radioshows, Podcasts, Livesets, Mixes)");
-            AddCategoryMapping(1828, TorznabCatType.Audio, " |- Techno (Singles, EPs) (lossy)");
-            AddCategoryMapping(1808, TorznabCatType.Audio, "Drum & Bass, Jungle, Breakbeat, Dubstep, IDM, Electro");
-            AddCategoryMapping(797, TorznabCatType.Audio, " |- Electro, Electro-Freestyle, Nu Electro (lossless)");
-            AddCategoryMapping(1805, TorznabCatType.Audio, " |- Electro, Electro-Freestyle, Nu Electro (lossy)");
-            AddCategoryMapping(1832, TorznabCatType.Audio, " |- Drum & Bass, Jungle (lossless)");
-            AddCategoryMapping(1833, TorznabCatType.Audio, " |- Drum & Bass, Jungle (lossy)");
-            AddCategoryMapping(1834, TorznabCatType.Audio, " |- Drum & Bass, Jungle (Radioshows, Podcasts, Livesets, Mix..");
-            AddCategoryMapping(1836, TorznabCatType.Audio, " |- Breakbeat (lossless)");
-            AddCategoryMapping(1837, TorznabCatType.Audio, " |- Breakbeat (lossy)");
-            AddCategoryMapping(1839, TorznabCatType.Audio, " |- Dubstep (lossless)");
-            AddCategoryMapping(454, TorznabCatType.Audio, " |- Dubstep (lossy)");
-            AddCategoryMapping(1838, TorznabCatType.Audio, " |- Breakbeat, Dubstep (Radioshows, Podcasts, Livesets, Mixe..");
-            AddCategoryMapping(1840, TorznabCatType.Audio, " |- IDM (lossless)");
-            AddCategoryMapping(1841, TorznabCatType.Audio, " |- IDM (lossy)");
-            AddCategoryMapping(2229, TorznabCatType.Audio, " |- IDM Discography & Collections (lossy)");
-            AddCategoryMapping(1809, TorznabCatType.Audio, "Chillout, Lounge, Downtempo, Trip-Hop");
-            AddCategoryMapping(1861, TorznabCatType.Audio, " |- Chillout, Lounge, Downtempo (lossless)");
-            AddCategoryMapping(1862, TorznabCatType.Audio, " |- Chillout, Lounge, Downtempo (lossy)");
-            AddCategoryMapping(1947, TorznabCatType.Audio, " |- Nu Jazz, Acid Jazz, Future Jazz (lossless)");
-            AddCategoryMapping(1946, TorznabCatType.Audio, " |- Nu Jazz, Acid Jazz, Future Jazz (lossy)");
-            AddCategoryMapping(1945, TorznabCatType.Audio, " |- Trip Hop, Abstract Hip-Hop (lossless)");
-            AddCategoryMapping(1944, TorznabCatType.Audio, " |- Trip Hop, Abstract Hip-Hop (lossy)");
-            AddCategoryMapping(1810, TorznabCatType.Audio, "Traditional Electronic, Ambient, Modern Classical, Electroac..");
-            AddCategoryMapping(1864, TorznabCatType.Audio, " |- Traditional Electronic, Ambient (lossless)");
-            AddCategoryMapping(1865, TorznabCatType.Audio, " |- Traditional Electronic, Ambient (lossy)");
-            AddCategoryMapping(1871, TorznabCatType.Audio, " |- Modern Classical, Electroacoustic (lossless)");
-            AddCategoryMapping(1867, TorznabCatType.Audio, " |- Modern Classical, Electroacoustic (lossy)");
-            AddCategoryMapping(1869, TorznabCatType.Audio, " |- Experimental (lossless)");
-            AddCategoryMapping(1873, TorznabCatType.Audio, " |- Experimental (lossy)");
-            AddCategoryMapping(1907, TorznabCatType.Audio, " |- 8-bit, Chiptune (lossy & lossless)");
-            AddCategoryMapping(1811, TorznabCatType.Audio, "Industrial, Noise, EBM, Dark Electro, Aggrotech, Synthpop, N..");
-            AddCategoryMapping(1868, TorznabCatType.Audio, " | - EBM, Dark Electro, Aggrotech (lossless)");
-            AddCategoryMapping(1875, TorznabCatType.Audio, " | - EBM, Dark Electro, Aggrotech (lossy)");
-            AddCategoryMapping(1877, TorznabCatType.Audio, " |- Industrial, Noise (lossless)");
-            AddCategoryMapping(1878, TorznabCatType.Audio, " |- Industrial, Noise (lossy)");
-            AddCategoryMapping(1880, TorznabCatType.Audio, " |- Synthpop, New Wave (lossless)");
-            AddCategoryMapping(1881, TorznabCatType.Audio, " |- Synthpop, New Wave (lossy)");
-            AddCategoryMapping(1866, TorznabCatType.Audio, " |- Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossles..");
-            AddCategoryMapping(406, TorznabCatType.Audio, " |- Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossy)");
-            AddCategoryMapping(1842, TorznabCatType.Audio, "Label Packs (lossless)");
-            AddCategoryMapping(1648, TorznabCatType.Audio, "Label packs, Scene packs (lossy)");
-            AddCategoryMapping(1812, TorznabCatType.Audio, "Электронная музыка (Видео, DVD Video/Audio, HD Video, DTS, S..");
-            AddCategoryMapping(1886, TorznabCatType.Audio, " | - Electronic music (Official DVD Video)");
-            AddCategoryMapping(1887, TorznabCatType.Audio, " | - Electronic music (Informal amateur DVD Vide ..");
-            AddCategoryMapping(1912, TorznabCatType.Audio, " | - Electronic music (Video)");
-            AddCategoryMapping(1893, TorznabCatType.Audio, " | - Hi-Res stereo (electronic music)");
-            AddCategoryMapping(1890, TorznabCatType.Audio, " | - Multi-channel music (electronic music)");
-            AddCategoryMapping(1913, TorznabCatType.Audio, " | - Electronic music (HD Video)");
-            AddCategoryMapping(1754, TorznabCatType.Audio, " | - Electronic music (own digitization)");
-
-            // Игры
-            AddCategoryMapping(5, TorznabCatType.PCGames, "Games for Windows (download)");
-            AddCategoryMapping(635, TorznabCatType.PCGames, " | - Hot New Releases");
-            AddCategoryMapping(127, TorznabCatType.PCGames, " | - Arcade");
-            AddCategoryMapping(2204, TorznabCatType.PCGames, " | - Puzzle Games");
-            AddCategoryMapping(53, TorznabCatType.PCGames, " | - Adventure and quests");
-            AddCategoryMapping(1008, TorznabCatType.PCGames, " | - Quest-style \"search objects\"");
-            AddCategoryMapping(51, TorznabCatType.PCGames, " | - Strategy");
-            AddCategoryMapping(961, TorznabCatType.PCGames, " | - Space and flight simulators");
-            AddCategoryMapping(962, TorznabCatType.PCGames, " | - Autos and Racing");
-            AddCategoryMapping(2187, TorznabCatType.PCGames, " | - Racing Simulators");
-            AddCategoryMapping(54, TorznabCatType.PCGames, " | - Other simulators");
-            AddCategoryMapping(55, TorznabCatType.PCGames, " |- Action");
-            AddCategoryMapping(2203, TorznabCatType.PCGames, " | - Fighting");
-            AddCategoryMapping(52, TorznabCatType.PCGames, " |- RPG");
-            AddCategoryMapping(900, TorznabCatType.PCGames, " | - Anime games");
-            AddCategoryMapping(246, TorznabCatType.PCGames, " | - Erotic Games");
-            AddCategoryMapping(278, TorznabCatType.PCGames, " | - Chess");
-            AddCategoryMapping(128, TorznabCatType.PCGames, " | - For the little ones");
-            AddCategoryMapping(637, TorznabCatType.PCGames, "Old Games");
-            AddCategoryMapping(642, TorznabCatType.PCGames, " | - Arcade (Old Games)");
-            AddCategoryMapping(2385, TorznabCatType.PCGames, " | - Puzzle games (old games)");
-            AddCategoryMapping(643, TorznabCatType.PCGames, " | - Adventure and quests (Old Games)");
-            AddCategoryMapping(644, TorznabCatType.PCGames, " | - Strategies (Old Games)");
-            AddCategoryMapping(2226, TorznabCatType.PCGames, " | - Space and flight simulators (Old Games)");
-            AddCategoryMapping(2227, TorznabCatType.PCGames, " | - Autos and Racing (Old Games)");
-            AddCategoryMapping(2225, TorznabCatType.PCGames, " | - Racing Simulators (Old Games)");
-            AddCategoryMapping(645, TorznabCatType.PCGames, " | - Other simulators (Old Games)");
-            AddCategoryMapping(646, TorznabCatType.PCGames, " | - Action (Old Games)");
-            AddCategoryMapping(647, TorznabCatType.PCGames, " | - RPG (Old Games)");
-            AddCategoryMapping(649, TorznabCatType.PCGames, " | - Erotic Games (Old Games)");
-            AddCategoryMapping(650, TorznabCatType.PCGames, " | - For the little ones (Old Games)");
-            AddCategoryMapping(1098, TorznabCatType.PCGames, " | - Game Collection (Old Games)");
-            AddCategoryMapping(2228, TorznabCatType.PCGames, " | - IBM PC incompatible (Old Games)");
-            AddCategoryMapping(2115, TorznabCatType.PCGames, "Online Games");
-            AddCategoryMapping(2117, TorznabCatType.PCGames, " |- World of Warcraft");
-            AddCategoryMapping(2155, TorznabCatType.PCGames, " |- Lineage II");
-            AddCategoryMapping(2118, TorznabCatType.PCGames, " | - MMO (Official)");
-            AddCategoryMapping(2119, TorznabCatType.PCGames, " | - MMO (Neoficialʹnye)");
-            AddCategoryMapping(2489, TorznabCatType.PCGames, " | - Multiplayer games");
-            AddCategoryMapping(2142, TorznabCatType.PCGames, "Microsoft Flight Simulator add-ons, and for him");
-            AddCategoryMapping(2143, TorznabCatType.PCGames, " | - Scripts, meshes and airports [FS2004]");
-            AddCategoryMapping(2060, TorznabCatType.PCGames, " |- Сценарии (FSX-P3D)");
-            AddCategoryMapping(2145, TorznabCatType.PCGames, " | - Aircraft [FS2004]");
-            AddCategoryMapping(2012, TorznabCatType.PCGames, " | - Planes, helicopters (FSX-P3D)");
-            AddCategoryMapping(2146, TorznabCatType.PCGames, " | - Mission, traffic sounds, packs and tools");
-            AddCategoryMapping(139, TorznabCatType.PCGames, "Others for Windows-based games");
-            AddCategoryMapping(2478, TorznabCatType.PCGames, " | - Official patches");
-            AddCategoryMapping(2479, TorznabCatType.PCGames, " | - Official Fashion, plug-ins, add-ons");
-            AddCategoryMapping(2480, TorznabCatType.PCGames, " | - Informal fashion, plugins, add-ons");
-            AddCategoryMapping(2481, TorznabCatType.PCGames, " | - Fun");
-            AddCategoryMapping(761, TorznabCatType.PCGames, " | - Editors, emulators and other gaming utility");
-            AddCategoryMapping(2482, TorznabCatType.PCGames, " |- NoCD / NoDVD");
-            AddCategoryMapping(2533, TorznabCatType.PCGames, " | - Conservation games");
-            AddCategoryMapping(2483, TorznabCatType.PCGames, " | - Cheat program and trainers");
-            AddCategoryMapping(2484, TorznabCatType.PCGames, " | - Guides and passing");
-            AddCategoryMapping(2485, TorznabCatType.PCGames, " | - The bonus discs for games");
-            AddCategoryMapping(240, TorznabCatType.PCGames, "video Game");
-            AddCategoryMapping(2415, TorznabCatType.PCGames, " | - Walkthroughs");
-            AddCategoryMapping(2067, TorznabCatType.PCGames, " |- Lineage II Movies");
-            AddCategoryMapping(2147, TorznabCatType.PCGames, " |- World of Warcraft Movies");
-            AddCategoryMapping(960, TorznabCatType.PCGames, " |- Counter Strike Movies");
-            AddCategoryMapping(548, TorznabCatType.Console, "Games for consoles");
-            AddCategoryMapping(129, TorznabCatType.Console, " | - Portable and Console (Games)");
-            AddCategoryMapping(908, TorznabCatType.ConsolePS3, " |- PS");
-            AddCategoryMapping(357, TorznabCatType.ConsolePS3, " |- PS2");
-            AddCategoryMapping(886, TorznabCatType.ConsolePS3, " |- PS3");
-            AddCategoryMapping(1352, TorznabCatType.ConsolePSP, " |- PSP");
-            AddCategoryMapping(1116, TorznabCatType.ConsolePSP, " | - PS1 games for PSP");
-            AddCategoryMapping(973, TorznabCatType.ConsolePSVita, " |- PSVITA");
-            AddCategoryMapping(887, TorznabCatType.ConsoleXbox, " | - Original Xbox");
-            AddCategoryMapping(510, TorznabCatType.ConsoleXbox360, " |- Xbox 360");
-            AddCategoryMapping(773, TorznabCatType.ConsoleWii, " |- Wii");
-            AddCategoryMapping(774, TorznabCatType.ConsoleNDS, " |- NDS");
-            AddCategoryMapping(968, TorznabCatType.ConsoleOther, " |- Dreamcast");
-            AddCategoryMapping(546, TorznabCatType.ConsoleOther, " | - Games for the DVD player");
-            AddCategoryMapping(2185, TorznabCatType.Console, "Video consoles");
-            AddCategoryMapping(2487, TorznabCatType.ConsolePSVita, " | - Video for PSVita");
-            AddCategoryMapping(2182, TorznabCatType.ConsolePSP, " | - Movies for PSP");
-            AddCategoryMapping(2181, TorznabCatType.ConsolePSP, " | - For PSP TV Shows");
-            AddCategoryMapping(2180, TorznabCatType.ConsolePSP, " | - Cartoons for PSP");
-            AddCategoryMapping(2179, TorznabCatType.ConsolePSP, " | - Drama for PSP");
-            AddCategoryMapping(2186, TorznabCatType.ConsolePSP, " | - Anime for PSP");
-            AddCategoryMapping(700, TorznabCatType.ConsolePSP, " | - Video to PSP");
-            AddCategoryMapping(1926, TorznabCatType.ConsolePS3, " | - Videos for the PS3 and other consoles");
-            AddCategoryMapping(899, TorznabCatType.PCGames, "Games for Linux");
-            AddCategoryMapping(1992, TorznabCatType.PCGames, " | - Native games for Linux");
-            AddCategoryMapping(2059, TorznabCatType.PCGames, " | - Game Ported to Linux");
-
-            // Программы и Дизайн
-            AddCategoryMapping(1012, TorznabCatType.PC0day, "Operating systems from Microsoft");
-            AddCategoryMapping(1019, TorznabCatType.PC0day, " | - Desktop operating system from Microsoft (released prior to Windows XP)");
-            AddCategoryMapping(2153, TorznabCatType.PC0day, " | - Desktop operating system from Microsoft (since Windows XP)");
-            AddCategoryMapping(1021, TorznabCatType.PC0day, " | - Server operating system from Microsoft");
-            AddCategoryMapping(1025, TorznabCatType.PC0day, " | - Other (Operating Systems from Microsoft)");
-            AddCategoryMapping(1376, TorznabCatType.PC0day, "Linux, Unix and other operating systems");
-            AddCategoryMapping(1379, TorznabCatType.PC0day, " | - Operating Systems (Linux, Unix)");
-            AddCategoryMapping(1381, TorznabCatType.PC0day, " | - Software (Linux, Unix)");
-            AddCategoryMapping(1473, TorznabCatType.PC0day, " | - Other operating systems and software for them");
-            AddCategoryMapping(1195, TorznabCatType.PC0day, "Test drives to adjust the audio / video equipment");
-            AddCategoryMapping(1013, TorznabCatType.PC0day, "System programs");
-            AddCategoryMapping(1028, TorznabCatType.PC0day, " | - Work with hard drive");
-            AddCategoryMapping(1029, TorznabCatType.PC0day, " | - Backup");
-            AddCategoryMapping(1030, TorznabCatType.PC0day, " | - Archivers and File Managers");
-            AddCategoryMapping(1031, TorznabCatType.PC0day, " | - Software to configure and optimize the operating system");
-            AddCategoryMapping(1032, TorznabCatType.PC0day, " | - Service computer service");
-            AddCategoryMapping(1033, TorznabCatType.PC0day, " | - Work with data carriers");
-            AddCategoryMapping(1034, TorznabCatType.PC0day, " | - Information and Diagnostics");
-            AddCategoryMapping(1066, TorznabCatType.PC0day, " | - Software for Internet and networks");
-            AddCategoryMapping(1035, TorznabCatType.PC0day, " | - Software to protect your computer (antivirus software, firewalls)");
-            AddCategoryMapping(1038, TorznabCatType.PC0day, " | - Anti-spyware and anti-trojan");
-            AddCategoryMapping(1039, TorznabCatType.PC0day, " | - Software to protect information");
-            AddCategoryMapping(1536, TorznabCatType.PC0day, " | - Drivers and Firmware");
-            AddCategoryMapping(1051, TorznabCatType.PC0day, " | - The original disks to computers and accessories");
-            AddCategoryMapping(1040, TorznabCatType.PC0day, " | - Server software for Windows");
-            AddCategoryMapping(1041, TorznabCatType.PC0day, " | - Change the Windows interface");
-            AddCategoryMapping(1636, TorznabCatType.PC0day, " | - Screensavers");
-            AddCategoryMapping(1042, TorznabCatType.PC0day, " | - Other (System programs on Windows)");
-            AddCategoryMapping(1014, TorznabCatType.PC0day, "Systems for business, office, research and project work");
-            AddCategoryMapping(1060, TorznabCatType.PC0day, " | - Everything for the home: dressmaking, sewing, cooking");
-            AddCategoryMapping(1061, TorznabCatType.PC0day, " | - Office Systems");
-            AddCategoryMapping(1062, TorznabCatType.PC0day, " | - Business Systems");
-            AddCategoryMapping(1067, TorznabCatType.PC0day, " | - Recognition of text, sound and speech synthesis");
-            AddCategoryMapping(1086, TorznabCatType.PC0day, " | - Work with PDF and DjVu");
-            AddCategoryMapping(1068, TorznabCatType.PC0day, " | - Dictionaries, translators");
-            AddCategoryMapping(1063, TorznabCatType.PC0day, " | - System for scientific work");
-            AddCategoryMapping(1087, TorznabCatType.PC0day, " | - CAD (general and engineering)");
-            AddCategoryMapping(1192, TorznabCatType.PC0day, " | - CAD (electronics, automation, GAP)");
-            AddCategoryMapping(1088, TorznabCatType.PC0day, " | - Software for architects and builders");
-            AddCategoryMapping(1193, TorznabCatType.PC0day, " | - Library and projects for architects and designers inter ..");
-            AddCategoryMapping(1071, TorznabCatType.PC0day, " | - Other reference systems");
-            AddCategoryMapping(1073, TorznabCatType.PC0day, " | - Miscellaneous (business systems, office, research and design ..");
-            AddCategoryMapping(1052, TorznabCatType.PC0day, "Web Development and Programming");
-            AddCategoryMapping(1053, TorznabCatType.PC0day, " | - WYSIWYG editors for web diz");
-            AddCategoryMapping(1054, TorznabCatType.PC0day, " | - Text editors Illuminated");
-            AddCategoryMapping(1055, TorznabCatType.PC0day, " | - Programming environments, compilers and support, etc. ..");
-            AddCategoryMapping(1056, TorznabCatType.PC0day, " | - Components for programming environments");
-            AddCategoryMapping(2077, TorznabCatType.PC0day, " | - Database Management Systems");
-            AddCategoryMapping(1057, TorznabCatType.PC0day, " | - Scripts and engines sites, CMS and extensions to it");
-            AddCategoryMapping(1018, TorznabCatType.PC0day, " | - Templates for websites and CMS");
-            AddCategoryMapping(1058, TorznabCatType.PC0day, " | - Miscellaneous (Web Development and Programming)");
-            AddCategoryMapping(1016, TorznabCatType.PC0day, "Programs to work with multimedia and 3D");
-            AddCategoryMapping(1079, TorznabCatType.PC0day, " | - Software Kits");
-            AddCategoryMapping(1080, TorznabCatType.PC0day, " | - Plug-ins for Adobe's programs");
-            AddCategoryMapping(1081, TorznabCatType.PC0day, " | - Graphic Editors");
-            AddCategoryMapping(1082, TorznabCatType.PC0day, " | - Software for typesetting, printing, and working with fonts");
-            AddCategoryMapping(1083, TorznabCatType.PC0day, " | - 3D modeling, rendering and plugins for them");
-            AddCategoryMapping(1084, TorznabCatType.PC0day, " | - Animation");
-            AddCategoryMapping(1085, TorznabCatType.PC0day, " | - Creating a BD / HD / DVD-Video");
-            AddCategoryMapping(1089, TorznabCatType.PC0day, " | - Video Editors");
-            AddCategoryMapping(1090, TorznabCatType.PC0day, " | - Video converters Audio");
-            AddCategoryMapping(1065, TorznabCatType.PC0day, " | - Audio and video, CD- players and catalogers");
-            AddCategoryMapping(1064, TorznabCatType.PC0day, " | - Cataloging and graphics viewers");
-            AddCategoryMapping(1092, TorznabCatType.PC0day, " | - Miscellaneous (Programme for multimedia and 3D)");
-            AddCategoryMapping(1204, TorznabCatType.PC0day, " | - Virtual Studios, sequencers and audio editor");
-            AddCategoryMapping(1027, TorznabCatType.PC0day, " | - Virtual Instruments & Synthesizers");
-            AddCategoryMapping(1199, TorznabCatType.PC0day, " | - Plug-ins for sound processing");
-            AddCategoryMapping(1091, TorznabCatType.PC0day, " | - Miscellaneous (Programs for working with audio)");
-            AddCategoryMapping(828, TorznabCatType.PC0day, "Materials for Multimedia and Design");
-            AddCategoryMapping(1357, TorznabCatType.PC0day, " | - Authoring");
-            AddCategoryMapping(890, TorznabCatType.PC0day, " | - Official compilations vector clipart");
-            AddCategoryMapping(830, TorznabCatType.PC0day, " | - Other vector cliparts");
-            AddCategoryMapping(1290, TorznabCatType.PC0day, " |- Photostoсks");
-            AddCategoryMapping(1962, TorznabCatType.PC0day, " | - Photoshop Costumes");
-            AddCategoryMapping(831, TorznabCatType.PC0day, " | - Frames and Vignettes for processing photos");
-            AddCategoryMapping(829, TorznabCatType.PC0day, " | - Other raster clipart");
-            AddCategoryMapping(633, TorznabCatType.PC0day, " | - 3D models, scenes and materials");
-            AddCategoryMapping(1009, TorznabCatType.PC0day, " | - Footage");
-            AddCategoryMapping(1963, TorznabCatType.PC0day, " | - Other collections footage");
-            AddCategoryMapping(1954, TorznabCatType.PC0day, " | - Music Library");
-            AddCategoryMapping(1010, TorznabCatType.PC0day, " | - Sound Effects");
-            AddCategoryMapping(1674, TorznabCatType.PC0day, " | - Sample Libraries");
-            AddCategoryMapping(2421, TorznabCatType.PC0day, " | - Library and saundbanki for samplers, presets for sy ..");
-            AddCategoryMapping(2492, TorznabCatType.PC0day, " |- Multitracks");
-            AddCategoryMapping(839, TorznabCatType.PC0day, " | - Materials for creating menus and DVD covers");
-            AddCategoryMapping(1679, TorznabCatType.PC0day, " | - Styles, brushes, shapes and patterns for Adobe Photoshop");
-            AddCategoryMapping(1011, TorznabCatType.PC0day, " | - Fonts");
-            AddCategoryMapping(835, TorznabCatType.PC0day, " | - Miscellaneous (Materials for Multimedia and Design)");
-            AddCategoryMapping(1503, TorznabCatType.PC0day, "GIS, navigation systems and maps");
-            AddCategoryMapping(1507, TorznabCatType.PC0day, " | - GIS (Geoinformatsionnыe sistemы)");
-            AddCategoryMapping(1526, TorznabCatType.PC0day, " | - Maps provided with the program shell");
-            AddCategoryMapping(1508, TorznabCatType.PC0day, " | - Atlases and maps modern (after 1950)");
-            AddCategoryMapping(1509, TorznabCatType.PC0day, " | - Atlases and antique maps (up to 1950)");
-            AddCategoryMapping(1510, TorznabCatType.PC0day, " | - Other Maps (astronomical, historical, topically ..");
-            AddCategoryMapping(1511, TorznabCatType.PC0day, " | - Built-in car navigation");
-            AddCategoryMapping(1512, TorznabCatType.PC0day, " |- Garmin");
-            AddCategoryMapping(1513, TorznabCatType.PC0day, " | -");
-            AddCategoryMapping(1514, TorznabCatType.PC0day, " |- TomTom");
-            AddCategoryMapping(1515, TorznabCatType.PC0day, " |- Navigon / Navitel");
-            AddCategoryMapping(1516, TorznabCatType.PC0day, " |- Igo");
-            AddCategoryMapping(1517, TorznabCatType.PC0day, " | - Miscellaneous - navigation and maps");
-
-            // Мобильные устройства
-            AddCategoryMapping(285, TorznabCatType.PCPhoneOther, "Games, applications and so on. Mobile");
-            AddCategoryMapping(2149, TorznabCatType.PCPhoneAndroid, " | - Games for Android OS");
-            AddCategoryMapping(2154, TorznabCatType.PCPhoneAndroid, " | - Applications for Android OS");
-            AddCategoryMapping(2419, TorznabCatType.PCPhoneOther, " | - Applications for Windows Phone 7,8");
-            AddCategoryMapping(2420, TorznabCatType.PCPhoneOther, " | - Games for Windows Phone 7,8");
-            AddCategoryMapping(1004, TorznabCatType.PCPhoneOther, " | - Games for Symbian");
-            AddCategoryMapping(289, TorznabCatType.PCPhoneOther, " | - Applications for Symbian");
-            AddCategoryMapping(1001, TorznabCatType.PCPhoneOther, " | - Games for Java");
-            AddCategoryMapping(1005, TorznabCatType.PCPhoneOther, " | - Applications for Java");
-            AddCategoryMapping(1002, TorznabCatType.PCPhoneOther, " | - Games for Windows Mobile, Palm OS, BlackBerry and so on.");
-            AddCategoryMapping(290, TorznabCatType.PCPhoneOther, " | - Applications for Windows Mobile, Palm OS, BlackBerry and so on.");
-            AddCategoryMapping(288, TorznabCatType.PCPhoneOther, " | - Software for your phone");
-            AddCategoryMapping(292, TorznabCatType.PCPhoneOther, " | - Firmware for phones");
-            AddCategoryMapping(291, TorznabCatType.PCPhoneOther, " | - Wallpapers and Themes");
-            AddCategoryMapping(957, TorznabCatType.PCPhoneOther, "Video for mobile devices");
-            AddCategoryMapping(287, TorznabCatType.PCPhoneOther, " | - Video for Smartphones and PDAs");
-            AddCategoryMapping(286, TorznabCatType.PCPhoneOther, " | - Mobile Video (3GP)");
-
-            // Apple
-            AddCategoryMapping(1366, TorznabCatType.PCMac, "Apple Macintosh");
-            AddCategoryMapping(1368, TorznabCatType.PCMac, " |- Mac OS (для Macintosh)");
-            AddCategoryMapping(1383, TorznabCatType.PCMac, " | - Mac OS (for RS-Hakintoš)");
-            AddCategoryMapping(537, TorznabCatType.PCMac, " | - Game Mac OS");
-            AddCategoryMapping(1394, TorznabCatType.PCMac, " | - Software for viewing and video processing");
-            AddCategoryMapping(1370, TorznabCatType.PCMac, " | - Software to build and graphics processing");
-            AddCategoryMapping(2237, TorznabCatType.PCMac, " | - Plug-ins for Adobe's programs");
-            AddCategoryMapping(1372, TorznabCatType.PCMac, " | - Audio editor and converter");
-            AddCategoryMapping(1373, TorznabCatType.PCMac, " | - System software");
-            AddCategoryMapping(1375, TorznabCatType.PCMac, " | - Office software");
-            AddCategoryMapping(1371, TorznabCatType.PCMac, " | - Software for the Internet and network");
-            AddCategoryMapping(1374, TorznabCatType.PCMac, " | - Other software");
-            AddCategoryMapping(1933, TorznabCatType.PCMac, "iOS");
-            AddCategoryMapping(1935, TorznabCatType.PCMac, " | - Software for iOS");
-            AddCategoryMapping(1003, TorznabCatType.PCMac, " | - Games for iOS");
-            AddCategoryMapping(1937, TorznabCatType.PCMac, " | - Miscellaneous for iOS");
-            AddCategoryMapping(2235, TorznabCatType.PCMac, "Video");
-            AddCategoryMapping(1908, TorznabCatType.PCMac, " | - Movies for iPod, iPhone, iPad");
-            AddCategoryMapping(864, TorznabCatType.PCMac, " | - TV Shows for iPod, iPhone, iPad");
-            AddCategoryMapping(863, TorznabCatType.PCMac, " | - Cartoons for iPod, iPhone, iPad");
-            AddCategoryMapping(2535, TorznabCatType.PCMac, " | - Anime for iPod, iPhone, iPad");
-            AddCategoryMapping(2534, TorznabCatType.PCMac, " | - The music video to iPod, iPhone, iPad");
-            AddCategoryMapping(2238, TorznabCatType.PCMac, "Видео HD");
-            AddCategoryMapping(1936, TorznabCatType.PCMac, " | - HD Movies to Apple TV");
-            AddCategoryMapping(315, TorznabCatType.PCMac, " | - HD TV Shows on Apple TV");
-            AddCategoryMapping(1363, TorznabCatType.PCMac, " | - HD Animation for Apple TV");
-            AddCategoryMapping(2082, TorznabCatType.PCMac, " | - Documentary HD video for Apple TV");
-            AddCategoryMapping(2241, TorznabCatType.PCMac, " | - Musical HD video for Apple TV");
-            AddCategoryMapping(2236, TorznabCatType.PCMac, "audio");
-            AddCategoryMapping(1909, TorznabCatType.PCMac, " | - Audiobooks (AAC, ALAC)");
-            AddCategoryMapping(1927, TorznabCatType.PCMac, " | - Music Lossless (ALAC)");
-            AddCategoryMapping(2240, TorznabCatType.PCMac, " |- Музыка Lossy (AAC-iTunes)");
-            AddCategoryMapping(2248, TorznabCatType.PCMac, " |- Музыка Lossy (AAC)");
-            AddCategoryMapping(2244, TorznabCatType.PCMac, " |- Музыка Lossy (AAC) (Singles, EPs)");
-            AddCategoryMapping(2243, TorznabCatType.PCMac, "F.A.Q.");
-
-            // Медицина и здоровье
-            AddCategoryMapping(2125, TorznabCatType.Books, "Books, magazines and programs");
-            AddCategoryMapping(2133, TorznabCatType.Books, " | - Clinical Medicine until 1980");
-            AddCategoryMapping(2130, TorznabCatType.Books, " | - Clinical Medicine from 1980 to 2000");
-            AddCategoryMapping(2313, TorznabCatType.Books, " | - Clinical Medicine since 2000");
-            AddCategoryMapping(2314, TorznabCatType.Books, " | - Popular medical periodicals (newspapers and magazines)");
-            AddCategoryMapping(2528, TorznabCatType.Books, " | - Scientific medical periodicals (newspapers and magazines)");
-            AddCategoryMapping(2129, TorznabCatType.Books, " | - Life Sciences");
-            AddCategoryMapping(2141, TorznabCatType.Books, " | - Pharmacy and Pharmacology");
-            AddCategoryMapping(2132, TorznabCatType.Books, " | - Non-traditional, traditional medicine and popular books on the s ..");
-            AddCategoryMapping(2131, TorznabCatType.Books, " | - Veterinary Medicine, Miscellaneous");
-            AddCategoryMapping(2315, TorznabCatType.Books, " | - Thematic collection of books");
-            AddCategoryMapping(1350, TorznabCatType.Books, " | - Audio Books on medicine");
-            AddCategoryMapping(2134, TorznabCatType.Books, " | - Medical software");
-            AddCategoryMapping(2126, TorznabCatType.Books, "Tutorials, Doc. movies and TV shows on medicine");
-            AddCategoryMapping(2135, TorznabCatType.Books, " | - Medicine and Dentistry");
-            AddCategoryMapping(2140, TorznabCatType.Books, " | - Psychotherapy and clinical psychology");
-            AddCategoryMapping(2136, TorznabCatType.Books, " | - Massage");
-            AddCategoryMapping(2138, TorznabCatType.Books, " | - Health");
-            AddCategoryMapping(2139, TorznabCatType.Books, " | - Documentary movies and TV shows on medicine");
-
-            // Разное
-            AddCategoryMapping(10, TorznabCatType.Other, "Miscellaneous");
-            AddCategoryMapping(865, TorznabCatType.Other, " | - Psihoaktivnye audioprogrammy");
-            AddCategoryMapping(1100, TorznabCatType.Other, " | - Avatars, Icons, Smileys");
-            AddCategoryMapping(1643, TorznabCatType.Other, " | - Painting, Graphics, Sculpture, Digital Art");
-            AddCategoryMapping(848, TorznabCatType.Other, " | - Pictures");
-            AddCategoryMapping(808, TorznabCatType.Other, " | - Amateur Photos");
-            AddCategoryMapping(630, TorznabCatType.Other, " | - Wallpapers");
-            AddCategoryMapping(1664, TorznabCatType.Other, " | - Celebrity Photos");
-            AddCategoryMapping(148, TorznabCatType.Other, " | - Audio");
-            AddCategoryMapping(807, TorznabCatType.Other, " | - Video");
-            AddCategoryMapping(147, TorznabCatType.Other, " | - Publications and educational materials (texts)");
-            AddCategoryMapping(847, TorznabCatType.Other, " | - Trailers and additional materials for films");
+            Language = "ru-ru";
+            Type = "semi-private";
+
+            // Новости
+            AddCategoryMapping(2317, TorznabCatType.Other, "NEW YEAR'S SECTION");
+            AddCategoryMapping(1241, TorznabCatType.Other, " | - New competitions");
+            AddCategoryMapping(2338, TorznabCatType.TV, " | - Entertainment shows and Documentaries");
+            AddCategoryMapping(1464, TorznabCatType.Movies, " | - Movies and Cartoons");
+            AddCategoryMapping(860, TorznabCatType.Books, " | - Books, Journals, Notes");
+            AddCategoryMapping(1340, TorznabCatType.Audio, " | - Music");
+            AddCategoryMapping(1346, TorznabCatType.AudioVideo, " | - Music video");
+            AddCategoryMapping(1239, TorznabCatType.Console, " | - Games");
+            AddCategoryMapping(1299, TorznabCatType.Other, " | - Miscellaneous (postcards, wallpapers, video, etc.).");
+            AddCategoryMapping(1289, TorznabCatType.Other, "Rutracker Awards (events and competitions)");
+            AddCategoryMapping(1579, TorznabCatType.Other, "| - Photo club. The whole world is in the palm of your hand.");
+            AddCategoryMapping(2214, TorznabCatType.Other, " | - Rutracker Awards (distribution)");
+
+            // Кино, Видео и ТВ
+            AddCategoryMapping(7, TorznabCatType.MoviesForeign, "Foreign movies");
+            AddCategoryMapping(187, TorznabCatType.MoviesForeign, " | - Classic of world cinema");
+            AddCategoryMapping(2090, TorznabCatType.MoviesForeign, " | - Movies before 1990");
+            AddCategoryMapping(2221, TorznabCatType.MoviesForeign, " | - Movies 1991-2000");
+            AddCategoryMapping(2091, TorznabCatType.MoviesForeign, " | - Movies 2001-2005");
+            AddCategoryMapping(2092, TorznabCatType.MoviesForeign, " | - Movies 2006-2010");
+            AddCategoryMapping(2093, TorznabCatType.MoviesForeign, " | - Movies 2011-2015");
+            AddCategoryMapping(2200, TorznabCatType.MoviesForeign, " | - Movies 2016");
+            AddCategoryMapping(934, TorznabCatType.MoviesForeign, " | - Asian movies");
+            AddCategoryMapping(505, TorznabCatType.MoviesForeign, " | - Indian Cinema");
+            AddCategoryMapping(212, TorznabCatType.MoviesForeign, " | - Movie Collections");
+            AddCategoryMapping(2459, TorznabCatType.MoviesForeign, " | - Shorts");
+            AddCategoryMapping(1235, TorznabCatType.MoviesForeign, " | - Grindhouse");
+            AddCategoryMapping(185, TorznabCatType.MoviesForeign, " | - Soundtracks and Translations");
+            AddCategoryMapping(22, TorznabCatType.Movies, "our film");
+            AddCategoryMapping(941, TorznabCatType.Movies, " | - Cinema of the USSR");
+            AddCategoryMapping(1666, TorznabCatType.Movies, " | - Children's domestic films");
+            AddCategoryMapping(376, TorznabCatType.Movies, " | - Author Debuts");
+            AddCategoryMapping(124, TorznabCatType.Movies, "Art-house cinema and author");
+            AddCategoryMapping(1543, TorznabCatType.Movies, " | - Shorts (Art-house cinema and author)");
+            AddCategoryMapping(709, TorznabCatType.Movies, " | - Documentaries (Art-house cinema and author)");
+            AddCategoryMapping(1577, TorznabCatType.Movies, " | - Animation (Art-house cinema and author)");
+            AddCategoryMapping(511, TorznabCatType.Movies, "Theater");
+            AddCategoryMapping(656, TorznabCatType.Movies, "| - Benefit. Master of Arts domestic theater and cinema");
+            AddCategoryMapping(93, TorznabCatType.Movies, "DVD Video");
+            AddCategoryMapping(905, TorznabCatType.Movies, " | - Classic of world cinema (DVD Video)");
+            AddCategoryMapping(1576, TorznabCatType.Movies, " | - Asian movies (DVD Video)");
+            AddCategoryMapping(101, TorznabCatType.Movies, " | - Foreign movies (DVD)");
+            AddCategoryMapping(100, TorznabCatType.Movies, " | - Our cinema (DVD)");
+            AddCategoryMapping(572, TorznabCatType.Movies, " | - Art-house and auteur cinema (DVD)");
+            AddCategoryMapping(2220, TorznabCatType.Movies, " | - Indian Cinema DVD and HD Video");
+            AddCategoryMapping(1670, TorznabCatType.Movies, " |- Грайндхаус DVD и HD Video");
+            AddCategoryMapping(2198, TorznabCatType.MoviesHD, "HD Video");
+            AddCategoryMapping(2199, TorznabCatType.MoviesHD, " | - Classic of world cinema (HD Video)");
+            AddCategoryMapping(313, TorznabCatType.MoviesHD, " | - Foreign movies (HD Video)");
+            AddCategoryMapping(2201, TorznabCatType.MoviesHD, " | - Asian movies (HD Video)");
+            AddCategoryMapping(312, TorznabCatType.MoviesHD, " | - Our cinema (HD Video)");
+            AddCategoryMapping(2339, TorznabCatType.MoviesHD, " | - Art-house and auteur cinema (HD Video)");
+            AddCategoryMapping(352, TorznabCatType.Movies3D, "3D / Stereo Film, Video, TV & Sports");
+            AddCategoryMapping(549, TorznabCatType.Movies3D, " | - 3D Movies");
+            AddCategoryMapping(1213, TorznabCatType.Movies3D, " | - 3D Animation");
+            AddCategoryMapping(2109, TorznabCatType.Movies3D, " | - 3D Documentary");
+            AddCategoryMapping(514, TorznabCatType.Movies3D, " | - 3D Спорт");
+            AddCategoryMapping(2097, TorznabCatType.Movies3D, " | - 3D Clips, Music Videos, Movie Trailers");
+            AddCategoryMapping(4, TorznabCatType.Movies, "Cartoons");
+            AddCategoryMapping(2343, TorznabCatType.Movies, " | - Animation (Announcements HD Video)");
+            AddCategoryMapping(930, TorznabCatType.Movies, " | - Animation (HD Video)");
+            AddCategoryMapping(2365, TorznabCatType.Movies, " | - Short Film (HD Video)");
+            AddCategoryMapping(1900, TorznabCatType.Movies, " | - Domestic cartoons (DVD)");
+            AddCategoryMapping(521, TorznabCatType.Movies, " | - Foreign cartoons (DVD)");
+            AddCategoryMapping(2258, TorznabCatType.Movies, " | - Foreign Short Film (DVD)");
+            AddCategoryMapping(208, TorznabCatType.Movies, " | - Domestic cartoons");
+            AddCategoryMapping(539, TorznabCatType.Movies, " | - Domestic full-length cartoons");
+            AddCategoryMapping(209, TorznabCatType.Movies, " | - Foreign cartoons");
+            AddCategoryMapping(484, TorznabCatType.Movies, " | - Foreign short cartoons");
+            AddCategoryMapping(822, TorznabCatType.Movies, " | - Cartoon Collection");
+            AddCategoryMapping(921, TorznabCatType.TV, "Serial cartoons");
+            AddCategoryMapping(922, TorznabCatType.TV, " | - Avatar");
+            AddCategoryMapping(1247, TorznabCatType.TV, " | - Griffiny / Family guy");
+            AddCategoryMapping(923, TorznabCatType.TV, " | - SpongeBob SquarePants");
+            AddCategoryMapping(924, TorznabCatType.TV, " | - The Simpsons");
+            AddCategoryMapping(1991, TorznabCatType.TV, " | - Skubi-du / Scooby-Doo");
+            AddCategoryMapping(925, TorznabCatType.TV, " | - Tom and Jerry");
+            AddCategoryMapping(1165, TorznabCatType.TV, " | - Transformers");
+            AddCategoryMapping(1245, TorznabCatType.TV, " | - DuckTales / DuckTales");
+            AddCategoryMapping(928, TorznabCatType.TV, " | - Futurama / Futurama");
+            AddCategoryMapping(926, TorznabCatType.TV, " | - Spider-Man / The Spectacular Spider-Man");
+            AddCategoryMapping(1246, TorznabCatType.TV, " | - Turtles Mutant Ninja / Teenage Mutant Ninja Turtles");
+            AddCategoryMapping(1250, TorznabCatType.TV, " |- Чип и Дейл / Chip And Dale");
+            AddCategoryMapping(927, TorznabCatType.TV, " | - South Park / South Park");
+            AddCategoryMapping(1248, TorznabCatType.TV, " | - For sub-standard hands");
+            AddCategoryMapping(33, TorznabCatType.TVAnime, "Anime");
+            AddCategoryMapping(281, TorznabCatType.TVAnime, " | - Manga");
+            AddCategoryMapping(1386, TorznabCatType.TVAnime, " | - Wallpapers, artbook, and others.");
+            AddCategoryMapping(1387, TorznabCatType.TVAnime, " | -. AMV and other rollers");
+            AddCategoryMapping(1388, TorznabCatType.TVAnime, " |- OST (lossless)");
+            AddCategoryMapping(282, TorznabCatType.TVAnime, " | - OST (mp3 and others lossy-format)");
+            AddCategoryMapping(599, TorznabCatType.TVAnime, " | - Anime (DVD)");
+            AddCategoryMapping(1105, TorznabCatType.TVAnime, " |- Аниме (HD Video)");
+            AddCategoryMapping(1389, TorznabCatType.TVAnime, " | - Anime (main subsection)");
+            AddCategoryMapping(1391, TorznabCatType.TVAnime, " | - Anime (pleerny subsection)");
+            AddCategoryMapping(2491, TorznabCatType.TVAnime, " | - Anime (QC subsection)");
+            AddCategoryMapping(404, TorznabCatType.TVAnime, " | - Pokemony");
+            AddCategoryMapping(1390, TorznabCatType.TVAnime, " | - Naruto");
+            AddCategoryMapping(1642, TorznabCatType.TVAnime, " | - Trade");
+            AddCategoryMapping(893, TorznabCatType.TVAnime, " | - Japanese cartoons");
+            AddCategoryMapping(1478, TorznabCatType.TVAnime, " | - For sub-standard hands");
+
+            // Документалистика и юмор
+            AddCategoryMapping(670, TorznabCatType.TVDocumentary, "Faith and Religion");
+            AddCategoryMapping(1475, TorznabCatType.TVDocumentary, " | - Christianity");
+            AddCategoryMapping(2107, TorznabCatType.TVDocumentary, " | - Islam");
+            AddCategoryMapping(294, TorznabCatType.TVDocumentary, " | - Religions of India, Tibet and East Asia");
+            AddCategoryMapping(1453, TorznabCatType.TVDocumentary, " | - Cults and new religious movements");
+            AddCategoryMapping(46, TorznabCatType.TVDocumentary, "Documentary movies and TV shows");
+            AddCategoryMapping(103, TorznabCatType.TVDocumentary, " | - Documentary (DVD)");
+            AddCategoryMapping(671, TorznabCatType.TVDocumentary, "| - Biographies. Personality and idols");
+            AddCategoryMapping(2177, TorznabCatType.TVDocumentary, " | - Cinema and animation");
+            AddCategoryMapping(2538, TorznabCatType.TVDocumentary, " | - Art, Art History");
+            AddCategoryMapping(2159, TorznabCatType.TVDocumentary, " | - Music");
+            AddCategoryMapping(251, TorznabCatType.TVDocumentary, " | - Kriminalynaya documentary");
+            AddCategoryMapping(98, TorznabCatType.TVDocumentary, " | - Secrets of the Ages / Special Services / Conspiracy Theory");
+            AddCategoryMapping(97, TorznabCatType.TVDocumentary, " | - Military");
+            AddCategoryMapping(851, TorznabCatType.TVDocumentary, " | - World War II");
+            AddCategoryMapping(2178, TorznabCatType.TVDocumentary, " | - Accidents / Accidents / Disasters");
+            AddCategoryMapping(821, TorznabCatType.TVDocumentary, " | - Aviation");
+            AddCategoryMapping(2076, TorznabCatType.TVDocumentary, " | - Space");
+            AddCategoryMapping(56, TorznabCatType.TVDocumentary, " | - Scientific-popular movies");
+            AddCategoryMapping(2123, TorznabCatType.TVDocumentary, " | - Flora and fauna");
+            AddCategoryMapping(876, TorznabCatType.TVDocumentary, " | - Travel and Tourism");
+            AddCategoryMapping(2380, TorznabCatType.TVDocumentary, " | - Social talk show");
+            AddCategoryMapping(1467, TorznabCatType.TVDocumentary, " | - Information-analytical and socio-political etc. ..");
+            AddCategoryMapping(1469, TorznabCatType.TVDocumentary, " | - Architecture and Construction");
+            AddCategoryMapping(672, TorznabCatType.TVDocumentary, " | - All about home, life and design");
+            AddCategoryMapping(249, TorznabCatType.TVDocumentary, " |- BBC");
+            AddCategoryMapping(552, TorznabCatType.TVDocumentary, " |- Discovery");
+            AddCategoryMapping(500, TorznabCatType.TVDocumentary, " |- National Geographic");
+            AddCategoryMapping(2112, TorznabCatType.TVDocumentary, " | - History: Ancient World / Antiquity / Middle Ages");
+            AddCategoryMapping(1327, TorznabCatType.TVDocumentary, " | - History: modern and contemporary times");
+            AddCategoryMapping(1468, TorznabCatType.TVDocumentary, " | - The Age of the USSR");
+            AddCategoryMapping(1280, TorznabCatType.TVDocumentary, " | - The Battle of psychics / Theory improbability / Seekers / G ..");
+            AddCategoryMapping(752, TorznabCatType.TVDocumentary, " | - Russian sensation / Program Maximum / Profession report ..");
+            AddCategoryMapping(1114, TorznabCatType.TVDocumentary, " | - Paranormal");
+            AddCategoryMapping(2168, TorznabCatType.TVDocumentary, " | - Alternative history and science");
+            AddCategoryMapping(2160, TorznabCatType.TVDocumentary, " | - Vnezhanrovaya documentary");
+            AddCategoryMapping(2176, TorznabCatType.TVDocumentary, " | - Other / nekonditsiya");
+            AddCategoryMapping(314, TorznabCatType.TVDocumentary, "Documentary (HD Video)");
+            AddCategoryMapping(2323, TorznabCatType.TVDocumentary, " | - Information-analytical and socio-political etc. ..");
+            AddCategoryMapping(1278, TorznabCatType.TVDocumentary, "| - Biographies. Personality and idols (HD Video)");
+            AddCategoryMapping(1281, TorznabCatType.TVDocumentary, " | - Military Science (HD Video)");
+            AddCategoryMapping(2110, TorznabCatType.TVDocumentary, " | - Natural History, Science and Technology (HD Video)");
+            AddCategoryMapping(979, TorznabCatType.TVDocumentary, " | - Travel and Tourism (HD Video)");
+            AddCategoryMapping(2169, TorznabCatType.TVDocumentary, " |- Флора и фауна (HD Video)");
+            AddCategoryMapping(2166, TorznabCatType.TVDocumentary, " | - History (HD Video)");
+            AddCategoryMapping(2164, TorznabCatType.TVDocumentary, " |- BBC, Discovery, National Geographic (HD Video)");
+            AddCategoryMapping(2163, TorznabCatType.TVDocumentary, " | - Kriminalynaya documentary (HD Video)");
+            AddCategoryMapping(24, TorznabCatType.TV, "Entertaining TV programs and shows, fun and humor");
+            AddCategoryMapping(1959, TorznabCatType.TV, " | - Mind games and quizzes");
+            AddCategoryMapping(939, TorznabCatType.TV, " | - Reality and talk show host / category / impressions");
+            AddCategoryMapping(1481, TorznabCatType.TV, " | - Children's TV Show");
+            AddCategoryMapping(113, TorznabCatType.TV, " | - KVN");
+            AddCategoryMapping(115, TorznabCatType.TV, " | - Post KVN");
+            AddCategoryMapping(882, TorznabCatType.TV, " | - Distorting Mirror / town / in the town");
+            AddCategoryMapping(1482, TorznabCatType.TV, " | - Ice show");
+            AddCategoryMapping(393, TorznabCatType.TV, " | - Musical Show");
+            AddCategoryMapping(1569, TorznabCatType.TV, " | - Dinner Party");
+            AddCategoryMapping(373, TorznabCatType.TV, " | - Good Jokes");
+            AddCategoryMapping(1186, TorznabCatType.TV, " | - Evening Quarter");
+            AddCategoryMapping(137, TorznabCatType.TV, " | - Movies with a funny transfer (parody)");
+            AddCategoryMapping(2537, TorznabCatType.TV, " |- Stand-up comedy");
+            AddCategoryMapping(532, TorznabCatType.TV, " | - Ukrainian Shows");
+            AddCategoryMapping(827, TorznabCatType.TV, " | - Dance shows, concerts, performances");
+            AddCategoryMapping(1484, TorznabCatType.TV, " | - The Circus");
+            AddCategoryMapping(1485, TorznabCatType.TV, " | - The School for Scandal");
+            AddCategoryMapping(114, TorznabCatType.TV, " | - Satirist, and humorists");
+            AddCategoryMapping(1332, TorznabCatType.TV, " | - Humorous Audio Transmissions");
+            AddCategoryMapping(1495, TorznabCatType.TV, " | - Audio and video clips (Jokes and humor)");
+
+            // Спорт
+            AddCategoryMapping(255, TorznabCatType.TVSport, "Sports tournaments, films and programs");
+            AddCategoryMapping(256, TorznabCatType.TVSport, " | - Motorsports");
+            AddCategoryMapping(1986, TorznabCatType.TVSport, " | - Motorsports");
+            AddCategoryMapping(660, TorznabCatType.TVSport, " | - Formula-1 2016");
+            AddCategoryMapping(1551, TorznabCatType.TVSport, " | - Formula-1 2012-2015");
+            AddCategoryMapping(626, TorznabCatType.TVSport, " | - Formula 1");
+            AddCategoryMapping(262, TorznabCatType.TVSport, " | - Cycling");
+            AddCategoryMapping(1326, TorznabCatType.TVSport, " | - Volleyball / Handball");
+            AddCategoryMapping(978, TorznabCatType.TVSport, " | - Billiards");
+            AddCategoryMapping(1287, TorznabCatType.TVSport, " | - Poker");
+            AddCategoryMapping(1188, TorznabCatType.TVSport, " | - Bodybuilding / Power Sports");
+            AddCategoryMapping(1667, TorznabCatType.TVSport, " | - Boxing");
+            AddCategoryMapping(1675, TorznabCatType.TVSport, " | - Classical arts");
+            AddCategoryMapping(257, TorznabCatType.TVSport, " | - MMA and K-1");
+            AddCategoryMapping(875, TorznabCatType.TVSport, " | - College Football");
+            AddCategoryMapping(263, TorznabCatType.TVSport, " | - Rugby");
+            AddCategoryMapping(2073, TorznabCatType.TVSport, " | - Baseball");
+            AddCategoryMapping(550, TorznabCatType.TVSport, " | - Tennis");
+            AddCategoryMapping(2124, TorznabCatType.TVSport, " | - Badminton / Table Tennis");
+            AddCategoryMapping(1470, TorznabCatType.TVSport, " | - Gymnastics / Dance Competitions");
+            AddCategoryMapping(528, TorznabCatType.TVSport, " | - Athletics / Water Sports");
+            AddCategoryMapping(486, TorznabCatType.TVSport, " | - Winter Sports");
+            AddCategoryMapping(854, TorznabCatType.TVSport, " | - Figure skating");
+            AddCategoryMapping(2079, TorznabCatType.TVSport, " | - Biathlon");
+            AddCategoryMapping(260, TorznabCatType.TVSport, " | - Extreme");
+            AddCategoryMapping(1319, TorznabCatType.TVSport, " | - Sports (video)");
+            AddCategoryMapping(1608, TorznabCatType.TVSport, "football");
+            AddCategoryMapping(1952, TorznabCatType.TVSport, " | - Russia 2016-2017");
+            AddCategoryMapping(2075, TorznabCatType.TVSport, " | - Russia 2015-2016");
+            AddCategoryMapping(1613, TorznabCatType.TVSport, " | - Russia / USSR");
+            AddCategoryMapping(1614, TorznabCatType.TVSport, " | - England");
+            AddCategoryMapping(1623, TorznabCatType.TVSport, " | - Spain");
+            AddCategoryMapping(1615, TorznabCatType.TVSport, " | - Italy");
+            AddCategoryMapping(1630, TorznabCatType.TVSport, " | - Germany");
+            AddCategoryMapping(2425, TorznabCatType.TVSport, " | - France");
+            AddCategoryMapping(2514, TorznabCatType.TVSport, " | - Ukraine");
+            AddCategoryMapping(1616, TorznabCatType.TVSport, " | - Other national championships and cups");
+            AddCategoryMapping(2014, TorznabCatType.TVSport, " | - International Events");
+            AddCategoryMapping(2171, TorznabCatType.TVSport, " | - European Cups 2016-2017");
+            AddCategoryMapping(1491, TorznabCatType.TVSport, " | - European Cups 2015-2016");
+            AddCategoryMapping(1987, TorznabCatType.TVSport, " | - European Cups 2011-2015");
+            AddCategoryMapping(1617, TorznabCatType.TVSport, " | - European Cups");
+            AddCategoryMapping(1610, TorznabCatType.TVSport, " | - European Football Championship 2016");
+            AddCategoryMapping(1620, TorznabCatType.TVSport, " | - European Championships");
+            AddCategoryMapping(1668, TorznabCatType.TVSport, " | - World Cup 2018");
+            AddCategoryMapping(1621, TorznabCatType.TVSport, " | - World Championships");
+            AddCategoryMapping(1998, TorznabCatType.TVSport, " | - Friendly tournaments and matches");
+            AddCategoryMapping(1343, TorznabCatType.TVSport, " | - The survey and analytical programs 2014-2017");
+            AddCategoryMapping(751, TorznabCatType.TVSport, " | - The survey and analytical programs");
+            AddCategoryMapping(1697, TorznabCatType.TVSport, " | - Mini football / Football");
+            AddCategoryMapping(2004, TorznabCatType.TVSport, "basketball");
+            AddCategoryMapping(2001, TorznabCatType.TVSport, " | - International Competitions");
+            AddCategoryMapping(2002, TorznabCatType.TVSport, " |- NBA / NCAA (до 2000 г.)");
+            AddCategoryMapping(283, TorznabCatType.TVSport, " | - NBA / NCAA (2000-2010 biennium).");
+            AddCategoryMapping(1997, TorznabCatType.TVSport, " | - NBA / NCAA (2010-2017 biennium).");
+            AddCategoryMapping(2003, TorznabCatType.TVSport, " | - European club basketball");
+            AddCategoryMapping(2009, TorznabCatType.TVSport, "Hockey");
+            AddCategoryMapping(2010, TorznabCatType.TVSport, " | - Hockey / Bandy");
+            AddCategoryMapping(2006, TorznabCatType.TVSport, " | - International Events");
+            AddCategoryMapping(2007, TorznabCatType.TVSport, " | - KHL");
+            AddCategoryMapping(2005, TorznabCatType.TVSport, " | - NHL (until 2011/12)");
+            AddCategoryMapping(259, TorznabCatType.TVSport, " | - NHL (2013)");
+            AddCategoryMapping(2008, TorznabCatType.TVSport, " | - USSR - Canada");
+            AddCategoryMapping(126, TorznabCatType.TVSport, " | - Documentaries and Analysis");
+            AddCategoryMapping(845, TorznabCatType.TVSport, "Wrestling");
+            AddCategoryMapping(343, TorznabCatType.TVSport, " |- Professional Wrestling");
+            AddCategoryMapping(2111, TorznabCatType.TVSport, " |- Independent Wrestling");
+            AddCategoryMapping(1527, TorznabCatType.TVSport, " |- International Wrestling");
+            AddCategoryMapping(2069, TorznabCatType.TVSport, " |- Oldschool Wrestling");
+            AddCategoryMapping(1323, TorznabCatType.TVSport, " |- Documentary Wrestling");
+
+            // Сериалы
+            AddCategoryMapping(9, TorznabCatType.TV, "Russion serials");
+            AddCategoryMapping(104, TorznabCatType.TV, " | - Secrets of the investigation");
+            AddCategoryMapping(1408, TorznabCatType.TV, " | - National Security Agent");
+            AddCategoryMapping(1535, TorznabCatType.TV, " | - Lawyer");
+            AddCategoryMapping(91, TorznabCatType.TV, " | - Gangster Petersburg");
+            AddCategoryMapping(1356, TorznabCatType.TV, " | - Return of Mukhtar");
+            AddCategoryMapping(990, TorznabCatType.TV, " | - Hounds");
+            AddCategoryMapping(856, TorznabCatType.TV, " | - Capercaillie / Pyatnitskii / Karpov");
+            AddCategoryMapping(188, TorznabCatType.TV, " | - Darya Dontsova");
+            AddCategoryMapping(310, TorznabCatType.TV, " | - Kadetstvo / Kremlëvskie kursanty");
+            AddCategoryMapping(202, TorznabCatType.TV, " | - Kamenskaya");
+            AddCategoryMapping(935, TorznabCatType.TV, " | - Code of Honor");
+            AddCategoryMapping(172, TorznabCatType.TV, " | - A cop-in-law");
+            AddCategoryMapping(805, TorznabCatType.TV, " | - Cop War");
+            AddCategoryMapping(80, TorznabCatType.TV, " | - My Fair Nanny");
+            AddCategoryMapping(119, TorznabCatType.TV, " | - Careful, Modern!");
+            AddCategoryMapping(812, TorznabCatType.TV, " | - Web");
+            AddCategoryMapping(175, TorznabCatType.TV, " | - After");
+            AddCategoryMapping(79, TorznabCatType.TV, " | - Soldiers and others.");
+            AddCategoryMapping(123, TorznabCatType.TV, " | - Stopping Power / Cops / Opera");
+            AddCategoryMapping(189, TorznabCatType.TV, "Foreign TV series");
+            AddCategoryMapping(842, TorznabCatType.TV, " | - News and TV shows in the display stage");
+            AddCategoryMapping(235, TorznabCatType.TV, " | - TV Shows US and Canada");
+            AddCategoryMapping(242, TorznabCatType.TV, " | - TV Shows UK and Ireland");
+            AddCategoryMapping(819, TorznabCatType.TV, " | - Scandinavian series");
+            AddCategoryMapping(1531, TorznabCatType.TV, " | - Spanish series");
+            AddCategoryMapping(721, TorznabCatType.TV, " | - Italian series");
+            AddCategoryMapping(1102, TorznabCatType.TV, " | - European series");
+            AddCategoryMapping(1120, TorznabCatType.TV, " | - TV Shows in Africa, Middle East");
+            AddCategoryMapping(1214, TorznabCatType.TV, " | - TV Shows Australia and New Zealand");
+            AddCategoryMapping(387, TorznabCatType.TV, " | - Serials joint production of several countries");
+            AddCategoryMapping(1359, TorznabCatType.TV, " | - Web series, webisodes and TV series for the pilot episode ..");
+            AddCategoryMapping(271, TorznabCatType.TV, " | - 24 hours / 24");
+            AddCategoryMapping(273, TorznabCatType.TV, " |- Альф / ALF");
+            AddCategoryMapping(743, TorznabCatType.TV, " | - Grey's Anatomy / Grey's Anatomy + Private Practice / Priv ..");
+            AddCategoryMapping(184, TorznabCatType.TV, " | - Buffy - the Vampire Slayer / Buffy + Angel / Angel");
+            AddCategoryMapping(194, TorznabCatType.TV, " | - Bludlivaya California / Californication");
+            AddCategoryMapping(85, TorznabCatType.TV, " |- Вавилон 5 / Babylon 5");
+            AddCategoryMapping(1171, TorznabCatType.TV, " |- Викинги / Vikings");
+            AddCategoryMapping(1417, TorznabCatType.TV, " | - Breaking Bad / Breaking Bad");
+            AddCategoryMapping(1144, TorznabCatType.TV, " | - The Return of Sherlock Holmes / Return of Sherlock Holmes");
+            AddCategoryMapping(595, TorznabCatType.TV, " |- Герои / Heroes");
+            AddCategoryMapping(1288, TorznabCatType.TV, " | - Dexter / Dexter");
+            AddCategoryMapping(1605, TorznabCatType.TV, " | - Two and a Half Men / Two and a Half Men");
+            AddCategoryMapping(1694, TorznabCatType.TV, " |- Династия / Dynasty");
+            AddCategoryMapping(1690, TorznabCatType.TV, " | - The Vampire Diaries / The Vampire Diaries + True Blood ..");
+            AddCategoryMapping(820, TorznabCatType.TV, " |- Доктор Кто / Doctor Who + Торчвуд / Torchwood");
+            AddCategoryMapping(625, TorznabCatType.TV, " |- Доктор Хаус / House M.D.");
+            AddCategoryMapping(84, TorznabCatType.TV, " | - Druzyya / Friends + Joey / Joey");
+            AddCategoryMapping(623, TorznabCatType.TV, " | - Fringe / Fringe");
+            AddCategoryMapping(1798, TorznabCatType.TV, "| - Stargate: Atlantis; Universe / Stargate: Atlanti ..");
+            AddCategoryMapping(106, TorznabCatType.TV, " | - Stargate: SG-1 / Stargate: SG1");
+            AddCategoryMapping(166, TorznabCatType.TV, " | - Battlestar Galactica / Battlestar Galactica + Copper ..");
+            AddCategoryMapping(236, TorznabCatType.TV, " | - Star Trek / Star Trek");
+            AddCategoryMapping(1449, TorznabCatType.TV, " |- Игра престолов / Game of Thrones");
+            AddCategoryMapping(507, TorznabCatType.TV, " | - How I Met Your Mother The Big Bang Theory +");
+            AddCategoryMapping(504, TorznabCatType.TV, " |- Клан Сопрано / The Sopranos");
+            AddCategoryMapping(536, TorznabCatType.TV, " |- Клиника / Scrubs");
+            AddCategoryMapping(173, TorznabCatType.TV, " | - Коломбо / Columbo");
+            AddCategoryMapping(918, TorznabCatType.TV, " | - Inspector Rex / Komissar Rex");
+            AddCategoryMapping(920, TorznabCatType.TV, " | - Bones / Bones");
+            AddCategoryMapping(203, TorznabCatType.TV, " | - Weeds / Weeds");
+            AddCategoryMapping(1243, TorznabCatType.TV, "| - Cool Walker. Justice in Texas / Walker, Texas Ran ..");
+            AddCategoryMapping(140, TorznabCatType.TV, " | - Masters of Horror / Masters of Horror");
+            AddCategoryMapping(636, TorznabCatType.TV, " | - Mentalist / The Mentalist + Castle / Castle");
+            AddCategoryMapping(606, TorznabCatType.TV, " | - Crime / CSI Location: Crime Scene Investigation");
+            AddCategoryMapping(776, TorznabCatType.TV, " |- Мисс Марпл / Miss Marple");
+            AddCategoryMapping(181, TorznabCatType.TV, "| - NCIS; Los Angeles; New Orleans");
+            AddCategoryMapping(1499, TorznabCatType.TV, " | - Murder, She Wrote / Murder, She Wrote + Perry Mason ..");
+            AddCategoryMapping(81, TorznabCatType.TV, " | - Survivors / LOST");
+            AddCategoryMapping(266, TorznabCatType.TV, " | - Desperate Housewives / Desperate Housewives");
+            AddCategoryMapping(252, TorznabCatType.TV, " | - Jailbreak / Prison Break");
+            AddCategoryMapping(196, TorznabCatType.TV, " |- Санта Барбара / Santa Barbara");
+            AddCategoryMapping(372, TorznabCatType.TV, " | - Supernatural / Supernatural");
+            AddCategoryMapping(110, TorznabCatType.TV, " | - The X-Files / The X-Files");
+            AddCategoryMapping(193, TorznabCatType.TV, " | - Sex and the City / Sex And The City");
+            AddCategoryMapping(237, TorznabCatType.TV, " | - Sliding / Sliders");
+            AddCategoryMapping(265, TorznabCatType.TV, " | - Ambulance / ER");
+            AddCategoryMapping(1117, TorznabCatType.TV, " | - Octopus / La Piovra");
+            AddCategoryMapping(497, TorznabCatType.TV, " | - Smallville / Smallville");
+            AddCategoryMapping(121, TorznabCatType.TV, " | - Twin Peaks / Twin Peaks");
+            AddCategoryMapping(134, TorznabCatType.TV, " | - Hercule Poirot / Hercule Poirot");
+            AddCategoryMapping(195, TorznabCatType.TV, " | - For sub-standard hands");
+            AddCategoryMapping(2366, TorznabCatType.TV, "Foreign TV shows (HD Video)");
+            AddCategoryMapping(2401, TorznabCatType.TV, " |- Блудливая Калифорния / Californication (HD Video)");
+            AddCategoryMapping(2390, TorznabCatType.TV, " | - Two and a Half Men / Two and a Half Men (HD Video)");
+            AddCategoryMapping(1669, TorznabCatType.TV, " |- Викинги / Vikings (HD Video)");
+            AddCategoryMapping(2391, TorznabCatType.TV, " |- Декстер / Dexter (HD Video)");
+            AddCategoryMapping(2392, TorznabCatType.TV, " | - Friends / Friends (HD Video)");
+            AddCategoryMapping(2407, TorznabCatType.TV, " |- Доктор Кто / Doctor Who; Торчвуд / Torchwood (HD Video)");
+            AddCategoryMapping(2393, TorznabCatType.TV, " |- Доктор Хаус / House M.D. (HD Video)");
+            AddCategoryMapping(2370, TorznabCatType.TV, " | - Fringe / Fringe (HD Video)");
+            AddCategoryMapping(2394, TorznabCatType.TV, "| - Stargate: a C1; Atlantis; The Universe (HD Video)");
+            AddCategoryMapping(2408, TorznabCatType.TV, "| - Battlestar Galactica / Battlestar Galactica; Capri ..");
+            AddCategoryMapping(2395, TorznabCatType.TV, " | - Star Trek / Star Trek (HD Video)");
+            AddCategoryMapping(2396, TorznabCatType.TV, "| - How I Met Your Mother; The Big Bang Theory (HD Vi ..");
+            AddCategoryMapping(2397, TorznabCatType.TV, " |- Кости / Bones (HD Video)");
+            AddCategoryMapping(2398, TorznabCatType.TV, " | - Weeds / Weeds (HD Video)");
+            AddCategoryMapping(2399, TorznabCatType.TV, "| - Mentalist / The Mentalist; Castle / Castle (HD Video)");
+            AddCategoryMapping(2400, TorznabCatType.TV, " | - Crime / CSI Location: Crime Scene Investigation (HD ..");
+            AddCategoryMapping(2402, TorznabCatType.TV, " | - Survivors / LOST (HD Video)");
+            AddCategoryMapping(2403, TorznabCatType.TV, " | - Jailbreak / Prison Break (HD Video)");
+            AddCategoryMapping(2404, TorznabCatType.TV, " |- Сверхъестественное / Supernatural (HD Video)");
+            AddCategoryMapping(2405, TorznabCatType.TV, " | - The X-Files / The X-Files (HD Video)");
+            AddCategoryMapping(2406, TorznabCatType.TV, " |- Тайны Смолвиля / Smallville (HD Video)");
+            AddCategoryMapping(911, TorznabCatType.TV, "Soaps Latin America, Turkey and India");
+            AddCategoryMapping(1493, TorznabCatType.TV, " | - Actors and actresses of Latin American soap operas");
+            AddCategoryMapping(1301, TorznabCatType.TV, " | - Indian series");
+            AddCategoryMapping(704, TorznabCatType.TV, " | - Turkish serials");
+            AddCategoryMapping(1940, TorznabCatType.TV, " | - Official brief version of Latin American soap operas");
+            AddCategoryMapping(1574, TorznabCatType.TV, " | - Latin American soap operas with the voice acting (folders distribution)");
+            AddCategoryMapping(1539, TorznabCatType.TV, " | - Latin American serials with subtitles");
+            AddCategoryMapping(1500, TorznabCatType.TV, " |- OST");
+            AddCategoryMapping(823, TorznabCatType.TV, " | - Богатые тоже плачут / The Rich Also Cry");
+            AddCategoryMapping(1006, TorznabCatType.TV, " | - Вдова бланко / La Viuda de Blanco");
+            AddCategoryMapping(877, TorznabCatType.TV, " | - Великолепный век / Magnificent Century");
+            AddCategoryMapping(972, TorznabCatType.TV, " | - In the name of love / Por Amor");
+            AddCategoryMapping(781, TorznabCatType.TV, " | - A girl named Fate / Milagros");
+            AddCategoryMapping(1300, TorznabCatType.TV, " |- Дикий ангел / Muneca Brava");
+            AddCategoryMapping(1803, TorznabCatType.TV, " | - Донья Барбара / Female Barbara");
+            AddCategoryMapping(1298, TorznabCatType.TV, " | - Дороги Индии / Passage to India");
+            AddCategoryMapping(825, TorznabCatType.TV, " | - Durnuška Betti / Yo Soy Betty la Fea");
+            AddCategoryMapping(1606, TorznabCatType.TV, " | - The wife of Judas (wine of love) / La Mujer de Judas");
+            AddCategoryMapping(1458, TorznabCatType.TV, " | - Cruel Angel / Anjo Mau");
+            AddCategoryMapping(1463, TorznabCatType.TV, " | - Замарашка / Cara Sucia");
+            AddCategoryMapping(1459, TorznabCatType.TV, " | - A Cinderella Story (Beautiful Loser) / Bella Calamidade ..");
+            AddCategoryMapping(1461, TorznabCatType.TV, " | - Kacorri / Kachorra");
+            AddCategoryMapping(718, TorznabCatType.TV, " |- Клон / O Clone");
+            AddCategoryMapping(1498, TorznabCatType.TV, " | - Клятва / The Oath");
+            AddCategoryMapping(907, TorznabCatType.TV, " | - Lalo / Lalola");
+            AddCategoryMapping(992, TorznabCatType.TV, " | - Morena Clara / Clara Morena");
+            AddCategoryMapping(607, TorznabCatType.TV, " | - Mi Segunda Madre / Mi segunda Madre");
+            AddCategoryMapping(594, TorznabCatType.TV, " | - The rebellious spirit / Rebelde Way");
+            AddCategoryMapping(775, TorznabCatType.TV, " | - Наследница / The Heiress");
+            AddCategoryMapping(534, TorznabCatType.TV, " | - Nobody but you / Tu o Nadie");
+            AddCategoryMapping(1462, TorznabCatType.TV, " | - Падре Корахе / Father Courage");
+            AddCategoryMapping(1678, TorznabCatType.TV, " | - Падший ангел / Mas Sabe el Diablo");
+            AddCategoryMapping(904, TorznabCatType.TV, " | - Предательство / The Betrayal");
+            AddCategoryMapping(1460, TorznabCatType.TV, " | - Призрак Элены / The Phantom of Elena");
+            AddCategoryMapping(816, TorznabCatType.TV, " | - Live your life / Viver a vida");
+            AddCategoryMapping(815, TorznabCatType.TV, " | - Just Maria / Simplemente Maria");
+            AddCategoryMapping(325, TorznabCatType.TV, " | - Rabыnya Isaura / Escrava Isaura");
+            AddCategoryMapping(1457, TorznabCatType.TV, " | - Реванш 2000 / Retaliation 2000");
+            AddCategoryMapping(1692, TorznabCatType.TV, " | - Family Ties / Lacos de Familia");
+            AddCategoryMapping(1540, TorznabCatType.TV, " | - Perfect Beauty / Beleza pura");
+            AddCategoryMapping(694, TorznabCatType.TV, " | - Secrets of Love / Los Misterios del Amor");
+            AddCategoryMapping(1949, TorznabCatType.TV, " | - Фаворитка / A Favorita");
+            AddCategoryMapping(1541, TorznabCatType.TV, " | - Цыганская кровь / Soy gitano");
+            AddCategoryMapping(1941, TorznabCatType.TV, " | - Шторм / Storm");
+            AddCategoryMapping(1537, TorznabCatType.TV, " | - For sub-standard hands");
+            AddCategoryMapping(2100, TorznabCatType.TV, "Asian series");
+            AddCategoryMapping(717, TorznabCatType.TV, " | - Chinese serials with subtitles");
+            AddCategoryMapping(915, TorznabCatType.TV, " | - Korean TV shows with voice acting");
+            AddCategoryMapping(1242, TorznabCatType.TV, " | - Korean serials with subtitles");
+            AddCategoryMapping(2412, TorznabCatType.TV, " | - Other Asian series with the voice acting");
+            AddCategoryMapping(1938, TorznabCatType.TV, " | - Taiwanese serials with subtitles");
+            AddCategoryMapping(2104, TorznabCatType.TV, " | - Japanese serials with subtitles");
+            AddCategoryMapping(1939, TorznabCatType.TV, " | - Japanese TV series with the voice acting");
+            AddCategoryMapping(2102, TorznabCatType.TV, " | -. VMV and other videos");
+            AddCategoryMapping(2103, TorznabCatType.TV, " |- OST");
+
+            // Книги и журналы
+            AddCategoryMapping(1411, TorznabCatType.Books, " | - Scanning, processing skanov");
+            AddCategoryMapping(21, TorznabCatType.Books, "books");
+            AddCategoryMapping(2157, TorznabCatType.Books, " | - Film, TV, animation");
+            AddCategoryMapping(765, TorznabCatType.Books, " | - Design, Graphic Design");
+            AddCategoryMapping(2019, TorznabCatType.Books, " | - Photography and video");
+            AddCategoryMapping(31, TorznabCatType.Books, " | - Magazines and newspapers (general section)");
+            AddCategoryMapping(1427, TorznabCatType.Books, " | - Esoteric Tarot, Feng Shui");
+            AddCategoryMapping(2422, TorznabCatType.Books, " | - Astrology");
+            AddCategoryMapping(2195, TorznabCatType.Books, "| - Beauty. Care. housekeeping");
+            AddCategoryMapping(2521, TorznabCatType.Books, "| - Fashion. Style. Etiquette");
+            AddCategoryMapping(2223, TorznabCatType.Books, " | - Travel and Tourism");
+            AddCategoryMapping(2447, TorznabCatType.Books, " | - Celebrity idols");
+            AddCategoryMapping(39, TorznabCatType.Books, " | - Miscellaneous");
+            AddCategoryMapping(1101, TorznabCatType.Books, "For children, parents and teachers");
+            AddCategoryMapping(745, TorznabCatType.Books, " | - Textbooks for kindergarten and primary school (..");
+            AddCategoryMapping(1689, TorznabCatType.Books, " | - Textbooks for high school (grades 5-11)");
+            AddCategoryMapping(2336, TorznabCatType.Books, " | - Teachers and educators");
+            AddCategoryMapping(2337, TorznabCatType.Books, " | - Scientific-popular and informative literature (for children ..");
+            AddCategoryMapping(1353, TorznabCatType.Books, " | - Leisure and creativity");
+            AddCategoryMapping(1400, TorznabCatType.Books, " | - Education and development");
+            AddCategoryMapping(1415, TorznabCatType.Books, "| - Hood. lit-ra for preschool and elementary grades");
+            AddCategoryMapping(2046, TorznabCatType.Books, "| - Hood. lit-ra for the middle and upper classes");
+            AddCategoryMapping(1802, TorznabCatType.Books, "Sports, physical training, martial arts");
+            AddCategoryMapping(2189, TorznabCatType.Books, " | - Football");
+            AddCategoryMapping(2190, TorznabCatType.Books, " | - Hockey");
+            AddCategoryMapping(2443, TorznabCatType.Books, " | - Team sports");
+            AddCategoryMapping(1477, TorznabCatType.Books, "| - Athletics. Swimming. Gymnastics. Weightlifting...");
+            AddCategoryMapping(669, TorznabCatType.Books, "| - Motorsport. Motorcycling. cycle racing");
+            AddCategoryMapping(2196, TorznabCatType.Books, "| - Chess. Checkers");
+            AddCategoryMapping(2056, TorznabCatType.Books, " | - Martial Arts, Martial Arts");
+            AddCategoryMapping(1436, TorznabCatType.Books, " | - Extreme");
+            AddCategoryMapping(2191, TorznabCatType.Books, " | - Fitness, fitness, bodybuilding");
+            AddCategoryMapping(2477, TorznabCatType.Books, " | - Sports press");
+            AddCategoryMapping(1680, TorznabCatType.Books, "Humanitarian sciences");
+            AddCategoryMapping(1684, TorznabCatType.Books, "| - Arts. Cultural");
+            AddCategoryMapping(2446, TorznabCatType.Books, "| - Folklore. Epic. Mythology");
+            AddCategoryMapping(2524, TorznabCatType.Books, " | - Literature");
+            AddCategoryMapping(2525, TorznabCatType.Books, " | - Linguistics");
+            AddCategoryMapping(995, TorznabCatType.Books, " | - Philosophy");
+            AddCategoryMapping(2022, TorznabCatType.Books, " | - Political Science");
+            AddCategoryMapping(2471, TorznabCatType.Books, " | - Sociology");
+            AddCategoryMapping(2375, TorznabCatType.Books, " | - Journalism, Journalism");
+            AddCategoryMapping(764, TorznabCatType.Books, " | - Business, Management");
+            AddCategoryMapping(1685, TorznabCatType.Books, " | - Marketing");
+            AddCategoryMapping(1688, TorznabCatType.Books, " | - Economy");
+            AddCategoryMapping(2472, TorznabCatType.Books, " | - Finance");
+            AddCategoryMapping(1687, TorznabCatType.Books, "| - Jurisprudence. Right. criminalistics");
+            AddCategoryMapping(2020, TorznabCatType.Books, "Historical sciences");
+            AddCategoryMapping(1349, TorznabCatType.Books, " | - Philosophy and Methodology of Historical Science");
+            AddCategoryMapping(1967, TorznabCatType.Books, " | - Historical sources");
+            AddCategoryMapping(2049, TorznabCatType.Books, " | - Historic Person");
+            AddCategoryMapping(1681, TorznabCatType.Books, " | - Alternative historical theories");
+            AddCategoryMapping(2319, TorznabCatType.Books, " | - Archaeology");
+            AddCategoryMapping(2434, TorznabCatType.Books, "| - Ancient World. Antiquity");
+            AddCategoryMapping(1683, TorznabCatType.Books, " | - The Middle Ages");
+            AddCategoryMapping(2444, TorznabCatType.Books, " | - History of modern and contemporary");
+            AddCategoryMapping(2427, TorznabCatType.Books, " | - European History");
+            AddCategoryMapping(2452, TorznabCatType.Books, " | - History of Asia and Africa");
+            AddCategoryMapping(2445, TorznabCatType.Books, " | - History of America, Australia, Oceania");
+            AddCategoryMapping(2435, TorznabCatType.Books, " | - History of Russia");
+            AddCategoryMapping(2436, TorznabCatType.Books, " | - The Age of the USSR");
+            AddCategoryMapping(2453, TorznabCatType.Books, " | - History of the countries of the former USSR");
+            AddCategoryMapping(2320, TorznabCatType.Books, " | - Ethnography, anthropology");
+            AddCategoryMapping(1801, TorznabCatType.Books, "| - International relations. Diplomacy");
+            AddCategoryMapping(2023, TorznabCatType.Books, "Accurate, natural and engineering sciences");
+            AddCategoryMapping(2024, TorznabCatType.Books, " | - Aviation / Cosmonautics");
+            AddCategoryMapping(2026, TorznabCatType.Books, " | - Physics");
+            AddCategoryMapping(2192, TorznabCatType.Books, " | - Astronomy");
+            AddCategoryMapping(2027, TorznabCatType.Books, " | - Biology / Ecology");
+            AddCategoryMapping(295, TorznabCatType.Books, " | - Chemistry / Biochemistry");
+            AddCategoryMapping(2028, TorznabCatType.Books, " | - Mathematics");
+            AddCategoryMapping(2029, TorznabCatType.Books, " | - Geography / Geology / Geodesy");
+            AddCategoryMapping(1325, TorznabCatType.Books, " | - Electronics / Radio");
+            AddCategoryMapping(2386, TorznabCatType.Books, " | - Diagrams and service manuals (original documents)");
+            AddCategoryMapping(2031, TorznabCatType.Books, " | - Architecture / Construction / Engineering networks");
+            AddCategoryMapping(2030, TorznabCatType.Books, " | - Engineering");
+            AddCategoryMapping(2526, TorznabCatType.Books, " | - Welding / Soldering / Non-Destructive Testing");
+            AddCategoryMapping(2527, TorznabCatType.Books, " | - Automation / Robotics");
+            AddCategoryMapping(2254, TorznabCatType.Books, " | - Metallurgy / Materials");
+            AddCategoryMapping(2376, TorznabCatType.Books, " | - Mechanics, strength of materials");
+            AddCategoryMapping(2054, TorznabCatType.Books, " | - Power engineering / electrical");
+            AddCategoryMapping(770, TorznabCatType.Books, " | - Oil, Gas and Chemicals");
+            AddCategoryMapping(2476, TorznabCatType.Books, " | - Agriculture and food industry");
+            AddCategoryMapping(2494, TorznabCatType.Books, " | - Railway case");
+            AddCategoryMapping(1528, TorznabCatType.Books, " | - Normative documentation");
+            AddCategoryMapping(2032, TorznabCatType.Books, " | - Journals: scientific, popular, radio and others.");
+            AddCategoryMapping(768, TorznabCatType.Books, "Warfare");
+            AddCategoryMapping(2099, TorznabCatType.Books, " | - Militaria");
+            AddCategoryMapping(2021, TorznabCatType.Books, " | - Military History");
+            AddCategoryMapping(2437, TorznabCatType.Books, " | - History of the Second World War");
+            AddCategoryMapping(1447, TorznabCatType.Books, " | - Military equipment");
+            AddCategoryMapping(2468, TorznabCatType.Books, " | - Small arms");
+            AddCategoryMapping(2469, TorznabCatType.Books, " | - Educational literature");
+            AddCategoryMapping(2470, TorznabCatType.Books, " | - Special forces of the world");
+            AddCategoryMapping(1686, TorznabCatType.Books, "Faith and Religion");
+            AddCategoryMapping(2215, TorznabCatType.Books, " | - Christianity");
+            AddCategoryMapping(2216, TorznabCatType.Books, " | - Islam");
+            AddCategoryMapping(2217, TorznabCatType.Books, " | - Religions of India, Tibet and East Asia / Judaism");
+            AddCategoryMapping(2218, TorznabCatType.Books, " | - Non-traditional religious, spiritual and mystical teachings ..");
+            AddCategoryMapping(2252, TorznabCatType.Books, "| - Religion. History of Religions. Atheism");
+            AddCategoryMapping(767, TorznabCatType.Books, "psychology");
+            AddCategoryMapping(2515, TorznabCatType.Books, " | - General and Applied Psychology");
+            AddCategoryMapping(2516, TorznabCatType.Books, " | - Psychotherapy and Counseling");
+            AddCategoryMapping(2517, TorznabCatType.Books, " | - Psychodiagnostics and psyhokorrektsyya");
+            AddCategoryMapping(2518, TorznabCatType.Books, " | - Social psychology and psychology of relationships");
+            AddCategoryMapping(2519, TorznabCatType.Books, " | - Training and Coaching");
+            AddCategoryMapping(2520, TorznabCatType.Books, " | - Personal development and self-improvement");
+            AddCategoryMapping(1696, TorznabCatType.Books, " | - Popular Psychology");
+            AddCategoryMapping(2253, TorznabCatType.Books, "| - Sexology. Relations between the sexes");
+            AddCategoryMapping(2033, TorznabCatType.Books, "Collecting, hobby and hobbies");
+            AddCategoryMapping(1412, TorznabCatType.Books, "| - Collecting and auxiliary ist. discipline");
+            AddCategoryMapping(1446, TorznabCatType.Books, " | - Embroidery");
+            AddCategoryMapping(753, TorznabCatType.Books, " | - Knitting");
+            AddCategoryMapping(2037, TorznabCatType.Books, " | - Sewing, Patchwork");
+            AddCategoryMapping(2224, TorznabCatType.Books, " | - Lace");
+            AddCategoryMapping(2194, TorznabCatType.Books, "| - Beading. Yuvelirika. Jewellery wire.");
+            AddCategoryMapping(2418, TorznabCatType.Books, " | - Paper Art");
+            AddCategoryMapping(1410, TorznabCatType.Books, " | - Other arts and crafts");
+            AddCategoryMapping(2034, TorznabCatType.Books, " | - Pets and aquariums");
+            AddCategoryMapping(2433, TorznabCatType.Books, " | - Hunting and fishing");
+            AddCategoryMapping(1961, TorznabCatType.Books, " | - Cooking (Book)");
+            AddCategoryMapping(2432, TorznabCatType.Books, " | - Cooking (newspapers and magazines)");
+            AddCategoryMapping(565, TorznabCatType.Books, " | - Modelling");
+            AddCategoryMapping(1523, TorznabCatType.Books, " | - Farmland / Floriculture");
+            AddCategoryMapping(1575, TorznabCatType.Books, " | - Repair, private construction, design of interiors");
+            AddCategoryMapping(1520, TorznabCatType.Books, " | - Woodworking");
+            AddCategoryMapping(2424, TorznabCatType.Books, " | - Board Games");
+            AddCategoryMapping(769, TorznabCatType.Books, " | - Other Hobbies");
+            AddCategoryMapping(2038, TorznabCatType.Books, "Fiction");
+            AddCategoryMapping(2043, TorznabCatType.Books, " | - Russian literature");
+            AddCategoryMapping(2042, TorznabCatType.Books, " | - Foreign literature (up to 1900)");
+            AddCategoryMapping(2041, TorznabCatType.Books, " | - Foreign literature (XX and XXI century)");
+            AddCategoryMapping(2044, TorznabCatType.Books, " | - Detective, Action");
+            AddCategoryMapping(2039, TorznabCatType.Books, " | - Female Novel");
+            AddCategoryMapping(2045, TorznabCatType.Books, " | - Domestic science fiction / fantasy / mystic");
+            AddCategoryMapping(2080, TorznabCatType.Books, " | - International science fiction / fantasy / mystic");
+            AddCategoryMapping(2047, TorznabCatType.Books, " | - Adventure");
+            AddCategoryMapping(2193, TorznabCatType.Books, " | - Literary Magazines");
+            AddCategoryMapping(1418, TorznabCatType.Books, "Computer books");
+            AddCategoryMapping(1422, TorznabCatType.Books, " | - Software from Microsoft");
+            AddCategoryMapping(1423, TorznabCatType.Books, " | - Other software");
+            AddCategoryMapping(1424, TorznabCatType.Books, " |- Mac OS; Linux, FreeBSD и прочие *NIX");
+            AddCategoryMapping(1445, TorznabCatType.Books, " | - RDBMS");
+            AddCategoryMapping(1425, TorznabCatType.Books, " | - Web Design and Programming");
+            AddCategoryMapping(1426, TorznabCatType.Books, " | - Programming");
+            AddCategoryMapping(1428, TorznabCatType.Books, " | - Graphics, Video Processing");
+            AddCategoryMapping(1429, TorznabCatType.Books, " | - Network / VoIP");
+            AddCategoryMapping(1430, TorznabCatType.Books, " | - Hacking and Security");
+            AddCategoryMapping(1431, TorznabCatType.Books, " | - Iron (book on a PC)");
+            AddCategoryMapping(1433, TorznabCatType.Books, " | - Engineering and scientific programs");
+            AddCategoryMapping(1432, TorznabCatType.Books, " | - Computer magazines and annexes");
+            AddCategoryMapping(2202, TorznabCatType.Books, " | - Disc applications to gaming magazines");
+            AddCategoryMapping(862, TorznabCatType.Books, "Comics");
+            AddCategoryMapping(2461, TorznabCatType.Books, " | - Comics in Russian");
+            AddCategoryMapping(2462, TorznabCatType.Books, " | - Marvel Comics publishing");
+            AddCategoryMapping(2463, TorznabCatType.Books, " | - DC Comics publishing");
+            AddCategoryMapping(2464, TorznabCatType.Books, " | - Comics from other publishers");
+            AddCategoryMapping(2473, TorznabCatType.Books, " | - Comics in other languages");
+            AddCategoryMapping(2465, TorznabCatType.Books, " | - Manga (in foreign languages)");
+            AddCategoryMapping(2048, TorznabCatType.Books, "Collections of books and libraries");
+            AddCategoryMapping(1238, TorznabCatType.Books, " | - Library (mirror network libraries / collections)");
+            AddCategoryMapping(2055, TorznabCatType.Books, " | - Thematic collections (collections)");
+            AddCategoryMapping(754, TorznabCatType.Books, " | - Multidisciplinary collections (collections)");
+            AddCategoryMapping(2114, TorznabCatType.Books, "Multimedia and online publications");
+            AddCategoryMapping(2438, TorznabCatType.Books, " | - Multimedia Encyclopedia");
+            AddCategoryMapping(2439, TorznabCatType.Books, " | - Interactive tutorials and educational materials");
+            AddCategoryMapping(2440, TorznabCatType.Books, " | - Educational publications for children");
+            AddCategoryMapping(2441, TorznabCatType.Books, "| - Cooking. Floriculture. housekeeping");
+            AddCategoryMapping(2442, TorznabCatType.Books, "| - Culture. Art. History");
+
+            // Обучение иностранным языкам
+            AddCategoryMapping(2362, TorznabCatType.Books, "Foreign Language for Adults");
+            AddCategoryMapping(1265, TorznabCatType.Books, " | - English (for adults)");
+            AddCategoryMapping(1266, TorznabCatType.Books, " | - German");
+            AddCategoryMapping(1267, TorznabCatType.Books, " | - French");
+            AddCategoryMapping(1358, TorznabCatType.Books, " | - Spanish");
+            AddCategoryMapping(2363, TorznabCatType.Books, " | - Italian");
+            AddCategoryMapping(1268, TorznabCatType.Books, " | - Other European languages");
+            AddCategoryMapping(1673, TorznabCatType.Books, " | - Arabic");
+            AddCategoryMapping(1269, TorznabCatType.Books, " | - Chinese");
+            AddCategoryMapping(1270, TorznabCatType.Books, " | - Japanese");
+            AddCategoryMapping(1275, TorznabCatType.Books, " | - Other Asian languages");
+            AddCategoryMapping(2364, TorznabCatType.Books, " | - Russian as a foreign language");
+            AddCategoryMapping(1276, TorznabCatType.Books, " | - Multilanguage collections");
+            AddCategoryMapping(1274, TorznabCatType.Books, " | - Other (foreign languages)");
+            AddCategoryMapping(2094, TorznabCatType.Books, " | - LIM-courses");
+            AddCategoryMapping(1264, TorznabCatType.Books, "Foreign languages &#8203;&#8203;for children");
+            AddCategoryMapping(2358, TorznabCatType.Books, " | - English (for children)");
+            AddCategoryMapping(2359, TorznabCatType.Books, " | - Other European languages &#8203;&#8203;(for children)");
+            AddCategoryMapping(2360, TorznabCatType.Books, " | - Eastern languages &#8203;&#8203;(for children)");
+            AddCategoryMapping(2361, TorznabCatType.Books, " | - School textbooks, exam (for children)");
+            AddCategoryMapping(2057, TorznabCatType.Books, "Fiction");
+            AddCategoryMapping(2355, TorznabCatType.Books, " | - Fiction in English");
+            AddCategoryMapping(2474, TorznabCatType.Books, " | - Fiction French");
+            AddCategoryMapping(2356, TorznabCatType.Books, " | - Fiction in other European languages");
+            AddCategoryMapping(2357, TorznabCatType.Books, " | - Fiction in oriental languages");
+            AddCategoryMapping(2413, TorznabCatType.Books, "Audio Books in foreign languages");
+            AddCategoryMapping(1501, TorznabCatType.Books, " | - Audiobooks in English");
+            AddCategoryMapping(1580, TorznabCatType.Books, " | - Audiobooks in German");
+            AddCategoryMapping(525, TorznabCatType.Books, " | - Audiobooks in other languages");
+
+            // Обучающее видео
+            AddCategoryMapping(610, TorznabCatType.Books, "Video tutorials and interactive training DVD");
+            AddCategoryMapping(1568, TorznabCatType.Books, " | - Cooking");
+            AddCategoryMapping(1542, TorznabCatType.Books, " | - Sport");
+            AddCategoryMapping(2335, TorznabCatType.Books, " | - Fitness - Cardio, Strength Training");
+            AddCategoryMapping(1544, TorznabCatType.Books, " | - Fitness - Mind and Body");
+            AddCategoryMapping(1545, TorznabCatType.Books, " | - Extreme");
+            AddCategoryMapping(1546, TorznabCatType.Books, " | - Bodybuilding");
+            AddCategoryMapping(1549, TorznabCatType.Books, " | - Health Practice");
+            AddCategoryMapping(1597, TorznabCatType.Books, " | - Yoga");
+            AddCategoryMapping(1552, TorznabCatType.Books, " | - Video and Snapshots");
+            AddCategoryMapping(1550, TorznabCatType.Books, " | - Personal care");
+            AddCategoryMapping(1553, TorznabCatType.Books, " | - Drawing");
+            AddCategoryMapping(1554, TorznabCatType.Books, " | - Playing the guitar");
+            AddCategoryMapping(617, TorznabCatType.Books, " | - Percussion");
+            AddCategoryMapping(1555, TorznabCatType.Books, " | - Other musical instruments");
+            AddCategoryMapping(2017, TorznabCatType.Books, " | - Play the bass guitar");
+            AddCategoryMapping(1257, TorznabCatType.Books, " | - Ballroom dancing");
+            AddCategoryMapping(1258, TorznabCatType.Books, " | - Belly Dance");
+            AddCategoryMapping(2208, TorznabCatType.Books, " | - The street and club dancing");
+            AddCategoryMapping(677, TorznabCatType.Books, " | - Dancing, miscellaneous");
+            AddCategoryMapping(1255, TorznabCatType.Books, " | - Hunting");
+            AddCategoryMapping(1479, TorznabCatType.Books, " | - Fishing and spearfishing");
+            AddCategoryMapping(1261, TorznabCatType.Books, " | - Tricks and stunts");
+            AddCategoryMapping(614, TorznabCatType.Books, " | - Education");
+            AddCategoryMapping(1259, TorznabCatType.Books, " | - Business, Economics and Finance");
+            AddCategoryMapping(2065, TorznabCatType.Books, " | - Pregnancy, childbirth, motherhood");
+            AddCategoryMapping(1254, TorznabCatType.Books, " | - Training videos for children");
+            AddCategoryMapping(1260, TorznabCatType.Books, " | - Psychology");
+            AddCategoryMapping(2209, TorznabCatType.Books, " | - Esoteric, self-development");
+            AddCategoryMapping(2210, TorznabCatType.Books, " | - Van, dating");
+            AddCategoryMapping(1547, TorznabCatType.Books, " | - Construction, repair and design");
+            AddCategoryMapping(1548, TorznabCatType.Books, " | - Wood and metal");
+            AddCategoryMapping(2211, TorznabCatType.Books, " | - Plants and Animals");
+            AddCategoryMapping(615, TorznabCatType.Books, " | - Miscellaneous");
+            AddCategoryMapping(1581, TorznabCatType.Books, "Martial Arts (Video Tutorials)");
+            AddCategoryMapping(1590, TorznabCatType.Books, " | - Aikido and Aiki-jutsu");
+            AddCategoryMapping(1587, TorznabCatType.Books, " | - Vin Chun");
+            AddCategoryMapping(1594, TorznabCatType.Books, " | - Jiu-Jitsu");
+            AddCategoryMapping(1591, TorznabCatType.Books, " | - Judo and Sambo");
+            AddCategoryMapping(1588, TorznabCatType.Books, " | - Karate");
+            AddCategoryMapping(1596, TorznabCatType.Books, " | - Knife Fight");
+            AddCategoryMapping(1585, TorznabCatType.Books, " | - Work with weapon");
+            AddCategoryMapping(1586, TorznabCatType.Books, " | - Russian style");
+            AddCategoryMapping(2078, TorznabCatType.Books, " | - Dogfight");
+            AddCategoryMapping(1929, TorznabCatType.Books, " | - Mixed styles");
+            AddCategoryMapping(1593, TorznabCatType.Books, " | - Percussion styles");
+            AddCategoryMapping(1592, TorznabCatType.Books, " | - This is a");
+            AddCategoryMapping(1595, TorznabCatType.Books, " | - Miscellaneous");
+            AddCategoryMapping(1556, TorznabCatType.Books, "Computer video tutorials and interactive training DVD");
+            AddCategoryMapping(1560, TorznabCatType.Books, " | - Networks and Security");
+            AddCategoryMapping(1561, TorznabCatType.Books, " | - OS and Microsoft Server Software");
+            AddCategoryMapping(1653, TorznabCatType.Books, " | - Microsoft Office program");
+            AddCategoryMapping(1570, TorznabCatType.Books, " | - OS and UNIX family program");
+            AddCategoryMapping(1654, TorznabCatType.Books, " | - Adobe Photoshop");
+            AddCategoryMapping(1655, TorznabCatType.Books, " |- Autodesk Maya");
+            AddCategoryMapping(1656, TorznabCatType.Books, " | - Autodesk 3ds Max");
+            AddCategoryMapping(1930, TorznabCatType.Books, " |- Autodesk Softimage (XSI)");
+            AddCategoryMapping(1931, TorznabCatType.Books, " |- ZBrush");
+            AddCategoryMapping(1932, TorznabCatType.Books, " |- Flash, Flex и ActionScript");
+            AddCategoryMapping(1562, TorznabCatType.Books, " | - 2D-графика");
+            AddCategoryMapping(1563, TorznabCatType.Books, " | - 3D-графика");
+            AddCategoryMapping(1626, TorznabCatType.Books, " | - Engineering and scientific programs");
+            AddCategoryMapping(1564, TorznabCatType.Books, " | - Web-design");
+            AddCategoryMapping(1565, TorznabCatType.Books, " | - Programming");
+            AddCategoryMapping(1559, TorznabCatType.Books, " | - Software for Mac OS");
+            AddCategoryMapping(1566, TorznabCatType.Books, " | - Working with video");
+            AddCategoryMapping(1573, TorznabCatType.Books, " | - Working with sound");
+            AddCategoryMapping(1567, TorznabCatType.Books, " | - Other (Computer video tutorials)");
+
+            // Аудиокниги
+            AddCategoryMapping(2326, TorznabCatType.Audio, "Auditions, history, memoirs");
+            AddCategoryMapping(574, TorznabCatType.Audio, " | - [Audio] Auditions and readings");
+            AddCategoryMapping(1036, TorznabCatType.Audio, " | - [Audio] Lots of great people");
+            AddCategoryMapping(400, TorznabCatType.Audio, " | - [Audio] Historical Book");
+            AddCategoryMapping(2389, TorznabCatType.Audio, "Science fiction, fantasy, mystery, horror, fanfiction");
+            AddCategoryMapping(2388, TorznabCatType.Audio, " | - [Audio] Foreign fiction, fantasy, mystery, horror, ..");
+            AddCategoryMapping(2387, TorznabCatType.Audio, " | - [Audio] Russian fiction, fantasy, mystery, horror, ..");
+            AddCategoryMapping(2348, TorznabCatType.Audio, " | - [Audio] Puzzle / Miscellaneous Science Fiction, Fantasy, Mystery, too ..");
+            AddCategoryMapping(2327, TorznabCatType.Audio, "Fiction");
+            AddCategoryMapping(695, TorznabCatType.Audio, " | - [Audio] Poetry");
+            AddCategoryMapping(399, TorznabCatType.Audio, " | - [Audio] Foreign literature");
+            AddCategoryMapping(402, TorznabCatType.Audio, " | - [Audio] Russian literature");
+            AddCategoryMapping(490, TorznabCatType.Audio, " | - [Audio] Children's Books");
+            AddCategoryMapping(499, TorznabCatType.Audio, " | - [Audio] Detectives, Adventure, Thriller, Action");
+            AddCategoryMapping(2324, TorznabCatType.Audio, "religion");
+            AddCategoryMapping(2325, TorznabCatType.Audio, " | - [Audio] Orthodoxy");
+            AddCategoryMapping(2342, TorznabCatType.Audio, " | - [Audio] Islam");
+            AddCategoryMapping(530, TorznabCatType.Audio, " | - [Audio] Other traditional religion");
+            AddCategoryMapping(2152, TorznabCatType.Audio, " | - [Audio] Non-traditional religious and philosophical teachings");
+            AddCategoryMapping(2328, TorznabCatType.Audio, "other literature");
+            AddCategoryMapping(403, TorznabCatType.Audio, " | - [Audio] academic and popular literature");
+            AddCategoryMapping(1279, TorznabCatType.Audio, " | - [Audio] lossless-audio books");
+            AddCategoryMapping(716, TorznabCatType.Audio, " | - [Audio] Business");
+            AddCategoryMapping(2165, TorznabCatType.Audio, " | - [Audio] Miscellaneous");
+            AddCategoryMapping(401, TorznabCatType.Audio, " | - [Audio], sub-standard distribution");
+
+            // Все по авто и мото
+            AddCategoryMapping(1964, TorznabCatType.Books, "Repair and maintenance of vehicles");
+            AddCategoryMapping(1973, TorznabCatType.Books, " | - Original catalogs on selection of spare parts");
+            AddCategoryMapping(1974, TorznabCatType.Books, " | - Non-original spare parts catalogs for selection");
+            AddCategoryMapping(1975, TorznabCatType.Books, " | - Diagnostic and repair programs");
+            AddCategoryMapping(1976, TorznabCatType.Books, " | - Tuning, chip tuning, tuning");
+            AddCategoryMapping(1977, TorznabCatType.Books, " | - Books for the repair / maintenance / operation of the vehicle");
+            AddCategoryMapping(1203, TorznabCatType.Books, " | - Multimediyki repair / maintenance / operation of the vehicle");
+            AddCategoryMapping(1978, TorznabCatType.Books, " | - Accounting, utilities, etc.");
+            AddCategoryMapping(1979, TorznabCatType.Books, " | - Virtual Driving School");
+            AddCategoryMapping(1980, TorznabCatType.Books, " | - Video lessons on driving vehicles");
+            AddCategoryMapping(1981, TorznabCatType.Books, " | - Tutorials repair vehicles");
+            AddCategoryMapping(1970, TorznabCatType.Books, " | - Journals by car / moto");
+            AddCategoryMapping(334, TorznabCatType.Books, " | - Water transport");
+            AddCategoryMapping(1202, TorznabCatType.Books, "Movies and transfer by car / moto");
+            AddCategoryMapping(1985, TorznabCatType.Books, " | - Documentary / educational films");
+            AddCategoryMapping(1982, TorznabCatType.Books, " | - Entertainment shows");
+            AddCategoryMapping(2151, TorznabCatType.Books, " |- Top Gear/Топ Гир");
+            AddCategoryMapping(1983, TorznabCatType.Books, " | - Test Drive / Reviews / Motor");
+            AddCategoryMapping(1984, TorznabCatType.Books, " | - Tuning / Fast and the Furious");
+
+            // Музыка
+            AddCategoryMapping(409, TorznabCatType.Audio, "Classical and contemporary academic music");
+            AddCategoryMapping(1660, TorznabCatType.Audio, " | - In-house digitizing (Classical Music)");
+            AddCategoryMapping(1164, TorznabCatType.Audio, " | - Multi-channel music (classical and modern classics in ..");
+            AddCategoryMapping(1884, TorznabCatType.Audio, " | - Hi-Res stereo (classic and modern classic in obrabot ..");
+            AddCategoryMapping(445, TorznabCatType.Audio, " | - Classical music (Video)");
+            AddCategoryMapping(984, TorznabCatType.Audio, " | - Classical music (DVD and HD Video)");
+            AddCategoryMapping(702, TorznabCatType.Audio, " | - Opera (Video)");
+            AddCategoryMapping(983, TorznabCatType.Audio, " |- Опера (DVD и HD Видео)");
+            AddCategoryMapping(1990, TorznabCatType.Audio, " | - Ballet and contemporary dance (Video, DVD and HD Video)");
+            AddCategoryMapping(560, TorznabCatType.Audio, " | - Complete collection of works and multi-disc edition (lossl ..");
+            AddCategoryMapping(794, TorznabCatType.Audio, " |- Опера (lossless)");
+            AddCategoryMapping(556, TorznabCatType.Audio, " | - Vocal music (lossless)");
+            AddCategoryMapping(2307, TorznabCatType.Audio, " | - Horovaya Music (lossless)");
+            AddCategoryMapping(557, TorznabCatType.Audio, " | - Orchestral music (lossless)");
+            AddCategoryMapping(2308, TorznabCatType.Audio, " | - Concerto for Orchestra Instrument (lossless)");
+            AddCategoryMapping(558, TorznabCatType.Audio, " | - Chamber instrumental music (lossless)");
+            AddCategoryMapping(793, TorznabCatType.Audio, " | - Solo instrumental music (lossless)");
+            AddCategoryMapping(436, TorznabCatType.Audio, " | - Complete collection of works and multi-disc edition (lossy ..");
+            AddCategoryMapping(2309, TorznabCatType.Audio, " | - Vocal and choral music (lossy)");
+            AddCategoryMapping(2310, TorznabCatType.Audio, " | - Orchestral music (lossy)");
+            AddCategoryMapping(2311, TorznabCatType.Audio, " | - Chamber and solo instrumental music (lossy)");
+            AddCategoryMapping(969, TorznabCatType.Audio, " | - Classics in modern processing, Classical Crossover (l ..");
+            AddCategoryMapping(1125, TorznabCatType.Audio, "Folklore, Folk and World Music");
+            AddCategoryMapping(1130, TorznabCatType.Audio, " |- Восточноевропейский фолк (lossy)");
+            AddCategoryMapping(1131, TorznabCatType.Audio, " | - Eastern European Folk (lossless)");
+            AddCategoryMapping(1132, TorznabCatType.Audio, " |- Западноевропейский фолк (lossy)");
+            AddCategoryMapping(1133, TorznabCatType.Audio, " |- Западноевропейский фолк (lossless)");
+            AddCategoryMapping(2084, TorznabCatType.Audio, " | - Klezmer and Jewish folklore (lossy and lossless)");
+            AddCategoryMapping(1128, TorznabCatType.Audio, " | - World Music Siberia, Central Asia and East Asia (loss ..");
+            AddCategoryMapping(1129, TorznabCatType.Audio, " | - World Music Siberia, Central Asia and East Asia (loss ..");
+            AddCategoryMapping(1856, TorznabCatType.Audio, " | - World Music India (lossy)");
+            AddCategoryMapping(2430, TorznabCatType.Audio, " | - World Music India (lossless)");
+            AddCategoryMapping(1283, TorznabCatType.Audio, " | - World Music Africa and the Middle East (lossy)");
+            AddCategoryMapping(2085, TorznabCatType.Audio, " | - World Music Africa and the Middle East (lossless)");
+            AddCategoryMapping(1282, TorznabCatType.Audio, " | - Ethnic Music of the Caucasus and Transcaucasia (lossy and lossless ..");
+            AddCategoryMapping(1284, TorznabCatType.Audio, " | - World Music Americas (lossy)");
+            AddCategoryMapping(1285, TorznabCatType.Audio, " | - World Music Americas (lossless)");
+            AddCategoryMapping(1138, TorznabCatType.Audio, " | - World Music Australia, the Pacific and Indian oceans ..");
+            AddCategoryMapping(1136, TorznabCatType.Audio, " |- Country, Bluegrass (lossy)");
+            AddCategoryMapping(1137, TorznabCatType.Audio, " |- Country, Bluegrass (lossless)");
+            AddCategoryMapping(1141, TorznabCatType.Audio, " | - Folklore, Folk and World Music (Video)");
+            AddCategoryMapping(1142, TorznabCatType.Audio, " | - Folklore, Folk and World Music (DVD Video)");
+            AddCategoryMapping(2530, TorznabCatType.Audio, " | - Folklore, Folk and World Music (HD Video)");
+            AddCategoryMapping(506, TorznabCatType.Audio, " | - Folklore, Folk and World Music (own otsif ..");
+            AddCategoryMapping(1849, TorznabCatType.Audio, "New Age, Relax, Meditative & Flamenco");
+            AddCategoryMapping(1126, TorznabCatType.Audio, " |- NewAge & Meditative (lossy)");
+            AddCategoryMapping(1127, TorznabCatType.Audio, " |- NewAge & Meditative (lossless)");
+            AddCategoryMapping(1134, TorznabCatType.Audio, " | - Flamenco and acoustic guitar (lossy)");
+            AddCategoryMapping(1135, TorznabCatType.Audio, " | - Flamenco and acoustic guitar (lossless)");
+            AddCategoryMapping(2352, TorznabCatType.Audio, " |- New Age, Relax, Meditative & Flamenco (Видео)");
+            AddCategoryMapping(2351, TorznabCatType.Audio, " |- New Age, Relax, Meditative & Flamenco (DVD и HD Видео)");
+            AddCategoryMapping(855, TorznabCatType.Audio, " | - Sounds of Nature");
+            AddCategoryMapping(408, TorznabCatType.Audio, "Рэп, Хип-Хоп, R'n'B");
+            AddCategoryMapping(441, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop (lossy)");
+            AddCategoryMapping(1173, TorznabCatType.Audio, " |- Отечественный R'n'B (lossy)");
+            AddCategoryMapping(1486, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop, R'n'B (lossless)");
+            AddCategoryMapping(1172, TorznabCatType.Audio, " |- Зарубежный R'n'B (lossy)");
+            AddCategoryMapping(446, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (lossy)");
+            AddCategoryMapping(909, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (lossless)");
+            AddCategoryMapping(1665, TorznabCatType.Audio, " |- Зарубежный R'n'B (lossless)");
+            AddCategoryMapping(1835, TorznabCatType.Audio, " | - Rap, Hip-Hop, R'n'B (own digitization)");
+            AddCategoryMapping(1189, TorznabCatType.Audio, " | - Domestic Rap, Hip-Hop (Video)");
+            AddCategoryMapping(1455, TorznabCatType.Audio, " | - Domestic R'n'B (Video)");
+            AddCategoryMapping(442, TorznabCatType.Audio, " | - Foreign Rap, Hip-Hop (Video)");
+            AddCategoryMapping(1174, TorznabCatType.Audio, " | - Foreign R'n'B (Video)");
+            AddCategoryMapping(1107, TorznabCatType.Audio, " |- Рэп, Хип-Хоп, R'n'B (DVD Video)");
+            AddCategoryMapping(2529, TorznabCatType.Audio, " |- Рэп, Хип-Хоп, R'n'B (HD Видео)");
+            AddCategoryMapping(1760, TorznabCatType.Audio, "Reggae, Ska, Dub");
+            AddCategoryMapping(1764, TorznabCatType.Audio, " | - Rocksteady, Early Reggae, Ska-Jazz, Trad.Ska (lossy и lo ..");
+            AddCategoryMapping(1766, TorznabCatType.Audio, " |- Punky-Reggae, Rocksteady-Punk, Ska Revival (lossy)");
+            AddCategoryMapping(1767, TorznabCatType.Audio, " | - 3rd Wave Ska (lossy)");
+            AddCategoryMapping(1769, TorznabCatType.Audio, " | - Ska-Punk, Ska-Core (lossy)");
+            AddCategoryMapping(1765, TorznabCatType.Audio, " |- Reggae (lossy)");
+            AddCategoryMapping(1771, TorznabCatType.Audio, " |- Dub (lossy)");
+            AddCategoryMapping(1770, TorznabCatType.Audio, " |- Dancehall, Raggamuffin (lossy)");
+            AddCategoryMapping(1768, TorznabCatType.Audio, " |- Reggae, Dancehall, Dub (lossless)");
+            AddCategoryMapping(1774, TorznabCatType.Audio, " | - Ska Ska-Punk, Ska-Jazz (lossless)");
+            AddCategoryMapping(1772, TorznabCatType.Audio, " | - Domestic reggae, dub (lossy and lossless)");
+            AddCategoryMapping(1773, TorznabCatType.Audio, " | - Patriotic ska music (lossy and lossless)");
+            AddCategoryMapping(2233, TorznabCatType.Audio, " | - Reggae, Ska, Dub (компиляции) (lossy и lossless)");
+            AddCategoryMapping(2232, TorznabCatType.Audio, " | - Reggae, Ska, Dub (own digitization)");
+            AddCategoryMapping(1775, TorznabCatType.Audio, " | - Reggae, Ska, Dub (Видео)");
+            AddCategoryMapping(1777, TorznabCatType.Audio, " | - Reggae, Ska, Dub (DVD и HD Video)");
+            AddCategoryMapping(416, TorznabCatType.Audio, "Soundtracks and Karaoke");
+            AddCategoryMapping(782, TorznabCatType.Audio, " | - Karaoke (Audio)");
+            AddCategoryMapping(2377, TorznabCatType.Audio, " | - Karaoke (Video)");
+            AddCategoryMapping(468, TorznabCatType.Audio, " |- Минусовки (lossy и lossless)");
+            AddCategoryMapping(1625, TorznabCatType.Audio, " | - Soundtracks (own digitization)");
+            AddCategoryMapping(691, TorznabCatType.Audio, " | - Soundtracks for domestic films (lossless)");
+            AddCategoryMapping(469, TorznabCatType.Audio, " | - Soundtracks for domestic films (lossy)");
+            AddCategoryMapping(786, TorznabCatType.Audio, " | - Soundtracks for foreign films (lossless)");
+            AddCategoryMapping(785, TorznabCatType.Audio, " | - Soundtracks for foreign films (lossy)");
+            AddCategoryMapping(796, TorznabCatType.Audio, " | - Informal soundtracks for films and TV series (lossy)");
+            AddCategoryMapping(784, TorznabCatType.Audio, " | - Soundtracks for games (lossless)");
+            AddCategoryMapping(783, TorznabCatType.Audio, " | - Soundtracks for games (lossy)");
+            AddCategoryMapping(2331, TorznabCatType.Audio, " | - Informal soundtracks for games (lossy)");
+            AddCategoryMapping(2431, TorznabCatType.Audio, " | - The arrangements of music from the game (lossy and lossless)");
+            AddCategoryMapping(1397, TorznabCatType.Audio, " | - Hi-Res stereo and multi-channel music (Soundtracks)");
+            AddCategoryMapping(1215, TorznabCatType.Audio, "Chanson, Author and military songs");
+            AddCategoryMapping(1220, TorznabCatType.Audio, " | - The domestic chanson (lossless)");
+            AddCategoryMapping(1221, TorznabCatType.Audio, " | - The domestic chanson (lossy)");
+            AddCategoryMapping(1334, TorznabCatType.Audio, " | - Compilations domestic chanson (lossy)");
+            AddCategoryMapping(1216, TorznabCatType.Audio, " | - War Song (lossless)");
+            AddCategoryMapping(1223, TorznabCatType.Audio, " | - War Song (lossy)");
+            AddCategoryMapping(1224, TorznabCatType.Audio, " | - Chanson (lossless)");
+            AddCategoryMapping(1225, TorznabCatType.Audio, " | - Chanson (lossy)");
+            AddCategoryMapping(1226, TorznabCatType.Audio, " |- Менестрели и ролевики (lossy и lossless)");
+            AddCategoryMapping(1217, TorznabCatType.Audio, " | - In-house digitizing (Chanson, and Bards) lossles ..");
+            AddCategoryMapping(1227, TorznabCatType.Audio, " | - Video (Chanson, and Bards)");
+            AddCategoryMapping(1228, TorznabCatType.Audio, " | - DVD Video (Chanson, and Bards)");
+            AddCategoryMapping(413, TorznabCatType.Audio, "Music of other genres");
+            AddCategoryMapping(974, TorznabCatType.Audio, " | - In-house digitizing (Music from other genres)");
+            AddCategoryMapping(463, TorznabCatType.Audio, " | - Patriotic music of other genres (lossy)");
+            AddCategoryMapping(464, TorznabCatType.Audio, " | - Patriotic music of other genres (lossless)");
+            AddCategoryMapping(466, TorznabCatType.Audio, " | - International music of other genres (lossy)");
+            AddCategoryMapping(465, TorznabCatType.Audio, " | - International music of other genres (lossless)");
+            AddCategoryMapping(2018, TorznabCatType.Audio, " | - Music for ballroom dancing (lossy and lossless)");
+            AddCategoryMapping(1396, TorznabCatType.Audio, " | - Orthodox chants (lossy)");
+            AddCategoryMapping(1395, TorznabCatType.Audio, " | - Orthodox chants (lossless)");
+            AddCategoryMapping(1351, TorznabCatType.Audio, " | - A collection of songs for children (lossy and lossless)");
+            AddCategoryMapping(475, TorznabCatType.Audio, " | - Video (Music from other genres)");
+            AddCategoryMapping(988, TorznabCatType.Audio, " | - DVD Video (Music from other genres)");
+            AddCategoryMapping(880, TorznabCatType.Audio, " | - The Musical (lossy and lossless)");
+            AddCategoryMapping(655, TorznabCatType.Audio, " | - The Musical (Video and DVD Video)");
+            AddCategoryMapping(965, TorznabCatType.Audio, " | - Informal and vnezhanrovye collections (lossy)");
+            AddCategoryMapping(919, TorznabCatType.Audio, "Sheet Music literature");
+            AddCategoryMapping(944, TorznabCatType.Audio, " | - Academic Music (Notes and Media CD)");
+            AddCategoryMapping(980, TorznabCatType.Audio, " | - Other destinations (notes, tablature)");
+            AddCategoryMapping(946, TorznabCatType.Audio, " | - Tutorials and Schools");
+            AddCategoryMapping(977, TorznabCatType.Audio, " | - Songbooks (Songbooks)");
+            AddCategoryMapping(2074, TorznabCatType.Audio, " | - Music Literature and Theory");
+            AddCategoryMapping(2349, TorznabCatType.Audio, " | - Music Magazines");
+
+            // Популярная музыка
+            AddCategoryMapping(2495, TorznabCatType.Audio, "Domestic Pop");
+            AddCategoryMapping(424, TorznabCatType.Audio, " | - Patriotic Pop (lossy)");
+            AddCategoryMapping(1361, TorznabCatType.Audio, " | - Patriotic Pop music (collections) (lossy)");
+            AddCategoryMapping(425, TorznabCatType.Audio, " | - Patriotic Pop (lossless)");
+            AddCategoryMapping(1635, TorznabCatType.Audio, " | - Soviet pop music, retro (lossy)");
+            AddCategoryMapping(1634, TorznabCatType.Audio, " | - Soviet pop music, retro (lossless)");
+            AddCategoryMapping(2497, TorznabCatType.Audio, "Foreign pop music");
+            AddCategoryMapping(428, TorznabCatType.Audio, " | - Foreign pop music (lossy)");
+            AddCategoryMapping(1362, TorznabCatType.Audio, " | - Foreign pop music (collections) (lossy)");
+            AddCategoryMapping(429, TorznabCatType.Audio, " | - International Pop (lossless)");
+            AddCategoryMapping(1219, TorznabCatType.Audio, " | - Foreign chanson (lossy)");
+            AddCategoryMapping(1452, TorznabCatType.Audio, " | - Foreign chanson (lossless)");
+            AddCategoryMapping(1331, TorznabCatType.Audio, " | - East Asian pop music (lossy)");
+            AddCategoryMapping(1330, TorznabCatType.Audio, " | - East Asian Pop (lossless)");
+            AddCategoryMapping(2499, TorznabCatType.Audio, "Eurodance, Disco, Hi-NRG");
+            AddCategoryMapping(2503, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (lossy)");
+            AddCategoryMapping(2504, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (сборники) (lossy)");
+            AddCategoryMapping(2502, TorznabCatType.Audio, " |- Eurodance, Euro-House, Technopop (lossless)");
+            AddCategoryMapping(2501, TorznabCatType.Audio, " |- Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossy)");
+            AddCategoryMapping(2505, TorznabCatType.Audio, " | - Disco, Italo-Disco, Euro-Disco, Hi-NRG (сборники) (lossy ..");
+            AddCategoryMapping(2500, TorznabCatType.Audio, " |- Disco, Italo-Disco, Euro-Disco, Hi-NRG (lossless)");
+            AddCategoryMapping(2507, TorznabCatType.Audio, "Видео, DVD Video, HD Video (поп-музыка)");
+            AddCategoryMapping(1121, TorznabCatType.Audio, " | - Patriotic Pop (Video)");
+            AddCategoryMapping(1122, TorznabCatType.Audio, " | - Patriotic Pop (DVD Video)");
+            AddCategoryMapping(2510, TorznabCatType.Audio, " | - Soviet pop music, retro (video)");
+            AddCategoryMapping(2509, TorznabCatType.Audio, " | - Soviet pop music, retro (DVD Video)");
+            AddCategoryMapping(431, TorznabCatType.Audio, " | - Foreign pop music (Video)");
+            AddCategoryMapping(986, TorznabCatType.Audio, " | - Foreign pop music (DVD Video)");
+            AddCategoryMapping(2532, TorznabCatType.Audio, " |- Eurodance, Disco (видео)");
+            AddCategoryMapping(2531, TorznabCatType.Audio, " |- Eurodance, Disco (DVD Video)");
+            AddCategoryMapping(2378, TorznabCatType.Audio, " | - East Asian pop music (Video)");
+            AddCategoryMapping(2379, TorznabCatType.Audio, " | - East Asian pop music (DVD Video)");
+            AddCategoryMapping(2383, TorznabCatType.Audio, " | - Foreign chanson (Video)");
+            AddCategoryMapping(2384, TorznabCatType.Audio, " | - Foreign chanson (DVD Video)");
+            AddCategoryMapping(2088, TorznabCatType.Audio, " | - Patriotic Pop (National concerts, video dock.) ..");
+            AddCategoryMapping(2089, TorznabCatType.Audio, " | - Foreign pop music (National concerts, video dock.) (Bu ..");
+            AddCategoryMapping(2426, TorznabCatType.Audio, " | - Patriotic Pop Music, Chanson, Eurodance, Disco (HD V ..");
+            AddCategoryMapping(2508, TorznabCatType.Audio, " | - International Pop Music, Chanson, Eurodance, Disco (HD Vide ..");
+            AddCategoryMapping(2512, TorznabCatType.Audio, "The multi-channel music and own digitization (pop music)");
+            AddCategoryMapping(1444, TorznabCatType.Audio, " | - Foreign pop music (own digitization)");
+            AddCategoryMapping(1785, TorznabCatType.Audio, " | - Eastern pop music (own digitization)");
+            AddCategoryMapping(239, TorznabCatType.Audio, " | - Patriotic Pop (own digitization)");
+            AddCategoryMapping(450, TorznabCatType.Audio, " | - Instrumental Pop (own digitization)");
+            AddCategoryMapping(1163, TorznabCatType.Audio, " | - Multi-channel music (pop music)");
+            AddCategoryMapping(1885, TorznabCatType.Audio, " |- Hi-Res stereo (Поп-музыка)");
+
+            // Джазовая и Блюзовая музыка
+            AddCategoryMapping(2267, TorznabCatType.Audio, "foreign jazz");
+            AddCategoryMapping(2277, TorznabCatType.Audio, " |- Early Jazz, Swing, Gypsy (lossless)");
+            AddCategoryMapping(2278, TorznabCatType.Audio, " |- Bop (lossless)");
+            AddCategoryMapping(2279, TorznabCatType.Audio, " |- Mainstream Jazz, Cool (lossless)");
+            AddCategoryMapping(2280, TorznabCatType.Audio, " |- Jazz Fusion (lossless)");
+            AddCategoryMapping(2281, TorznabCatType.Audio, " |- World Fusion, Ethnic Jazz (lossless)");
+            AddCategoryMapping(2282, TorznabCatType.Audio, " |- Avant-Garde Jazz, Free Improvisation (lossless)");
+            AddCategoryMapping(2353, TorznabCatType.Audio, " |- Modern Creative, Third Stream (lossless)");
+            AddCategoryMapping(2284, TorznabCatType.Audio, " |- Smooth, Jazz-Pop (lossless)");
+            AddCategoryMapping(2285, TorznabCatType.Audio, " |- Vocal Jazz (lossless)");
+            AddCategoryMapping(2283, TorznabCatType.Audio, " |- Funk, Soul, R&B (lossless)");
+            AddCategoryMapping(2286, TorznabCatType.Audio, " | - Compilations foreign jazz (lossless)");
+            AddCategoryMapping(2287, TorznabCatType.Audio, " | - Foreign jazz (lossy)");
+            AddCategoryMapping(2268, TorznabCatType.Audio, "foreign blues");
+            AddCategoryMapping(2293, TorznabCatType.Audio, " |- Blues (Texas, Chicago, Modern and Others) (lossless)");
+            AddCategoryMapping(2292, TorznabCatType.Audio, " |- Blues-rock (lossless)");
+            AddCategoryMapping(2290, TorznabCatType.Audio, " |- Roots, Pre-War Blues, Early R&B, Gospel (lossless)");
+            AddCategoryMapping(2289, TorznabCatType.Audio, " | - Foreign blues (collections; Tribute VA) (lossless)");
+            AddCategoryMapping(2288, TorznabCatType.Audio, " | - Foreign blues (lossy)");
+            AddCategoryMapping(2269, TorznabCatType.Audio, "Domestic jazz and blues");
+            AddCategoryMapping(2297, TorznabCatType.Audio, " | - Domestic Jazz (lossless)");
+            AddCategoryMapping(2295, TorznabCatType.Audio, " | - Domestic jazz (lossy)");
+            AddCategoryMapping(2296, TorznabCatType.Audio, " | - Domestic Blues (lossless)");
+            AddCategoryMapping(2298, TorznabCatType.Audio, " | - Domestic Blues (lossy)");
+            AddCategoryMapping(2270, TorznabCatType.Audio, "The multi-channel music and own digitization (Jazz and Blues)");
+            AddCategoryMapping(2303, TorznabCatType.Audio, " | - Multi-channel music (Jazz and Blues)");
+            AddCategoryMapping(2302, TorznabCatType.Audio, " | - Hi-Res stereo (Jazz and Blues)");
+            AddCategoryMapping(2301, TorznabCatType.Audio, " | - In-house digitizing (Jazz and Blues)");
+            AddCategoryMapping(2271, TorznabCatType.Audio, "Video, DVD Video, HD Video (Jazz and Blues)");
+            AddCategoryMapping(2305, TorznabCatType.Audio, " | - Jazz and Blues (Video)");
+            AddCategoryMapping(2304, TorznabCatType.Audio, " | - Jazz and Blues (DVD Video)");
+            AddCategoryMapping(2306, TorznabCatType.Audio, " | - Jazz and Blues (HD Video)");
+
+            // Рок-музыка
+            AddCategoryMapping(1698, TorznabCatType.Audio, "foreign Rock");
+            AddCategoryMapping(1702, TorznabCatType.Audio, " |- Classic Rock & Hard Rock (lossless)");
+            AddCategoryMapping(1703, TorznabCatType.Audio, " |- Classic Rock & Hard Rock (lossy)");
+            AddCategoryMapping(1704, TorznabCatType.Audio, " |- Progressive & Art-Rock (lossless)");
+            AddCategoryMapping(1705, TorznabCatType.Audio, " |- Progressive & Art-Rock (lossy)");
+            AddCategoryMapping(1706, TorznabCatType.Audio, " |- Folk-Rock (lossless)");
+            AddCategoryMapping(1707, TorznabCatType.Audio, " |- Folk-Rock (lossy)");
+            AddCategoryMapping(2329, TorznabCatType.Audio, " |- AOR (Melodic Hard Rock, Arena rock) (lossless)");
+            AddCategoryMapping(2330, TorznabCatType.Audio, " |- AOR (Melodic Hard Rock, Arena rock) (lossy)");
+            AddCategoryMapping(1708, TorznabCatType.Audio, " |- Pop-Rock & Soft Rock (lossless)");
+            AddCategoryMapping(1709, TorznabCatType.Audio, " |- Pop-Rock & Soft Rock (lossy)");
+            AddCategoryMapping(1710, TorznabCatType.Audio, " |- Instrumental Guitar Rock (lossless)");
+            AddCategoryMapping(1711, TorznabCatType.Audio, " |- Instrumental Guitar Rock (lossy)");
+            AddCategoryMapping(1712, TorznabCatType.Audio, " |- Rockabilly, Psychobilly, Rock'n'Roll (lossless)");
+            AddCategoryMapping(1713, TorznabCatType.Audio, " |- Rockabilly, Psychobilly, Rock'n'Roll (lossy)");
+            AddCategoryMapping(731, TorznabCatType.Audio, " | - Compilations foreign rock (lossless)");
+            AddCategoryMapping(1799, TorznabCatType.Audio, " | - Compilations foreign rock (lossy)");
+            AddCategoryMapping(1714, TorznabCatType.Audio, " | - East Asian Rock (lossless)");
+            AddCategoryMapping(1715, TorznabCatType.Audio, " | - East Asian rock (lossy)");
+            AddCategoryMapping(1716, TorznabCatType.Audio, "foreign Metal");
+            AddCategoryMapping(1796, TorznabCatType.Audio, " |- Avant-garde, Experimental Metal (lossless)");
+            AddCategoryMapping(1797, TorznabCatType.Audio, " |- Avant-garde, Experimental Metal (lossy)");
+            AddCategoryMapping(1719, TorznabCatType.Audio, " |- Black (lossless)");
+            AddCategoryMapping(1778, TorznabCatType.Audio, " |- Black (lossy)");
+            AddCategoryMapping(1779, TorznabCatType.Audio, " |- Death, Doom (lossless)");
+            AddCategoryMapping(1780, TorznabCatType.Audio, " |- Death, Doom (lossy)");
+            AddCategoryMapping(1720, TorznabCatType.Audio, " |- Folk, Pagan, Viking (lossless)");
+            AddCategoryMapping(798, TorznabCatType.Audio, " |- Folk, Pagan, Viking (lossy)");
+            AddCategoryMapping(1724, TorznabCatType.Audio, " |- Gothic Metal (lossless)");
+            AddCategoryMapping(1725, TorznabCatType.Audio, " |- Gothic Metal (lossy)");
+            AddCategoryMapping(1730, TorznabCatType.Audio, " |- Grind, Brutal Death (lossless)");
+            AddCategoryMapping(1731, TorznabCatType.Audio, " |- Grind, Brutal Death (lossy)");
+            AddCategoryMapping(1726, TorznabCatType.Audio, " |- Heavy, Power, Progressive (lossless)");
+            AddCategoryMapping(1727, TorznabCatType.Audio, " |- Heavy, Power, Progressive (lossy)");
+            AddCategoryMapping(1815, TorznabCatType.Audio, " |- Sludge, Stoner, Post-Metal (lossless)");
+            AddCategoryMapping(1816, TorznabCatType.Audio, " |- Sludge, Stoner, Post-Metal (lossy)");
+            AddCategoryMapping(1728, TorznabCatType.Audio, " |- Thrash, Speed (lossless)");
+            AddCategoryMapping(1729, TorznabCatType.Audio, " |- Thrash, Speed (lossy)");
+            AddCategoryMapping(2230, TorznabCatType.Audio, " | - Compilations (lossless)");
+            AddCategoryMapping(2231, TorznabCatType.Audio, " | - Compilations (lossy)");
+            AddCategoryMapping(1732, TorznabCatType.Audio, "Foreign Alternative, Punk, Independent");
+            AddCategoryMapping(1736, TorznabCatType.Audio, " |- Alternative & Nu-metal (lossless)");
+            AddCategoryMapping(1737, TorznabCatType.Audio, " |- Alternative & Nu-metal (lossy)");
+            AddCategoryMapping(1738, TorznabCatType.Audio, " |- Punk (lossless)");
+            AddCategoryMapping(1739, TorznabCatType.Audio, " |- Punk (lossy)");
+            AddCategoryMapping(1740, TorznabCatType.Audio, " |- Hardcore (lossless)");
+            AddCategoryMapping(1741, TorznabCatType.Audio, " |- Hardcore (lossy)");
+            AddCategoryMapping(1742, TorznabCatType.Audio, " |- Indie, Post-Rock & Post-Punk (lossless)");
+            AddCategoryMapping(1743, TorznabCatType.Audio, " |- Indie, Post-Rock & Post-Punk (lossy)");
+            AddCategoryMapping(1744, TorznabCatType.Audio, " |- Industrial & Post-industrial (lossless)");
+            AddCategoryMapping(1745, TorznabCatType.Audio, " |- Industrial & Post-industrial (lossy)");
+            AddCategoryMapping(1746, TorznabCatType.Audio, " |- Emocore, Post-hardcore, Metalcore (lossless)");
+            AddCategoryMapping(1747, TorznabCatType.Audio, " |- Emocore, Post-hardcore, Metalcore (lossy)");
+            AddCategoryMapping(1748, TorznabCatType.Audio, " |- Gothic Rock & Dark Folk (lossless)");
+            AddCategoryMapping(1749, TorznabCatType.Audio, " |- Gothic Rock & Dark Folk (lossy)");
+            AddCategoryMapping(2175, TorznabCatType.Audio, " |- Avant-garde, Experimental Rock (lossless)");
+            AddCategoryMapping(2174, TorznabCatType.Audio, " |- Avant-garde, Experimental Rock (lossy)");
+            AddCategoryMapping(722, TorznabCatType.Audio, "Domestic Rock");
+            AddCategoryMapping(737, TorznabCatType.Audio, " | - Rock, Punk, Alternative (lossless)");
+            AddCategoryMapping(738, TorznabCatType.Audio, " | - Rock, Punk, Alternative (lossy)");
+            AddCategoryMapping(739, TorznabCatType.Audio, " |- Металл (lossless)");
+            AddCategoryMapping(740, TorznabCatType.Audio, " |- Металл (lossy)");
+            AddCategoryMapping(951, TorznabCatType.Audio, " | - Rock in the languages &#8203;&#8203;of xUSSR (lossless)");
+            AddCategoryMapping(952, TorznabCatType.Audio, " | - Rock in the languages &#8203;&#8203;of xUSSR (lossy)");
+            AddCategoryMapping(1752, TorznabCatType.Audio, "The multi-channel music and own digitization (Rock)");
+            AddCategoryMapping(1756, TorznabCatType.Audio, " | - Foreign rock (own digitization)");
+            AddCategoryMapping(1758, TorznabCatType.Audio, " | - Domestic Rock (own digitization)");
+            AddCategoryMapping(1757, TorznabCatType.Audio, " | - Multi-channel music (rock)");
+            AddCategoryMapping(1755, TorznabCatType.Audio, " |- Hi-Res stereo (рок)");
+            AddCategoryMapping(453, TorznabCatType.Audio, " | - Conversions Quadraphonic (multichannel music)");
+            AddCategoryMapping(1170, TorznabCatType.Audio, " | - Conversions SACD (multi-channel music)");
+            AddCategoryMapping(1759, TorznabCatType.Audio, " | - Conversions from the Blu-Ray (multichannel music)");
+            AddCategoryMapping(1852, TorznabCatType.Audio, " |- Апмиксы-Upmixes/Даунмиксы-Downmix (многоканальная и Hi-R..");
+            AddCategoryMapping(1781, TorznabCatType.Audio, "Видео, DVD Video, HD Video (Рок-музыка)");
+            AddCategoryMapping(1782, TorznabCatType.Audio, " |- Rock (Видео)");
+            AddCategoryMapping(1783, TorznabCatType.Audio, " |- Rock (DVD Video)");
+            AddCategoryMapping(2261, TorznabCatType.Audio, " | - Rock (Unofficial DVD Video)");
+            AddCategoryMapping(1787, TorznabCatType.Audio, " |- Metal (Видео)");
+            AddCategoryMapping(1788, TorznabCatType.Audio, " |- Metal (DVD Video)");
+            AddCategoryMapping(2262, TorznabCatType.Audio, " | - Metal (Unofficial DVD Video)");
+            AddCategoryMapping(1789, TorznabCatType.Audio, " |- Alternative, Punk, Independent (Видео)");
+            AddCategoryMapping(1790, TorznabCatType.Audio, " |- Alternative, Punk, Independent (DVD Video)");
+            AddCategoryMapping(2263, TorznabCatType.Audio, " |- Alternative, Punk, Independent (Неофициальные DVD Video)");
+            AddCategoryMapping(1791, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative (Video)");
+            AddCategoryMapping(1792, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative (DVD Video)");
+            AddCategoryMapping(1793, TorznabCatType.Audio, " | - Domestic Metal (Video)");
+            AddCategoryMapping(1794, TorznabCatType.Audio, " | - Domestic Metal (DVD Video)");
+            AddCategoryMapping(2264, TorznabCatType.Audio, " | - Domestic Rock, Punk, Alternative, Metal (Neofitsial ..");
+            AddCategoryMapping(1795, TorznabCatType.Audio, " | - Rock (HD Video)");
+
+            // Электронная музыка
+            AddCategoryMapping(1821, TorznabCatType.Audio, "Trance, Goa Trance, Psy-Trance, PsyChill, Ambient, Dub");
+            AddCategoryMapping(1844, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance (lossless)");
+            AddCategoryMapping(1822, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance (lossy)");
+            AddCategoryMapping(1894, TorznabCatType.Audio, " |- PsyChill, Ambient, Dub (lossless)");
+            AddCategoryMapping(1895, TorznabCatType.Audio, " |- PsyChill, Ambient, Dub (lossy)");
+            AddCategoryMapping(460, TorznabCatType.Audio, " |- Goa Trance, Psy-Trance, PsyChill, Ambient, Dub (Live Set..");
+            AddCategoryMapping(1818, TorznabCatType.Audio, " |- Trance (lossless)");
+            AddCategoryMapping(1819, TorznabCatType.Audio, " |- Trance (lossy)");
+            AddCategoryMapping(1847, TorznabCatType.Audio, " |- Trance (Singles, EPs) (lossy)");
+            AddCategoryMapping(1824, TorznabCatType.Audio, " |- Trance (Radioshows, Podcasts, Live Sets, Mixes) (lossy)");
+            AddCategoryMapping(1807, TorznabCatType.Audio, "House, Techno, Hardcore, Hardstyle, Jumpstyle");
+            AddCategoryMapping(1829, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (lossless)");
+            AddCategoryMapping(1830, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (lossy)");
+            AddCategoryMapping(1831, TorznabCatType.Audio, " |- Hardcore, Hardstyle, Jumpstyle (vinyl, web)");
+            AddCategoryMapping(1857, TorznabCatType.Audio, " |- House (lossless)");
+            AddCategoryMapping(1859, TorznabCatType.Audio, " |- House (Radioshow, Podcast, Liveset, Mixes)");
+            AddCategoryMapping(1858, TorznabCatType.Audio, " |- House (lossy)");
+            AddCategoryMapping(840, TorznabCatType.Audio, " | - House (Promorelyzы, collections of)");
+            AddCategoryMapping(1860, TorznabCatType.Audio, " |- House (Singles, EPs) (lossy)");
+            AddCategoryMapping(1825, TorznabCatType.Audio, " |- Techno (lossless)");
+            AddCategoryMapping(1826, TorznabCatType.Audio, " |- Techno (lossy)");
+            AddCategoryMapping(1827, TorznabCatType.Audio, " |- Techno (Radioshows, Podcasts, Livesets, Mixes)");
+            AddCategoryMapping(1828, TorznabCatType.Audio, " |- Techno (Singles, EPs) (lossy)");
+            AddCategoryMapping(1808, TorznabCatType.Audio, "Drum & Bass, Jungle, Breakbeat, Dubstep, IDM, Electro");
+            AddCategoryMapping(797, TorznabCatType.Audio, " |- Electro, Electro-Freestyle, Nu Electro (lossless)");
+            AddCategoryMapping(1805, TorznabCatType.Audio, " |- Electro, Electro-Freestyle, Nu Electro (lossy)");
+            AddCategoryMapping(1832, TorznabCatType.Audio, " |- Drum & Bass, Jungle (lossless)");
+            AddCategoryMapping(1833, TorznabCatType.Audio, " |- Drum & Bass, Jungle (lossy)");
+            AddCategoryMapping(1834, TorznabCatType.Audio, " |- Drum & Bass, Jungle (Radioshows, Podcasts, Livesets, Mix..");
+            AddCategoryMapping(1836, TorznabCatType.Audio, " |- Breakbeat (lossless)");
+            AddCategoryMapping(1837, TorznabCatType.Audio, " |- Breakbeat (lossy)");
+            AddCategoryMapping(1839, TorznabCatType.Audio, " |- Dubstep (lossless)");
+            AddCategoryMapping(454, TorznabCatType.Audio, " |- Dubstep (lossy)");
+            AddCategoryMapping(1838, TorznabCatType.Audio, " |- Breakbeat, Dubstep (Radioshows, Podcasts, Livesets, Mixe..");
+            AddCategoryMapping(1840, TorznabCatType.Audio, " |- IDM (lossless)");
+            AddCategoryMapping(1841, TorznabCatType.Audio, " |- IDM (lossy)");
+            AddCategoryMapping(2229, TorznabCatType.Audio, " |- IDM Discography & Collections (lossy)");
+            AddCategoryMapping(1809, TorznabCatType.Audio, "Chillout, Lounge, Downtempo, Trip-Hop");
+            AddCategoryMapping(1861, TorznabCatType.Audio, " |- Chillout, Lounge, Downtempo (lossless)");
+            AddCategoryMapping(1862, TorznabCatType.Audio, " |- Chillout, Lounge, Downtempo (lossy)");
+            AddCategoryMapping(1947, TorznabCatType.Audio, " |- Nu Jazz, Acid Jazz, Future Jazz (lossless)");
+            AddCategoryMapping(1946, TorznabCatType.Audio, " |- Nu Jazz, Acid Jazz, Future Jazz (lossy)");
+            AddCategoryMapping(1945, TorznabCatType.Audio, " |- Trip Hop, Abstract Hip-Hop (lossless)");
+            AddCategoryMapping(1944, TorznabCatType.Audio, " |- Trip Hop, Abstract Hip-Hop (lossy)");
+            AddCategoryMapping(1810, TorznabCatType.Audio, "Traditional Electronic, Ambient, Modern Classical, Electroac..");
+            AddCategoryMapping(1864, TorznabCatType.Audio, " |- Traditional Electronic, Ambient (lossless)");
+            AddCategoryMapping(1865, TorznabCatType.Audio, " |- Traditional Electronic, Ambient (lossy)");
+            AddCategoryMapping(1871, TorznabCatType.Audio, " |- Modern Classical, Electroacoustic (lossless)");
+            AddCategoryMapping(1867, TorznabCatType.Audio, " |- Modern Classical, Electroacoustic (lossy)");
+            AddCategoryMapping(1869, TorznabCatType.Audio, " |- Experimental (lossless)");
+            AddCategoryMapping(1873, TorznabCatType.Audio, " |- Experimental (lossy)");
+            AddCategoryMapping(1907, TorznabCatType.Audio, " |- 8-bit, Chiptune (lossy & lossless)");
+            AddCategoryMapping(1811, TorznabCatType.Audio, "Industrial, Noise, EBM, Dark Electro, Aggrotech, Synthpop, N..");
+            AddCategoryMapping(1868, TorznabCatType.Audio, " | - EBM, Dark Electro, Aggrotech (lossless)");
+            AddCategoryMapping(1875, TorznabCatType.Audio, " | - EBM, Dark Electro, Aggrotech (lossy)");
+            AddCategoryMapping(1877, TorznabCatType.Audio, " |- Industrial, Noise (lossless)");
+            AddCategoryMapping(1878, TorznabCatType.Audio, " |- Industrial, Noise (lossy)");
+            AddCategoryMapping(1880, TorznabCatType.Audio, " |- Synthpop, New Wave (lossless)");
+            AddCategoryMapping(1881, TorznabCatType.Audio, " |- Synthpop, New Wave (lossy)");
+            AddCategoryMapping(1866, TorznabCatType.Audio, " |- Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossles..");
+            AddCategoryMapping(406, TorznabCatType.Audio, " |- Darkwave, Neoclassical, Ethereal, Dungeon Synth (lossy)");
+            AddCategoryMapping(1842, TorznabCatType.Audio, "Label Packs (lossless)");
+            AddCategoryMapping(1648, TorznabCatType.Audio, "Label packs, Scene packs (lossy)");
+            AddCategoryMapping(1812, TorznabCatType.Audio, "Электронная музыка (Видео, DVD Video/Audio, HD Video, DTS, S..");
+            AddCategoryMapping(1886, TorznabCatType.Audio, " | - Electronic music (Official DVD Video)");
+            AddCategoryMapping(1887, TorznabCatType.Audio, " | - Electronic music (Informal amateur DVD Vide ..");
+            AddCategoryMapping(1912, TorznabCatType.Audio, " | - Electronic music (Video)");
+            AddCategoryMapping(1893, TorznabCatType.Audio, " | - Hi-Res stereo (electronic music)");
+            AddCategoryMapping(1890, TorznabCatType.Audio, " | - Multi-channel music (electronic music)");
+            AddCategoryMapping(1913, TorznabCatType.Audio, " | - Electronic music (HD Video)");
+            AddCategoryMapping(1754, TorznabCatType.Audio, " | - Electronic music (own digitization)");
+
+            // Игры
+            AddCategoryMapping(5, TorznabCatType.PCGames, "Games for Windows (download)");
+            AddCategoryMapping(635, TorznabCatType.PCGames, " | - Hot New Releases");
+            AddCategoryMapping(127, TorznabCatType.PCGames, " | - Arcade");
+            AddCategoryMapping(2204, TorznabCatType.PCGames, " | - Puzzle Games");
+            AddCategoryMapping(53, TorznabCatType.PCGames, " | - Adventure and quests");
+            AddCategoryMapping(1008, TorznabCatType.PCGames, " | - Quest-style \"search objects\"");
+            AddCategoryMapping(51, TorznabCatType.PCGames, " | - Strategy");
+            AddCategoryMapping(961, TorznabCatType.PCGames, " | - Space and flight simulators");
+            AddCategoryMapping(962, TorznabCatType.PCGames, " | - Autos and Racing");
+            AddCategoryMapping(2187, TorznabCatType.PCGames, " | - Racing Simulators");
+            AddCategoryMapping(54, TorznabCatType.PCGames, " | - Other simulators");
+            AddCategoryMapping(55, TorznabCatType.PCGames, " |- Action");
+            AddCategoryMapping(2203, TorznabCatType.PCGames, " | - Fighting");
+            AddCategoryMapping(52, TorznabCatType.PCGames, " |- RPG");
+            AddCategoryMapping(900, TorznabCatType.PCGames, " | - Anime games");
+            AddCategoryMapping(246, TorznabCatType.PCGames, " | - Erotic Games");
+            AddCategoryMapping(278, TorznabCatType.PCGames, " | - Chess");
+            AddCategoryMapping(128, TorznabCatType.PCGames, " | - For the little ones");
+            AddCategoryMapping(637, TorznabCatType.PCGames, "Old Games");
+            AddCategoryMapping(642, TorznabCatType.PCGames, " | - Arcade (Old Games)");
+            AddCategoryMapping(2385, TorznabCatType.PCGames, " | - Puzzle games (old games)");
+            AddCategoryMapping(643, TorznabCatType.PCGames, " | - Adventure and quests (Old Games)");
+            AddCategoryMapping(644, TorznabCatType.PCGames, " | - Strategies (Old Games)");
+            AddCategoryMapping(2226, TorznabCatType.PCGames, " | - Space and flight simulators (Old Games)");
+            AddCategoryMapping(2227, TorznabCatType.PCGames, " | - Autos and Racing (Old Games)");
+            AddCategoryMapping(2225, TorznabCatType.PCGames, " | - Racing Simulators (Old Games)");
+            AddCategoryMapping(645, TorznabCatType.PCGames, " | - Other simulators (Old Games)");
+            AddCategoryMapping(646, TorznabCatType.PCGames, " | - Action (Old Games)");
+            AddCategoryMapping(647, TorznabCatType.PCGames, " | - RPG (Old Games)");
+            AddCategoryMapping(649, TorznabCatType.PCGames, " | - Erotic Games (Old Games)");
+            AddCategoryMapping(650, TorznabCatType.PCGames, " | - For the little ones (Old Games)");
+            AddCategoryMapping(1098, TorznabCatType.PCGames, " | - Game Collection (Old Games)");
+            AddCategoryMapping(2228, TorznabCatType.PCGames, " | - IBM PC incompatible (Old Games)");
+            AddCategoryMapping(2115, TorznabCatType.PCGames, "Online Games");
+            AddCategoryMapping(2117, TorznabCatType.PCGames, " |- World of Warcraft");
+            AddCategoryMapping(2155, TorznabCatType.PCGames, " |- Lineage II");
+            AddCategoryMapping(2118, TorznabCatType.PCGames, " | - MMO (Official)");
+            AddCategoryMapping(2119, TorznabCatType.PCGames, " | - MMO (Neoficialʹnye)");
+            AddCategoryMapping(2489, TorznabCatType.PCGames, " | - Multiplayer games");
+            AddCategoryMapping(2142, TorznabCatType.PCGames, "Microsoft Flight Simulator add-ons, and for him");
+            AddCategoryMapping(2143, TorznabCatType.PCGames, " | - Scripts, meshes and airports [FS2004]");
+            AddCategoryMapping(2060, TorznabCatType.PCGames, " |- Сценарии (FSX-P3D)");
+            AddCategoryMapping(2145, TorznabCatType.PCGames, " | - Aircraft [FS2004]");
+            AddCategoryMapping(2012, TorznabCatType.PCGames, " | - Planes, helicopters (FSX-P3D)");
+            AddCategoryMapping(2146, TorznabCatType.PCGames, " | - Mission, traffic sounds, packs and tools");
+            AddCategoryMapping(139, TorznabCatType.PCGames, "Others for Windows-based games");
+            AddCategoryMapping(2478, TorznabCatType.PCGames, " | - Official patches");
+            AddCategoryMapping(2479, TorznabCatType.PCGames, " | - Official Fashion, plug-ins, add-ons");
+            AddCategoryMapping(2480, TorznabCatType.PCGames, " | - Informal fashion, plugins, add-ons");
+            AddCategoryMapping(2481, TorznabCatType.PCGames, " | - Fun");
+            AddCategoryMapping(761, TorznabCatType.PCGames, " | - Editors, emulators and other gaming utility");
+            AddCategoryMapping(2482, TorznabCatType.PCGames, " |- NoCD / NoDVD");
+            AddCategoryMapping(2533, TorznabCatType.PCGames, " | - Conservation games");
+            AddCategoryMapping(2483, TorznabCatType.PCGames, " | - Cheat program and trainers");
+            AddCategoryMapping(2484, TorznabCatType.PCGames, " | - Guides and passing");
+            AddCategoryMapping(2485, TorznabCatType.PCGames, " | - The bonus discs for games");
+            AddCategoryMapping(240, TorznabCatType.PCGames, "video Game");
+            AddCategoryMapping(2415, TorznabCatType.PCGames, " | - Walkthroughs");
+            AddCategoryMapping(2067, TorznabCatType.PCGames, " |- Lineage II Movies");
+            AddCategoryMapping(2147, TorznabCatType.PCGames, " |- World of Warcraft Movies");
+            AddCategoryMapping(960, TorznabCatType.PCGames, " |- Counter Strike Movies");
+            AddCategoryMapping(548, TorznabCatType.Console, "Games for consoles");
+            AddCategoryMapping(129, TorznabCatType.Console, " | - Portable and Console (Games)");
+            AddCategoryMapping(908, TorznabCatType.ConsolePS3, " |- PS");
+            AddCategoryMapping(357, TorznabCatType.ConsolePS3, " |- PS2");
+            AddCategoryMapping(886, TorznabCatType.ConsolePS3, " |- PS3");
+            AddCategoryMapping(1352, TorznabCatType.ConsolePSP, " |- PSP");
+            AddCategoryMapping(1116, TorznabCatType.ConsolePSP, " | - PS1 games for PSP");
+            AddCategoryMapping(973, TorznabCatType.ConsolePSVita, " |- PSVITA");
+            AddCategoryMapping(887, TorznabCatType.ConsoleXbox, " | - Original Xbox");
+            AddCategoryMapping(510, TorznabCatType.ConsoleXbox360, " |- Xbox 360");
+            AddCategoryMapping(773, TorznabCatType.ConsoleWii, " |- Wii");
+            AddCategoryMapping(774, TorznabCatType.ConsoleNDS, " |- NDS");
+            AddCategoryMapping(968, TorznabCatType.ConsoleOther, " |- Dreamcast");
+            AddCategoryMapping(546, TorznabCatType.ConsoleOther, " | - Games for the DVD player");
+            AddCategoryMapping(2185, TorznabCatType.Console, "Video consoles");
+            AddCategoryMapping(2487, TorznabCatType.ConsolePSVita, " | - Video for PSVita");
+            AddCategoryMapping(2182, TorznabCatType.ConsolePSP, " | - Movies for PSP");
+            AddCategoryMapping(2181, TorznabCatType.ConsolePSP, " | - For PSP TV Shows");
+            AddCategoryMapping(2180, TorznabCatType.ConsolePSP, " | - Cartoons for PSP");
+            AddCategoryMapping(2179, TorznabCatType.ConsolePSP, " | - Drama for PSP");
+            AddCategoryMapping(2186, TorznabCatType.ConsolePSP, " | - Anime for PSP");
+            AddCategoryMapping(700, TorznabCatType.ConsolePSP, " | - Video to PSP");
+            AddCategoryMapping(1926, TorznabCatType.ConsolePS3, " | - Videos for the PS3 and other consoles");
+            AddCategoryMapping(899, TorznabCatType.PCGames, "Games for Linux");
+            AddCategoryMapping(1992, TorznabCatType.PCGames, " | - Native games for Linux");
+            AddCategoryMapping(2059, TorznabCatType.PCGames, " | - Game Ported to Linux");
+
+            // Программы и Дизайн
+            AddCategoryMapping(1012, TorznabCatType.PC0day, "Operating systems from Microsoft");
+            AddCategoryMapping(1019, TorznabCatType.PC0day, " | - Desktop operating system from Microsoft (released prior to Windows XP)");
+            AddCategoryMapping(2153, TorznabCatType.PC0day, " | - Desktop operating system from Microsoft (since Windows XP)");
+            AddCategoryMapping(1021, TorznabCatType.PC0day, " | - Server operating system from Microsoft");
+            AddCategoryMapping(1025, TorznabCatType.PC0day, " | - Other (Operating Systems from Microsoft)");
+            AddCategoryMapping(1376, TorznabCatType.PC0day, "Linux, Unix and other operating systems");
+            AddCategoryMapping(1379, TorznabCatType.PC0day, " | - Operating Systems (Linux, Unix)");
+            AddCategoryMapping(1381, TorznabCatType.PC0day, " | - Software (Linux, Unix)");
+            AddCategoryMapping(1473, TorznabCatType.PC0day, " | - Other operating systems and software for them");
+            AddCategoryMapping(1195, TorznabCatType.PC0day, "Test drives to adjust the audio / video equipment");
+            AddCategoryMapping(1013, TorznabCatType.PC0day, "System programs");
+            AddCategoryMapping(1028, TorznabCatType.PC0day, " | - Work with hard drive");
+            AddCategoryMapping(1029, TorznabCatType.PC0day, " | - Backup");
+            AddCategoryMapping(1030, TorznabCatType.PC0day, " | - Archivers and File Managers");
+            AddCategoryMapping(1031, TorznabCatType.PC0day, " | - Software to configure and optimize the operating system");
+            AddCategoryMapping(1032, TorznabCatType.PC0day, " | - Service computer service");
+            AddCategoryMapping(1033, TorznabCatType.PC0day, " | - Work with data carriers");
+            AddCategoryMapping(1034, TorznabCatType.PC0day, " | - Information and Diagnostics");
+            AddCategoryMapping(1066, TorznabCatType.PC0day, " | - Software for Internet and networks");
+            AddCategoryMapping(1035, TorznabCatType.PC0day, " | - Software to protect your computer (antivirus software, firewalls)");
+            AddCategoryMapping(1038, TorznabCatType.PC0day, " | - Anti-spyware and anti-trojan");
+            AddCategoryMapping(1039, TorznabCatType.PC0day, " | - Software to protect information");
+            AddCategoryMapping(1536, TorznabCatType.PC0day, " | - Drivers and Firmware");
+            AddCategoryMapping(1051, TorznabCatType.PC0day, " | - The original disks to computers and accessories");
+            AddCategoryMapping(1040, TorznabCatType.PC0day, " | - Server software for Windows");
+            AddCategoryMapping(1041, TorznabCatType.PC0day, " | - Change the Windows interface");
+            AddCategoryMapping(1636, TorznabCatType.PC0day, " | - Screensavers");
+            AddCategoryMapping(1042, TorznabCatType.PC0day, " | - Other (System programs on Windows)");
+            AddCategoryMapping(1014, TorznabCatType.PC0day, "Systems for business, office, research and project work");
+            AddCategoryMapping(1060, TorznabCatType.PC0day, " | - Everything for the home: dressmaking, sewing, cooking");
+            AddCategoryMapping(1061, TorznabCatType.PC0day, " | - Office Systems");
+            AddCategoryMapping(1062, TorznabCatType.PC0day, " | - Business Systems");
+            AddCategoryMapping(1067, TorznabCatType.PC0day, " | - Recognition of text, sound and speech synthesis");
+            AddCategoryMapping(1086, TorznabCatType.PC0day, " | - Work with PDF and DjVu");
+            AddCategoryMapping(1068, TorznabCatType.PC0day, " | - Dictionaries, translators");
+            AddCategoryMapping(1063, TorznabCatType.PC0day, " | - System for scientific work");
+            AddCategoryMapping(1087, TorznabCatType.PC0day, " | - CAD (general and engineering)");
+            AddCategoryMapping(1192, TorznabCatType.PC0day, " | - CAD (electronics, automation, GAP)");
+            AddCategoryMapping(1088, TorznabCatType.PC0day, " | - Software for architects and builders");
+            AddCategoryMapping(1193, TorznabCatType.PC0day, " | - Library and projects for architects and designers inter ..");
+            AddCategoryMapping(1071, TorznabCatType.PC0day, " | - Other reference systems");
+            AddCategoryMapping(1073, TorznabCatType.PC0day, " | - Miscellaneous (business systems, office, research and design ..");
+            AddCategoryMapping(1052, TorznabCatType.PC0day, "Web Development and Programming");
+            AddCategoryMapping(1053, TorznabCatType.PC0day, " | - WYSIWYG editors for web diz");
+            AddCategoryMapping(1054, TorznabCatType.PC0day, " | - Text editors Illuminated");
+            AddCategoryMapping(1055, TorznabCatType.PC0day, " | - Programming environments, compilers and support, etc. ..");
+            AddCategoryMapping(1056, TorznabCatType.PC0day, " | - Components for programming environments");
+            AddCategoryMapping(2077, TorznabCatType.PC0day, " | - Database Management Systems");
+            AddCategoryMapping(1057, TorznabCatType.PC0day, " | - Scripts and engines sites, CMS and extensions to it");
+            AddCategoryMapping(1018, TorznabCatType.PC0day, " | - Templates for websites and CMS");
+            AddCategoryMapping(1058, TorznabCatType.PC0day, " | - Miscellaneous (Web Development and Programming)");
+            AddCategoryMapping(1016, TorznabCatType.PC0day, "Programs to work with multimedia and 3D");
+            AddCategoryMapping(1079, TorznabCatType.PC0day, " | - Software Kits");
+            AddCategoryMapping(1080, TorznabCatType.PC0day, " | - Plug-ins for Adobe's programs");
+            AddCategoryMapping(1081, TorznabCatType.PC0day, " | - Graphic Editors");
+            AddCategoryMapping(1082, TorznabCatType.PC0day, " | - Software for typesetting, printing, and working with fonts");
+            AddCategoryMapping(1083, TorznabCatType.PC0day, " | - 3D modeling, rendering and plugins for them");
+            AddCategoryMapping(1084, TorznabCatType.PC0day, " | - Animation");
+            AddCategoryMapping(1085, TorznabCatType.PC0day, " | - Creating a BD / HD / DVD-Video");
+            AddCategoryMapping(1089, TorznabCatType.PC0day, " | - Video Editors");
+            AddCategoryMapping(1090, TorznabCatType.PC0day, " | - Video converters Audio");
+            AddCategoryMapping(1065, TorznabCatType.PC0day, " | - Audio and video, CD- players and catalogers");
+            AddCategoryMapping(1064, TorznabCatType.PC0day, " | - Cataloging and graphics viewers");
+            AddCategoryMapping(1092, TorznabCatType.PC0day, " | - Miscellaneous (Programme for multimedia and 3D)");
+            AddCategoryMapping(1204, TorznabCatType.PC0day, " | - Virtual Studios, sequencers and audio editor");
+            AddCategoryMapping(1027, TorznabCatType.PC0day, " | - Virtual Instruments & Synthesizers");
+            AddCategoryMapping(1199, TorznabCatType.PC0day, " | - Plug-ins for sound processing");
+            AddCategoryMapping(1091, TorznabCatType.PC0day, " | - Miscellaneous (Programs for working with audio)");
+            AddCategoryMapping(828, TorznabCatType.PC0day, "Materials for Multimedia and Design");
+            AddCategoryMapping(1357, TorznabCatType.PC0day, " | - Authoring");
+            AddCategoryMapping(890, TorznabCatType.PC0day, " | - Official compilations vector clipart");
+            AddCategoryMapping(830, TorznabCatType.PC0day, " | - Other vector cliparts");
+            AddCategoryMapping(1290, TorznabCatType.PC0day, " |- Photostoсks");
+            AddCategoryMapping(1962, TorznabCatType.PC0day, " | - Photoshop Costumes");
+            AddCategoryMapping(831, TorznabCatType.PC0day, " | - Frames and Vignettes for processing photos");
+            AddCategoryMapping(829, TorznabCatType.PC0day, " | - Other raster clipart");
+            AddCategoryMapping(633, TorznabCatType.PC0day, " | - 3D models, scenes and materials");
+            AddCategoryMapping(1009, TorznabCatType.PC0day, " | - Footage");
+            AddCategoryMapping(1963, TorznabCatType.PC0day, " | - Other collections footage");
+            AddCategoryMapping(1954, TorznabCatType.PC0day, " | - Music Library");
+            AddCategoryMapping(1010, TorznabCatType.PC0day, " | - Sound Effects");
+            AddCategoryMapping(1674, TorznabCatType.PC0day, " | - Sample Libraries");
+            AddCategoryMapping(2421, TorznabCatType.PC0day, " | - Library and saundbanki for samplers, presets for sy ..");
+            AddCategoryMapping(2492, TorznabCatType.PC0day, " |- Multitracks");
+            AddCategoryMapping(839, TorznabCatType.PC0day, " | - Materials for creating menus and DVD covers");
+            AddCategoryMapping(1679, TorznabCatType.PC0day, " | - Styles, brushes, shapes and patterns for Adobe Photoshop");
+            AddCategoryMapping(1011, TorznabCatType.PC0day, " | - Fonts");
+            AddCategoryMapping(835, TorznabCatType.PC0day, " | - Miscellaneous (Materials for Multimedia and Design)");
+            AddCategoryMapping(1503, TorznabCatType.PC0day, "GIS, navigation systems and maps");
+            AddCategoryMapping(1507, TorznabCatType.PC0day, " | - GIS (Geoinformatsionnыe sistemы)");
+            AddCategoryMapping(1526, TorznabCatType.PC0day, " | - Maps provided with the program shell");
+            AddCategoryMapping(1508, TorznabCatType.PC0day, " | - Atlases and maps modern (after 1950)");
+            AddCategoryMapping(1509, TorznabCatType.PC0day, " | - Atlases and antique maps (up to 1950)");
+            AddCategoryMapping(1510, TorznabCatType.PC0day, " | - Other Maps (astronomical, historical, topically ..");
+            AddCategoryMapping(1511, TorznabCatType.PC0day, " | - Built-in car navigation");
+            AddCategoryMapping(1512, TorznabCatType.PC0day, " |- Garmin");
+            AddCategoryMapping(1513, TorznabCatType.PC0day, " | -");
+            AddCategoryMapping(1514, TorznabCatType.PC0day, " |- TomTom");
+            AddCategoryMapping(1515, TorznabCatType.PC0day, " |- Navigon / Navitel");
+            AddCategoryMapping(1516, TorznabCatType.PC0day, " |- Igo");
+            AddCategoryMapping(1517, TorznabCatType.PC0day, " | - Miscellaneous - navigation and maps");
+
+            // Мобильные устройства
+            AddCategoryMapping(285, TorznabCatType.PCPhoneOther, "Games, applications and so on. Mobile");
+            AddCategoryMapping(2149, TorznabCatType.PCPhoneAndroid, " | - Games for Android OS");
+            AddCategoryMapping(2154, TorznabCatType.PCPhoneAndroid, " | - Applications for Android OS");
+            AddCategoryMapping(2419, TorznabCatType.PCPhoneOther, " | - Applications for Windows Phone 7,8");
+            AddCategoryMapping(2420, TorznabCatType.PCPhoneOther, " | - Games for Windows Phone 7,8");
+            AddCategoryMapping(1004, TorznabCatType.PCPhoneOther, " | - Games for Symbian");
+            AddCategoryMapping(289, TorznabCatType.PCPhoneOther, " | - Applications for Symbian");
+            AddCategoryMapping(1001, TorznabCatType.PCPhoneOther, " | - Games for Java");
+            AddCategoryMapping(1005, TorznabCatType.PCPhoneOther, " | - Applications for Java");
+            AddCategoryMapping(1002, TorznabCatType.PCPhoneOther, " | - Games for Windows Mobile, Palm OS, BlackBerry and so on.");
+            AddCategoryMapping(290, TorznabCatType.PCPhoneOther, " | - Applications for Windows Mobile, Palm OS, BlackBerry and so on.");
+            AddCategoryMapping(288, TorznabCatType.PCPhoneOther, " | - Software for your phone");
+            AddCategoryMapping(292, TorznabCatType.PCPhoneOther, " | - Firmware for phones");
+            AddCategoryMapping(291, TorznabCatType.PCPhoneOther, " | - Wallpapers and Themes");
+            AddCategoryMapping(957, TorznabCatType.PCPhoneOther, "Video for mobile devices");
+            AddCategoryMapping(287, TorznabCatType.PCPhoneOther, " | - Video for Smartphones and PDAs");
+            AddCategoryMapping(286, TorznabCatType.PCPhoneOther, " | - Mobile Video (3GP)");
+
+            // Apple
+            AddCategoryMapping(1366, TorznabCatType.PCMac, "Apple Macintosh");
+            AddCategoryMapping(1368, TorznabCatType.PCMac, " |- Mac OS (для Macintosh)");
+            AddCategoryMapping(1383, TorznabCatType.PCMac, " | - Mac OS (for RS-Hakintoš)");
+            AddCategoryMapping(537, TorznabCatType.PCMac, " | - Game Mac OS");
+            AddCategoryMapping(1394, TorznabCatType.PCMac, " | - Software for viewing and video processing");
+            AddCategoryMapping(1370, TorznabCatType.PCMac, " | - Software to build and graphics processing");
+            AddCategoryMapping(2237, TorznabCatType.PCMac, " | - Plug-ins for Adobe's programs");
+            AddCategoryMapping(1372, TorznabCatType.PCMac, " | - Audio editor and converter");
+            AddCategoryMapping(1373, TorznabCatType.PCMac, " | - System software");
+            AddCategoryMapping(1375, TorznabCatType.PCMac, " | - Office software");
+            AddCategoryMapping(1371, TorznabCatType.PCMac, " | - Software for the Internet and network");
+            AddCategoryMapping(1374, TorznabCatType.PCMac, " | - Other software");
+            AddCategoryMapping(1933, TorznabCatType.PCMac, "iOS");
+            AddCategoryMapping(1935, TorznabCatType.PCMac, " | - Software for iOS");
+            AddCategoryMapping(1003, TorznabCatType.PCMac, " | - Games for iOS");
+            AddCategoryMapping(1937, TorznabCatType.PCMac, " | - Miscellaneous for iOS");
+            AddCategoryMapping(2235, TorznabCatType.PCMac, "Video");
+            AddCategoryMapping(1908, TorznabCatType.PCMac, " | - Movies for iPod, iPhone, iPad");
+            AddCategoryMapping(864, TorznabCatType.PCMac, " | - TV Shows for iPod, iPhone, iPad");
+            AddCategoryMapping(863, TorznabCatType.PCMac, " | - Cartoons for iPod, iPhone, iPad");
+            AddCategoryMapping(2535, TorznabCatType.PCMac, " | - Anime for iPod, iPhone, iPad");
+            AddCategoryMapping(2534, TorznabCatType.PCMac, " | - The music video to iPod, iPhone, iPad");
+            AddCategoryMapping(2238, TorznabCatType.PCMac, "Видео HD");
+            AddCategoryMapping(1936, TorznabCatType.PCMac, " | - HD Movies to Apple TV");
+            AddCategoryMapping(315, TorznabCatType.PCMac, " | - HD TV Shows on Apple TV");
+            AddCategoryMapping(1363, TorznabCatType.PCMac, " | - HD Animation for Apple TV");
+            AddCategoryMapping(2082, TorznabCatType.PCMac, " | - Documentary HD video for Apple TV");
+            AddCategoryMapping(2241, TorznabCatType.PCMac, " | - Musical HD video for Apple TV");
+            AddCategoryMapping(2236, TorznabCatType.PCMac, "audio");
+            AddCategoryMapping(1909, TorznabCatType.PCMac, " | - Audiobooks (AAC, ALAC)");
+            AddCategoryMapping(1927, TorznabCatType.PCMac, " | - Music Lossless (ALAC)");
+            AddCategoryMapping(2240, TorznabCatType.PCMac, " |- Музыка Lossy (AAC-iTunes)");
+            AddCategoryMapping(2248, TorznabCatType.PCMac, " |- Музыка Lossy (AAC)");
+            AddCategoryMapping(2244, TorznabCatType.PCMac, " |- Музыка Lossy (AAC) (Singles, EPs)");
+            AddCategoryMapping(2243, TorznabCatType.PCMac, "F.A.Q.");
+
+            // Медицина и здоровье
+            AddCategoryMapping(2125, TorznabCatType.Books, "Books, magazines and programs");
+            AddCategoryMapping(2133, TorznabCatType.Books, " | - Clinical Medicine until 1980");
+            AddCategoryMapping(2130, TorznabCatType.Books, " | - Clinical Medicine from 1980 to 2000");
+            AddCategoryMapping(2313, TorznabCatType.Books, " | - Clinical Medicine since 2000");
+            AddCategoryMapping(2314, TorznabCatType.Books, " | - Popular medical periodicals (newspapers and magazines)");
+            AddCategoryMapping(2528, TorznabCatType.Books, " | - Scientific medical periodicals (newspapers and magazines)");
+            AddCategoryMapping(2129, TorznabCatType.Books, " | - Life Sciences");
+            AddCategoryMapping(2141, TorznabCatType.Books, " | - Pharmacy and Pharmacology");
+            AddCategoryMapping(2132, TorznabCatType.Books, " | - Non-traditional, traditional medicine and popular books on the s ..");
+            AddCategoryMapping(2131, TorznabCatType.Books, " | - Veterinary Medicine, Miscellaneous");
+            AddCategoryMapping(2315, TorznabCatType.Books, " | - Thematic collection of books");
+            AddCategoryMapping(1350, TorznabCatType.Books, " | - Audio Books on medicine");
+            AddCategoryMapping(2134, TorznabCatType.Books, " | - Medical software");
+            AddCategoryMapping(2126, TorznabCatType.Books, "Tutorials, Doc. movies and TV shows on medicine");
+            AddCategoryMapping(2135, TorznabCatType.Books, " | - Medicine and Dentistry");
+            AddCategoryMapping(2140, TorznabCatType.Books, " | - Psychotherapy and clinical psychology");
+            AddCategoryMapping(2136, TorznabCatType.Books, " | - Massage");
+            AddCategoryMapping(2138, TorznabCatType.Books, " | - Health");
+            AddCategoryMapping(2139, TorznabCatType.Books, " | - Documentary movies and TV shows on medicine");
+
+            // Разное
+            AddCategoryMapping(10, TorznabCatType.Other, "Miscellaneous");
+            AddCategoryMapping(865, TorznabCatType.Other, " | - Psihoaktivnye audioprogrammy");
+            AddCategoryMapping(1100, TorznabCatType.Other, " | - Avatars, Icons, Smileys");
+            AddCategoryMapping(1643, TorznabCatType.Other, " | - Painting, Graphics, Sculpture, Digital Art");
+            AddCategoryMapping(848, TorznabCatType.Other, " | - Pictures");
+            AddCategoryMapping(808, TorznabCatType.Other, " | - Amateur Photos");
+            AddCategoryMapping(630, TorznabCatType.Other, " | - Wallpapers");
+            AddCategoryMapping(1664, TorznabCatType.Other, " | - Celebrity Photos");
+            AddCategoryMapping(148, TorznabCatType.Other, " | - Audio");
+            AddCategoryMapping(807, TorznabCatType.Other, " | - Video");
+            AddCategoryMapping(147, TorznabCatType.Other, " | - Publications and educational materials (texts)");
+            AddCategoryMapping(847, TorznabCatType.Other, " | - Trailers and additional materials for films");
             AddCategoryMapping(1167, TorznabCatType.Other, " | - Amateur videos");
         }
 
         public override async Task<ConfigurationData> GetConfigurationForSetup()
         {
             var response = await RequestStringWithCookies(LoginUrl);
-            var LoginResultParser = new HtmlParser();
-            var LoginResultDocument = LoginResultParser.Parse(response.Content);
+            var LoginResultParser = new HtmlParser();
+            var LoginResultDocument = LoginResultParser.Parse(response.Content);
             var captchaimg = LoginResultDocument.QuerySelector("img[src^=\"//static.t-ru.org/captcha/\"]");
-            if (captchaimg != null)
+            if (captchaimg != null)
             { 
                 var captchaImage = await RequestBytesWithCookies("https:" + captchaimg.GetAttribute("src"));
                 configData.CaptchaImage.Value = captchaImage.Content;
 
                 var codefield = LoginResultDocument.QuerySelector("input[name^=\"cap_code_\"]");
-                cap_code_field = codefield.GetAttribute("name");
-
+                cap_code_field = codefield.GetAttribute("name");
+
                 var sidfield = LoginResultDocument.QuerySelector("input[name=\"cap_sid\"]");
-                cap_sid = sidfield.GetAttribute("value");
+                cap_sid = sidfield.GetAttribute("value");
             }
-            else
-            {
-                configData.CaptchaImage.Value = null;
+            else
+            {
+                configData.CaptchaImage.Value = null;
             }
             return configData;
         }
@@ -1469,26 +1469,26 @@ namespace Jackett.Indexers
                 { "login", "entry" }
             };
 
-            if (!string.IsNullOrWhiteSpace(cap_sid))
-            {
-                pairs.Add("cap_sid", cap_sid);
-                pairs.Add(cap_code_field, configData.CaptchaText.Value);
-
-                cap_sid = null;
-                cap_code_field = null;
+            if (!string.IsNullOrWhiteSpace(cap_sid))
+            {
+                pairs.Add("cap_sid", cap_sid);
+                pairs.Add(cap_code_field, configData.CaptchaText.Value);
+
+                cap_sid = null;
+                cap_code_field = null;
             }
 
             var result = await RequestLoginAndFollowRedirect(LoginUrl, pairs, CookieHeader, true, null, LoginUrl, true);
-            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("class=\"logged-in-as-uname\""), () =>
-            {
-                var errorMessage = result.Content;
-                var LoginResultParser = new HtmlParser();
-                var LoginResultDocument = LoginResultParser.Parse(result.Content);
-                var errormsg = LoginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]");
-                if (errormsg != null)
-                    errorMessage = errormsg.TextContent;
-
-                throw new ExceptionWithConfigData(errorMessage, configData);
+            await ConfigureIfOK(result.Cookies, result.Content != null && result.Content.Contains("class=\"logged-in-as-uname\""), () =>
+            {
+                var errorMessage = result.Content;
+                var LoginResultParser = new HtmlParser();
+                var LoginResultDocument = LoginResultParser.Parse(result.Content);
+                var errormsg = LoginResultDocument.QuerySelector("h4[class=\"warnColor1 tCenter mrg_16\"]");
+                if (errormsg != null)
+                    errorMessage = errormsg.TextContent;
+
+                throw new ExceptionWithConfigData(errorMessage, configData);
             });
             return IndexerConfigurationStatus.RequiresTesting;
         }
@@ -1496,82 +1496,82 @@ namespace Jackett.Indexers
         public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
         {
             var releases = new List<ReleaseInfo>();
-            var searchString = query.GetQueryString();
-
-            var queryCollection = new NameValueCollection();
-
-            // if the search string is empty use the getnew view
-            if (string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("nm", searchString);
+            var searchString = query.GetQueryString();
+
+            var queryCollection = new NameValueCollection();
+
+            // if the search string is empty use the getnew view
+            if (string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("nm", searchString);
             }
-            else // use the normal search
-            {
-                searchString = searchString.Replace("-", " ");
-                queryCollection.Add("nm", searchString);
+            else // use the normal search
+            {
+                searchString = searchString.Replace("-", " ");
+                queryCollection.Add("nm", searchString);
             }
 
             var searchUrl = SearchUrl + "?" + queryCollection.GetQueryString();
-            var results = await RequestStringWithCookies(searchUrl);
-            if (!results.Content.Contains("class=\"logged-in-as-uname\""))
-            {
-                // re login
-                await ApplyConfiguration(null);
-                results = await RequestStringWithCookies(searchUrl);
-            }
+            var results = await RequestStringWithCookies(searchUrl);
+            if (!results.Content.Contains("class=\"logged-in-as-uname\""))
+            {
+                // re login
+                await ApplyConfiguration(null);
+                results = await RequestStringWithCookies(searchUrl);
+            }
             try
             {
                 string RowsSelector = "table#tor-tbl > tbody > tr";
 
-                var SearchResultParser = new HtmlParser();
+                var SearchResultParser = new HtmlParser();
                 var SearchResultDocument = SearchResultParser.Parse(results.Content);
-                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
-                foreach (var Row in Rows)
+                var Rows = SearchResultDocument.QuerySelectorAll(RowsSelector);
+                foreach (var Row in Rows)
                 {
-                    try
+                    try
                     {
                         var release = new ReleaseInfo();
 
-                        release.MinimumRatio = 1;
+                        release.MinimumRatio = 1;
                         release.MinimumSeedTime = 0;
-
-                        var qDownloadLink = Row.QuerySelector("td.tor-size > a.tr-dl");
-                        if (qDownloadLink == null) // Expects moderation
-                            continue;
-
-                        var qDetailsLink = Row.QuerySelector("td.t-title > div.t-title > a.tLink");
-                        var qSize = Row.QuerySelector("td.tor-size > u");
-
-                        release.Title = qDetailsLink.TextContent;
-                        release.Comments = new Uri(SiteLink + "forum/" + qDetailsLink.GetAttribute("href"));
-                        release.Link = new Uri(SiteLink + "forum/" + qDownloadLink.GetAttribute("href"));
-                        release.Guid = release.Comments;
-                        release.Size = ReleaseInfo.GetBytes(qSize.TextContent);
-
-                        var seeders = Row.QuerySelector("td:nth-child(7) > u").TextContent;
-                        if (string.IsNullOrWhiteSpace(seeders))
-                            seeders = "0";
-                        release.Seeders = ParseUtil.CoerceInt(seeders);
-                        release.Peers = ParseUtil.CoerceInt(Row.QuerySelector("td:nth-child(8) > b").TextContent) + release.Seeders;
-                        release.Grabs = ParseUtil.CoerceLong(Row.QuerySelector("td:nth-child(9)").TextContent);
-
-                        var timestr = Row.QuerySelector("td:nth-child(10) > u").TextContent;
-                        release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(long.Parse(timestr));
-
-                        var forum = Row.QuerySelector("td.f-name > div.f-name > a");
-                        var forumid = forum.GetAttribute("href").Split('=')[1];
-                        release.Category = MapTrackerCatToNewznab(forumid);
-
-                        release.DownloadVolumeFactor = 1;
-                        release.UploadVolumeFactor = 1;
 
-                        releases.Add(release);
-                    }
-                    catch (Exception ex)
-                    {
-                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
+                        var qDownloadLink = Row.QuerySelector("td.tor-size > a.tr-dl");
+                        if (qDownloadLink == null) // Expects moderation
+                            continue;
+
+                        var qDetailsLink = Row.QuerySelector("td.t-title > div.t-title > a.tLink");
+                        var qSize = Row.QuerySelector("td.tor-size > u");
+
+                        release.Title = qDetailsLink.TextContent;
+                        release.Comments = new Uri(SiteLink + "forum/" + qDetailsLink.GetAttribute("href"));
+                        release.Link = new Uri(SiteLink + "forum/" + qDownloadLink.GetAttribute("href"));
+                        release.Guid = release.Comments;
+                        release.Size = ReleaseInfo.GetBytes(qSize.TextContent);
+
+                        var seeders = Row.QuerySelector("td:nth-child(7) > u").TextContent;
+                        if (string.IsNullOrWhiteSpace(seeders))
+                            seeders = "0";
+                        release.Seeders = ParseUtil.CoerceInt(seeders);
+                        release.Peers = ParseUtil.CoerceInt(Row.QuerySelector("td:nth-child(8) > b").TextContent) + release.Seeders;
+                        release.Grabs = ParseUtil.CoerceLong(Row.QuerySelector("td:nth-child(9)").TextContent);
+
+                        var timestr = Row.QuerySelector("td:nth-child(10) > u").TextContent;
+                        release.PublishDate = DateTimeUtil.UnixTimestampToDateTime(long.Parse(timestr));
+
+                        var forum = Row.QuerySelector("td.f-name > div.f-name > a");
+                        var forumid = forum.GetAttribute("href").Split('=')[1];
+                        release.Category = MapTrackerCatToNewznab(forumid);
+
+                        release.DownloadVolumeFactor = 1;
+                        release.UploadVolumeFactor = 1;
+
+                        releases.Add(release);
+                    }
+                    catch (Exception ex)
+                    {
+                        logger.Error(string.Format("{0}: Error while parsing row '{1}':\n\n{2}", ID, Row.OuterHtml, ex));
                     }
-                }
+                }
             }
             catch (Exception ex)
             {
diff --git a/src/Jackett/Indexers/x264.cs b/src/Jackett/Indexers/x264.cs
index 90239b7a855d96851249a65389e9ccacc46e39ee..0bc73841846a44813cceea6d408e63e98f8dba71 100644
--- a/src/Jackett/Indexers/x264.cs
+++ b/src/Jackett/Indexers/x264.cs
@@ -1,206 +1,206 @@
-using CsQuery;
-using Jackett.Models;
-using Jackett.Services;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json.Linq;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Jackett.Models.IndexerConfig;
-using System.Collections.Specialized;
-
-namespace Jackett.Indexers
-{
-    public class x264 : BaseIndexer, IIndexer
-    {
-        private string SearchUrl { get { return SiteLink + "browse.php"; } }
-        private string LoginUrl { get { return SiteLink + "login.php"; } }
-        private string SubmitLoginUrl { get { return SiteLink + "takelogin.php"; } }
-
-        new ConfigurationDataRecaptchaLogin configData
-        {
-            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
-            set { base.configData = value; }
-        }
-
-        public x264(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
-            : base(name: "x264",
-                description: "A movie/TV tracker",
-                link: "https://x264.me/",
-                caps: new TorznabCapabilities(),
-                manager: i,
-                client: w,
-                logger: l,
-                p: ps,
-                configData: new ConfigurationDataRecaptchaLogin())
-        {
-            Encoding = Encoding.GetEncoding("iso-8859-1");
-            Language = "en-us";
-            Type = "private";
-
-            TorznabCaps.SupportsImdbSearch = true;
-
-            AddCategoryMapping(20, TorznabCatType.Movies); // Movies&TV/Sources
-            AddCategoryMapping(53, TorznabCatType.MoviesHD); // Movies/1080p
-            AddCategoryMapping(30, TorznabCatType.MoviesHD); // Movies/576p
-            AddCategoryMapping(50, TorznabCatType.MoviesHD); // Movies/720p
-            AddCategoryMapping(33, TorznabCatType.MoviesSD); // Movies/SD
-            AddCategoryMapping(54, TorznabCatType.TVHD); // TV/1080p
-            AddCategoryMapping(31, TorznabCatType.TVHD); // TV/576p
-            AddCategoryMapping(51, TorznabCatType.TVHD); // TV/720p
-            AddCategoryMapping(25, TorznabCatType.TVSD); // TV/SD
-        }
-
-        public override async Task<ConfigurationData> GetConfigurationForSetup()
-        {
-            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
-            CQ dom = loginPage.Content;
-
-            var result = this.configData;
-            var captcha = dom.Find(".g-recaptcha");
-            result.CookieHeader.Value = loginPage.Cookies;
-            result.Captcha.SiteKey = captcha.Attr("data-sitekey");
-            result.Captcha.Version = "2";
-            return result;
-        }
-
-        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
-        {
-            LoadValuesFromJson(configJson);
-            var pairs = new Dictionary<string, string> {
-                { "username", configData.Username.Value },
-                { "password", configData.Password.Value },
-                { "g-recaptcha-response", configData.Captcha.Value }
-            };
-
-            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
-            {
-                // Cookie was manually supplied
-                CookieHeader = configData.Captcha.Cookie;
-                try
-                {
-                    var results = await PerformQuery(new TorznabQuery());
-                    if (!results.Any())
-                    {
-                        throw new Exception("Your cookie did not work");
-                    }
-
-                    SaveConfig();
-                    IsConfigured = true;
-                    return IndexerConfigurationStatus.Completed;
-                }
-                catch (Exception e)
-                {
-                    IsConfigured = false;
-                    throw new Exception("Your cookie did not work: " + e.Message);
-                }
-            }
-
-            var result = await RequestLoginAndFollowRedirect(SubmitLoginUrl, pairs, configData.CookieHeader.Value, true, null, LoginUrl);
-            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
-            {
-                var errorMessage = result.Content;
-                throw new ExceptionWithConfigData(errorMessage, configData);
-            });
-            return IndexerConfigurationStatus.RequiresTesting;
-        }
-
-        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
-        {
-            List<ReleaseInfo> releases = new List<ReleaseInfo>();
-
-            var searchString = query.GetQueryString();
-            var searchUrl = SearchUrl;
-            var queryCollection = new NameValueCollection();
-            queryCollection.Add("incldead", "1");
-            queryCollection.Add("xtype", "0");
-            queryCollection.Add("stype", "0");
-
-            if (query.ImdbID != null)
-            {
-                queryCollection.Add("search", query.ImdbID);
-            }
-            else if (!string.IsNullOrWhiteSpace(searchString))
-            {
-                queryCollection.Add("search", searchString);
-            }
-
-            foreach (var cat in MapTorznabCapsToTrackers(query))
-            {
-                queryCollection.Add("c" + cat, "1");
-            }
-
-            searchUrl += "?" + queryCollection.GetQueryString();
-
-            var results = await RequestStringWithCookiesAndRetry(searchUrl);
-            try
-            {
-                CQ dom = results.Content;
-
-                var sideWideFreeLeech = false;
-                if (dom.Find("td > b > font[color=\"white\"]:contains(Free Leech)").Length >= 1)
-                    sideWideFreeLeech = true;
-
-                var rows = dom["table > tbody > tr[height=36]"];
-                foreach (var row in rows)
-                {
-                    var release = new ReleaseInfo();
-                    release.MinimumRatio = 1;
-                    release.MinimumSeedTime = 7 * 24 * 60 * 60;
-                    
-                    var qRow = row.Cq();
-                    var qCatLink = qRow.Find("a[href^=?cat]").First();
-                    var qDetailsLink = qRow.Find("a[href^=details.php]").First();
-                    var qSeeders = qRow.Find("td:eq(8)");
-                    var qLeechers = qRow.Find("td:eq(9)");
-                    var qDownloadLink = qRow.Find("a[href^=\"download.php\"]").First();
-                    var qImdbLink = qRow.Find("a[href^=/redir.php?url=http://www.imdb.com]");
-                    var qSize = qRow.Find("td:eq(6)");
-
-                    var catStr = qCatLink.Attr("href").Split('=')[1];
-                    release.Category = MapTrackerCatToNewznab(catStr);
-
-                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
-                    release.Title = qDetailsLink.Text().Trim();
-                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
-                    release.Guid = release.Link;
-
-                    var sizeStr = qSize.Text();
-                    release.Size = ReleaseInfo.GetBytes(sizeStr);
-
-                    if(qImdbLink.Length == 1) { 
-                        var ImdbId = qImdbLink.Attr("href").Split('/').Last().Substring(2);
-                        release.Imdb = ParseUtil.CoerceLong(ImdbId);
-                    }
-
-                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
-                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
-
+using CsQuery;
+using Jackett.Models;
+using Jackett.Services;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json.Linq;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Jackett.Models.IndexerConfig;
+using System.Collections.Specialized;
+
+namespace Jackett.Indexers
+{
+    public class x264 : BaseIndexer, IIndexer
+    {
+        private string SearchUrl { get { return SiteLink + "browse.php"; } }
+        private string LoginUrl { get { return SiteLink + "login.php"; } }
+        private string SubmitLoginUrl { get { return SiteLink + "takelogin.php"; } }
+
+        new ConfigurationDataRecaptchaLogin configData
+        {
+            get { return (ConfigurationDataRecaptchaLogin)base.configData; }
+            set { base.configData = value; }
+        }
+
+        public x264(IIndexerManagerService i, Logger l, IWebClient w, IProtectionService ps)
+            : base(name: "x264",
+                description: "A movie/TV tracker",
+                link: "https://x264.me/",
+                caps: new TorznabCapabilities(),
+                manager: i,
+                client: w,
+                logger: l,
+                p: ps,
+                configData: new ConfigurationDataRecaptchaLogin())
+        {
+            Encoding = Encoding.GetEncoding("iso-8859-1");
+            Language = "en-us";
+            Type = "private";
+
+            TorznabCaps.SupportsImdbSearch = true;
+
+            AddCategoryMapping(20, TorznabCatType.Movies); // Movies&TV/Sources
+            AddCategoryMapping(53, TorznabCatType.MoviesHD); // Movies/1080p
+            AddCategoryMapping(30, TorznabCatType.MoviesHD); // Movies/576p
+            AddCategoryMapping(50, TorznabCatType.MoviesHD); // Movies/720p
+            AddCategoryMapping(33, TorznabCatType.MoviesSD); // Movies/SD
+            AddCategoryMapping(54, TorznabCatType.TVHD); // TV/1080p
+            AddCategoryMapping(31, TorznabCatType.TVHD); // TV/576p
+            AddCategoryMapping(51, TorznabCatType.TVHD); // TV/720p
+            AddCategoryMapping(25, TorznabCatType.TVSD); // TV/SD
+        }
+
+        public override async Task<ConfigurationData> GetConfigurationForSetup()
+        {
+            var loginPage = await RequestStringWithCookies(LoginUrl, string.Empty);
+            CQ dom = loginPage.Content;
+
+            var result = this.configData;
+            var captcha = dom.Find(".g-recaptcha");
+            result.CookieHeader.Value = loginPage.Cookies;
+            result.Captcha.SiteKey = captcha.Attr("data-sitekey");
+            result.Captcha.Version = "2";
+            return result;
+        }
+
+        public async Task<IndexerConfigurationStatus> ApplyConfiguration(JToken configJson)
+        {
+            LoadValuesFromJson(configJson);
+            var pairs = new Dictionary<string, string> {
+                { "username", configData.Username.Value },
+                { "password", configData.Password.Value },
+                { "g-recaptcha-response", configData.Captcha.Value }
+            };
+
+            if (!string.IsNullOrWhiteSpace(configData.Captcha.Cookie))
+            {
+                // Cookie was manually supplied
+                CookieHeader = configData.Captcha.Cookie;
+                try
+                {
+                    var results = await PerformQuery(new TorznabQuery());
+                    if (!results.Any())
+                    {
+                        throw new Exception("Your cookie did not work");
+                    }
+
+                    SaveConfig();
+                    IsConfigured = true;
+                    return IndexerConfigurationStatus.Completed;
+                }
+                catch (Exception e)
+                {
+                    IsConfigured = false;
+                    throw new Exception("Your cookie did not work: " + e.Message);
+                }
+            }
+
+            var result = await RequestLoginAndFollowRedirect(SubmitLoginUrl, pairs, configData.CookieHeader.Value, true, null, LoginUrl);
+            await ConfigureIfOK(result.Cookies, result.Content.Contains("logout.php"), () =>
+            {
+                var errorMessage = result.Content;
+                throw new ExceptionWithConfigData(errorMessage, configData);
+            });
+            return IndexerConfigurationStatus.RequiresTesting;
+        }
+
+        public async Task<IEnumerable<ReleaseInfo>> PerformQuery(TorznabQuery query)
+        {
+            List<ReleaseInfo> releases = new List<ReleaseInfo>();
+
+            var searchString = query.GetQueryString();
+            var searchUrl = SearchUrl;
+            var queryCollection = new NameValueCollection();
+            queryCollection.Add("incldead", "1");
+            queryCollection.Add("xtype", "0");
+            queryCollection.Add("stype", "0");
+
+            if (query.ImdbID != null)
+            {
+                queryCollection.Add("search", query.ImdbID);
+            }
+            else if (!string.IsNullOrWhiteSpace(searchString))
+            {
+                queryCollection.Add("search", searchString);
+            }
+
+            foreach (var cat in MapTorznabCapsToTrackers(query))
+            {
+                queryCollection.Add("c" + cat, "1");
+            }
+
+            searchUrl += "?" + queryCollection.GetQueryString();
+
+            var results = await RequestStringWithCookiesAndRetry(searchUrl);
+            try
+            {
+                CQ dom = results.Content;
+
+                var sideWideFreeLeech = false;
+                if (dom.Find("td > b > font[color=\"white\"]:contains(Free Leech)").Length >= 1)
+                    sideWideFreeLeech = true;
+
+                var rows = dom["table > tbody > tr[height=36]"];
+                foreach (var row in rows)
+                {
+                    var release = new ReleaseInfo();
+                    release.MinimumRatio = 1;
+                    release.MinimumSeedTime = 7 * 24 * 60 * 60;
+                    
+                    var qRow = row.Cq();
+                    var qCatLink = qRow.Find("a[href^=?cat]").First();
+                    var qDetailsLink = qRow.Find("a[href^=details.php]").First();
+                    var qSeeders = qRow.Find("td:eq(8)");
+                    var qLeechers = qRow.Find("td:eq(9)");
+                    var qDownloadLink = qRow.Find("a[href^=\"download.php\"]").First();
+                    var qImdbLink = qRow.Find("a[href^=/redir.php?url=http://www.imdb.com]");
+                    var qSize = qRow.Find("td:eq(6)");
+
+                    var catStr = qCatLink.Attr("href").Split('=')[1];
+                    release.Category = MapTrackerCatToNewznab(catStr);
+
+                    release.Link = new Uri(SiteLink + qDownloadLink.Attr("href"));
+                    release.Title = qDetailsLink.Text().Trim();
+                    release.Comments = new Uri(SiteLink + qDetailsLink.Attr("href"));
+                    release.Guid = release.Link;
+
+                    var sizeStr = qSize.Text();
+                    release.Size = ReleaseInfo.GetBytes(sizeStr);
+
+                    if(qImdbLink.Length == 1) { 
+                        var ImdbId = qImdbLink.Attr("href").Split('/').Last().Substring(2);
+                        release.Imdb = ParseUtil.CoerceLong(ImdbId);
+                    }
+
+                    release.Seeders = ParseUtil.CoerceInt(qSeeders.Text());
+                    release.Peers = ParseUtil.CoerceInt(qLeechers.Text()) + release.Seeders;
+
                     var files = qRow.Find("td:nth-child(3)").Text();
                     release.Files = ParseUtil.CoerceInt(files);
 
                     var grabs = qRow.Find("td:nth-child(8)").Get(0).FirstChild.ToString();
                     release.Grabs = ParseUtil.CoerceInt(grabs);
 
-                    if (sideWideFreeLeech || qRow.Find("font[color=\"red\"]:contains(FREE)").Length >= 1)
-                        release.DownloadVolumeFactor = 0;
+                    if (sideWideFreeLeech || qRow.Find("font[color=\"red\"]:contains(FREE)").Length >= 1)
+                        release.DownloadVolumeFactor = 0;
                     else
-                        release.DownloadVolumeFactor = 1;
-                    release.UploadVolumeFactor = 1;
-
-                    releases.Add(release);
-                }
-            }
-            catch (Exception ex)
-            {
-                OnParseError(results.Content, ex);
-            }
-
-            return releases;
-        }
-    }
-}
+                        release.DownloadVolumeFactor = 1;
+                    release.UploadVolumeFactor = 1;
+
+                    releases.Add(release);
+                }
+            }
+            catch (Exception ex)
+            {
+                OnParseError(results.Content, ex);
+            }
+
+            return releases;
+        }
+    }
+}
diff --git a/src/Jackett/JackettModule.cs b/src/Jackett/JackettModule.cs
index 484e726b54eb40f47b495ffcfd81b4fcbf9cdc3b..43501a723c2948c5a048d781b5fec8f0343045c5 100644
--- a/src/Jackett/JackettModule.cs
+++ b/src/Jackett/JackettModule.cs
@@ -1,139 +1,139 @@
-using Autofac;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Autofac.Integration.WebApi;
-using Jackett.Indexers;
-using Jackett.Utils;
-using Jackett.Utils.Clients;
-using AutoMapper;
-using Jackett.Models;
-using System.Reflection;
-
-namespace Jackett
-{
-    public class JackettModule : Autofac.Module
-    {
-        protected override void Load(ContainerBuilder builder)
-        {
-            // Just register everything!
-            var thisAssembly = typeof(JackettModule).Assembly;
-            builder.RegisterAssemblyTypes(thisAssembly).Except<IIndexer>().AsImplementedInterfaces().SingleInstance();
-            builder.RegisterApiControllers(thisAssembly).InstancePerRequest();
-            builder.RegisterType<HttpWebClient>();
-
-            // Register the best web client for the platform or the override
-            switch (Startup.ClientOverride)
-            {
-                case "httpclient":
-                    builder.RegisterType<HttpWebClient>().As<IWebClient>();
-                    break;
-                case "httpclient2":
-                    builder.RegisterType<HttpWebClient2>().As<IWebClient>();
-                    break;
-                case "safecurl":
-                    builder.RegisterType<UnixSafeCurlWebClient>().As<IWebClient>();
-                    break;
-                case "libcurl":
-                    builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
-                    break;
-                case "automatic":
-                    default:
-                    if (System.Environment.OSVersion.Platform == PlatformID.Unix)
-                    {
-                        var usehttpclient = false;
-                        try { 
-                            Type monotype = Type.GetType("Mono.Runtime");
-                            if (monotype != null)
-                            {
-                                MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
-                                if (displayName != null)
-                                { 
-                                    var monoVersion = displayName.Invoke(null, null).ToString();
-                                    var monoVersionO = new Version(monoVersion.Split(' ')[0]);
-                                    if (monoVersionO.Major >= 4 && monoVersionO.Minor >= 8)
-                                    {
-                                        // check if btls is supported
-                                        var monoSecurity = Assembly.Load("Mono.Security");
-                                        Type monoTlsProviderFactory = monoSecurity.GetType("Mono.Security.Interface.MonoTlsProviderFactory");
-                                        if (monoTlsProviderFactory != null)
-                                        {
-                                            MethodInfo isProviderSupported = monoTlsProviderFactory.GetMethod("IsProviderSupported");
-                                            if(isProviderSupported != null)
-                                            {
-                                                var btlsSupported = (bool)isProviderSupported.Invoke(null, new string[] { "btls" });
-                                                if (btlsSupported)
-                                                {
-                                                    // initialize btls
-                                                    MethodInfo initialize = monoTlsProviderFactory.GetMethod("Initialize", new[] { typeof(string) });
-                                                    if (initialize != null)
-                                                    {
-                                                        initialize.Invoke(null, new string[] { "btls" });
-                                                        usehttpclient = true;
-                                                    }
-                                                }
-                                            }
-                                        }
-                                    }
-                                }
-                            }
-                        }
-                        catch (Exception e)
-                        {
-                            Console.Out.WriteLine("Error while deciding which HttpWebClient to use: " + e);
-                        }
-
-                        if (usehttpclient)
-                            builder.RegisterType<HttpWebClient>().As<IWebClient>();
-                        else
-                            builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
-                    }
-                    else
-                    {
-                        builder.RegisterType<HttpWebClient>().As<IWebClient>();
-                    }
-                    break;
-            }
-
-            // Register indexers
-            foreach (var indexer in thisAssembly.GetTypes()
-                .Where(p => typeof(IIndexer).IsAssignableFrom(p) && !p.IsInterface)
-                .ToArray())
-            {
-                builder.RegisterType(indexer).Named<IIndexer>(BaseIndexer.GetIndexerID(indexer));
-            }
-
-            Mapper.CreateMap<WebClientByteResult, WebClientStringResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((be, str) =>
-            {
-                str.Content = Encoding.UTF8.GetString(be.Content);
-            });
-
-            Mapper.CreateMap<WebClientStringResult, WebClientByteResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((str, be) =>
-            {
-                if (!string.IsNullOrEmpty(str.Content))
-                {
-                    be.Content = Encoding.UTF8.GetBytes(str.Content);
-                }
-            });
-
-            Mapper.CreateMap<WebClientStringResult, WebClientStringResult>();
-            Mapper.CreateMap<WebClientByteResult, WebClientByteResult>();
-            Mapper.CreateMap<ReleaseInfo, ReleaseInfo>();
-
-            Mapper.CreateMap<ReleaseInfo, TrackerCacheResult>().AfterMap((r, t) =>
-            {
-                if (r.Category != null)
-                {
-                    var CategoryDesc = string.Join(", ", r.Category.Select(x => TorznabCatType.GetCatDesc(x)).Where(x => !string.IsNullOrEmpty(x)));
-                    t.CategoryDesc = CategoryDesc;
-                }
-                else
-                {
-                    t.CategoryDesc = "";
-                }
-            });
-        }
-    }
-}
+using Autofac;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Autofac.Integration.WebApi;
+using Jackett.Indexers;
+using Jackett.Utils;
+using Jackett.Utils.Clients;
+using AutoMapper;
+using Jackett.Models;
+using System.Reflection;
+
+namespace Jackett
+{
+    public class JackettModule : Autofac.Module
+    {
+        protected override void Load(ContainerBuilder builder)
+        {
+            // Just register everything!
+            var thisAssembly = typeof(JackettModule).Assembly;
+            builder.RegisterAssemblyTypes(thisAssembly).Except<IIndexer>().AsImplementedInterfaces().SingleInstance();
+            builder.RegisterApiControllers(thisAssembly).InstancePerRequest();
+            builder.RegisterType<HttpWebClient>();
+
+            // Register the best web client for the platform or the override
+            switch (Startup.ClientOverride)
+            {
+                case "httpclient":
+                    builder.RegisterType<HttpWebClient>().As<IWebClient>();
+                    break;
+                case "httpclient2":
+                    builder.RegisterType<HttpWebClient2>().As<IWebClient>();
+                    break;
+                case "safecurl":
+                    builder.RegisterType<UnixSafeCurlWebClient>().As<IWebClient>();
+                    break;
+                case "libcurl":
+                    builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
+                    break;
+                case "automatic":
+                    default:
+                    if (System.Environment.OSVersion.Platform == PlatformID.Unix)
+                    {
+                        var usehttpclient = false;
+                        try { 
+                            Type monotype = Type.GetType("Mono.Runtime");
+                            if (monotype != null)
+                            {
+                                MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
+                                if (displayName != null)
+                                { 
+                                    var monoVersion = displayName.Invoke(null, null).ToString();
+                                    var monoVersionO = new Version(monoVersion.Split(' ')[0]);
+                                    if (monoVersionO.Major >= 4 && monoVersionO.Minor >= 8)
+                                    {
+                                        // check if btls is supported
+                                        var monoSecurity = Assembly.Load("Mono.Security");
+                                        Type monoTlsProviderFactory = monoSecurity.GetType("Mono.Security.Interface.MonoTlsProviderFactory");
+                                        if (monoTlsProviderFactory != null)
+                                        {
+                                            MethodInfo isProviderSupported = monoTlsProviderFactory.GetMethod("IsProviderSupported");
+                                            if(isProviderSupported != null)
+                                            {
+                                                var btlsSupported = (bool)isProviderSupported.Invoke(null, new string[] { "btls" });
+                                                if (btlsSupported)
+                                                {
+                                                    // initialize btls
+                                                    MethodInfo initialize = monoTlsProviderFactory.GetMethod("Initialize", new[] { typeof(string) });
+                                                    if (initialize != null)
+                                                    {
+                                                        initialize.Invoke(null, new string[] { "btls" });
+                                                        usehttpclient = true;
+                                                    }
+                                                }
+                                            }
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                        catch (Exception e)
+                        {
+                            Console.Out.WriteLine("Error while deciding which HttpWebClient to use: " + e);
+                        }
+
+                        if (usehttpclient)
+                            builder.RegisterType<HttpWebClient>().As<IWebClient>();
+                        else
+                            builder.RegisterType<UnixLibCurlWebClient>().As<IWebClient>();
+                    }
+                    else
+                    {
+                        builder.RegisterType<HttpWebClient>().As<IWebClient>();
+                    }
+                    break;
+            }
+
+            // Register indexers
+            foreach (var indexer in thisAssembly.GetTypes()
+                .Where(p => typeof(IIndexer).IsAssignableFrom(p) && !p.IsInterface)
+                .ToArray())
+            {
+                builder.RegisterType(indexer).Named<IIndexer>(BaseIndexer.GetIndexerID(indexer));
+            }
+
+            Mapper.CreateMap<WebClientByteResult, WebClientStringResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((be, str) =>
+            {
+                str.Content = Encoding.UTF8.GetString(be.Content);
+            });
+
+            Mapper.CreateMap<WebClientStringResult, WebClientByteResult>().ForMember(x => x.Content, opt => opt.Ignore()).AfterMap((str, be) =>
+            {
+                if (!string.IsNullOrEmpty(str.Content))
+                {
+                    be.Content = Encoding.UTF8.GetBytes(str.Content);
+                }
+            });
+
+            Mapper.CreateMap<WebClientStringResult, WebClientStringResult>();
+            Mapper.CreateMap<WebClientByteResult, WebClientByteResult>();
+            Mapper.CreateMap<ReleaseInfo, ReleaseInfo>();
+
+            Mapper.CreateMap<ReleaseInfo, TrackerCacheResult>().AfterMap((r, t) =>
+            {
+                if (r.Category != null)
+                {
+                    var CategoryDesc = string.Join(", ", r.Category.Select(x => TorznabCatType.GetCatDesc(x)).Where(x => !string.IsNullOrEmpty(x)));
+                    t.CategoryDesc = CategoryDesc;
+                }
+                else
+                {
+                    t.CategoryDesc = "";
+                }
+            });
+        }
+    }
+}
diff --git a/src/Jackett/Models/Config/ServerConfig.cs b/src/Jackett/Models/Config/ServerConfig.cs
index 5b18ee2cd29d8bb8b3eb976e10a53134360ebd26..6f9b604f47ccad051fb6af5cd459211330714c68 100644
--- a/src/Jackett/Models/Config/ServerConfig.cs
+++ b/src/Jackett/Models/Config/ServerConfig.cs
@@ -1,47 +1,47 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.Config
-{
-    public class ServerConfig
-    {
-        public ServerConfig()
-        {
-            Port = 9117;
-            AllowExternal = System.Environment.OSVersion.Platform == PlatformID.Unix;
-        }
-
-        public int Port { get; set; }
-        public bool AllowExternal { get; set; }
-        public string APIKey { get; set; }
-        public string AdminPassword { get; set; }
-        public string InstanceId { get; set; }
-        public string BlackholeDir { get; set; }
-        public bool UpdateDisabled { get; set; }
-        public bool UpdatePrerelease { get; set; }
-        public string BasePathOverride { get; set; }
-
-        public string[] GetListenAddresses(bool? external = null)
-        {
-            if (external == null)
-            {
-                external = AllowExternal;
-            }
-            if (external.Value)
-            {
-                return new string[] { "http://*:" + Port + "/" };
-            }
-            else
-            {
-                return new string[] { 
-                    "http://127.0.0.1:" + Port + "/",
-                    "http://localhost:" + Port + "/",
-                };
-            }
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.Config
+{
+    public class ServerConfig
+    {
+        public ServerConfig()
+        {
+            Port = 9117;
+            AllowExternal = System.Environment.OSVersion.Platform == PlatformID.Unix;
+        }
+
+        public int Port { get; set; }
+        public bool AllowExternal { get; set; }
+        public string APIKey { get; set; }
+        public string AdminPassword { get; set; }
+        public string InstanceId { get; set; }
+        public string BlackholeDir { get; set; }
+        public bool UpdateDisabled { get; set; }
+        public bool UpdatePrerelease { get; set; }
+        public string BasePathOverride { get; set; }
+
+        public string[] GetListenAddresses(bool? external = null)
+        {
+            if (external == null)
+            {
+                external = AllowExternal;
+            }
+            if (external.Value)
+            {
+                return new string[] { "http://*:" + Port + "/" };
+            }
+            else
+            {
+                return new string[] { 
+                    "http://127.0.0.1:" + Port + "/",
+                    "http://localhost:" + Port + "/",
+                };
+            }
+        }
+    }
+}
diff --git a/src/Jackett/Models/GitHub/Asset.cs b/src/Jackett/Models/GitHub/Asset.cs
index 8cc6305d5cd6fe2de4e0360a61bd182af747cfdb..a89a10c3eb1418a466d06331accb2e8b3f1e4682 100644
--- a/src/Jackett/Models/GitHub/Asset.cs
+++ b/src/Jackett/Models/GitHub/Asset.cs
@@ -1,14 +1,14 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.GitHub
-{
-    public class Asset
-    {
-        public string Name { get; set; }
-        public string Browser_download_url { get; set; }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.GitHub
+{
+    public class Asset
+    {
+        public string Name { get; set; }
+        public string Browser_download_url { get; set; }
+    }
+}
diff --git a/src/Jackett/Models/GitHub/Release.cs b/src/Jackett/Models/GitHub/Release.cs
index 4ab187610059481408e8b9c7d6130c5bcf0db223..886afc902c743b1a288db5a5f2b0767a9f78b681 100644
--- a/src/Jackett/Models/GitHub/Release.cs
+++ b/src/Jackett/Models/GitHub/Release.cs
@@ -1,16 +1,16 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.GitHub
-{
-    public class Release
-    {
-        public string Name { set; get; }
-        public DateTime Created_at { get; set; }
-        public bool Prerelease { get; set; }
-        public List<Asset> Assets { set; get; } = new List<Asset>();
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.GitHub
+{
+    public class Release
+    {
+        public string Name { set; get; }
+        public DateTime Created_at { get; set; }
+        public bool Prerelease { get; set; }
+        public List<Asset> Assets { set; get; } = new List<Asset>();
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAbnormal.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAbnormal.cs
index 13a9b7bdf340775135f956a9d3a756d82e8c9cd6..412a4068192d242b091fa3ddbd2d2124a9fd5b7d 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAbnormal.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAbnormal.cs
@@ -1,57 +1,57 @@
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    class ConfigurationDataAbnormal : ConfigurationData
-    {
-        public HiddenItem AuthKey { get; set; }
-        public HiddenItem TorrentPass { get; set; }
-        public DisplayItem CredentialsWarning { get; private set; }
-        public StringItem Username { get; private set; }
-        public StringItem Password { get; private set; }
-        public DisplayItem PagesWarning { get; private set; }
-        public StringItem Pages { get; private set; }
-        public DisplayItem SecurityWarning { get; private set; }
-        public BoolItem Latency { get; private set; }
-        public BoolItem Browser { get; private set; }
-        public DisplayItem LatencyWarning { get; private set; }
-        public StringItem LatencyStart { get; private set; }
-        public StringItem LatencyEnd { get; private set; }
-        public DisplayItem HeadersWarning { get; private set; }
-        public StringItem HeaderAccept { get; private set; }
-        public StringItem HeaderAcceptLang { get; private set; }
-        public BoolItem HeaderDNT { get; private set; }
-        public BoolItem HeaderUpgradeInsecure { get; private set; }
-        public StringItem HeaderUserAgent { get; private set; }
-        public DisplayItem DevWarning { get; private set; }
-        public BoolItem DevMode { get; private set; }
-        public BoolItem HardDriveCache { get; private set; }
-        public StringItem HardDriveCacheKeepTime { get; private set; }
-
-        public ConfigurationDataAbnormal()
-            : base()
-        {
-            AuthKey = new HiddenItem { Name = "AuthKey", Value = "" };
-            TorrentPass = new HiddenItem { Name = "TorrentPass", Value = "" };
-            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
-            Username = new StringItem { Name = "Username (Required)", Value = "" };
-            Password = new StringItem { Name = "Password (Required)", Value = "" };
-            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li><li><b>With Dead Torrents</b> let you search <u>with</u> torrents which are marked Dead.</li><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li><li><b>With Nuked Releases</b> let you search <u>with</u> torrents which are marked Nuked.</li><li><b>3D Releases Only</b> let you search <u>only</u> for torrents which are marked 3D.</li><li><b>French Only</b> let you search <u>only</u> for torrents which are marked FRENCH or TRUEFRENCH (<i>MULTI not included !</i>).</li></ul>") { Name  = "Preferences" };
-            Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
-            SecurityWarning = new DisplayItem("<b>Security Configuration</b> (<i>Read this area carefully !</i>),<br /><br /> <ul><li><b>Latency Simulation</b> will simulate human browsing with Jacket by pausing Jacket for an random time between each request, to fake a real content browsing.</li><li><b>Browser Simulation</b> will simulate a real human browser by injecting additionals headers when doing requests to tracker.</li></ul>") { Name = "Security" };
-            Latency = new BoolItem() { Name = "Latency Simulation (Optional)", Value = false };
-            Browser = new BoolItem() { Name = "Browser Simulation (Optional)", Value = true };
-            LatencyWarning = new DisplayItem("<b>Latency Configuration</b> (<i>Required if latency simulation enabled</i>),<br /><br/> <ul><li>By filling this range, <b>Jackett will make a random timed pause</b> <u>between requests</u> to tracker <u>to simulate a real browser</u>.</li><li>MilliSeconds <b>only</b></li></ul>") { Name = "Simulate Latency" };
-            LatencyStart = new StringItem { Name = "Minimum Latency (ms)", Value = "1589" };
-            LatencyEnd = new StringItem { Name = "Maximum Latency (ms)", Value = "3674" };
-            HeadersWarning = new DisplayItem("<b>Browser Headers Configuration</b> (<i>Required if browser simulation enabled</i>),<br /><br /> <ul><li>By filling these fields, <b>Jackett will inject headers</b> with your values <u>to simulate a real browser</u>.</li><li>You can get <b>your browser values</b> here: <a href='https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' target='blank'>www.whatismybrowser.com</a></li></ul><br /><i><b>Note that</b> some headers are not necessary because they are injected automatically by this provider such as Accept_Encoding, Connection, Host or X-Requested-With</i>") { Name = "Injecting headers" };
-            HeaderAccept = new StringItem { Name = "Accept", Value = "" };
-            HeaderAcceptLang = new StringItem { Name = "Accept-Language", Value = "" };
-            HeaderDNT = new BoolItem { Name = "DNT", Value = false };
-            HeaderUpgradeInsecure = new BoolItem { Name = "Upgrade-Insecure-Requests", Value = false };
-            HeaderUserAgent = new StringItem { Name = "User-Agent", Value = "" };
-            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
-            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
-            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
-            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
-            }
-    }
-}
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    class ConfigurationDataAbnormal : ConfigurationData
+    {
+        public HiddenItem AuthKey { get; set; }
+        public HiddenItem TorrentPass { get; set; }
+        public DisplayItem CredentialsWarning { get; private set; }
+        public StringItem Username { get; private set; }
+        public StringItem Password { get; private set; }
+        public DisplayItem PagesWarning { get; private set; }
+        public StringItem Pages { get; private set; }
+        public DisplayItem SecurityWarning { get; private set; }
+        public BoolItem Latency { get; private set; }
+        public BoolItem Browser { get; private set; }
+        public DisplayItem LatencyWarning { get; private set; }
+        public StringItem LatencyStart { get; private set; }
+        public StringItem LatencyEnd { get; private set; }
+        public DisplayItem HeadersWarning { get; private set; }
+        public StringItem HeaderAccept { get; private set; }
+        public StringItem HeaderAcceptLang { get; private set; }
+        public BoolItem HeaderDNT { get; private set; }
+        public BoolItem HeaderUpgradeInsecure { get; private set; }
+        public StringItem HeaderUserAgent { get; private set; }
+        public DisplayItem DevWarning { get; private set; }
+        public BoolItem DevMode { get; private set; }
+        public BoolItem HardDriveCache { get; private set; }
+        public StringItem HardDriveCacheKeepTime { get; private set; }
+
+        public ConfigurationDataAbnormal()
+            : base()
+        {
+            AuthKey = new HiddenItem { Name = "AuthKey", Value = "" };
+            TorrentPass = new HiddenItem { Name = "TorrentPass", Value = "" };
+            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
+            Username = new StringItem { Name = "Username (Required)", Value = "" };
+            Password = new StringItem { Name = "Password (Required)", Value = "" };
+            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li><li><b>With Dead Torrents</b> let you search <u>with</u> torrents which are marked Dead.</li><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li><li><b>With Nuked Releases</b> let you search <u>with</u> torrents which are marked Nuked.</li><li><b>3D Releases Only</b> let you search <u>only</u> for torrents which are marked 3D.</li><li><b>French Only</b> let you search <u>only</u> for torrents which are marked FRENCH or TRUEFRENCH (<i>MULTI not included !</i>).</li></ul>") { Name  = "Preferences" };
+            Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
+            SecurityWarning = new DisplayItem("<b>Security Configuration</b> (<i>Read this area carefully !</i>),<br /><br /> <ul><li><b>Latency Simulation</b> will simulate human browsing with Jacket by pausing Jacket for an random time between each request, to fake a real content browsing.</li><li><b>Browser Simulation</b> will simulate a real human browser by injecting additionals headers when doing requests to tracker.</li></ul>") { Name = "Security" };
+            Latency = new BoolItem() { Name = "Latency Simulation (Optional)", Value = false };
+            Browser = new BoolItem() { Name = "Browser Simulation (Optional)", Value = true };
+            LatencyWarning = new DisplayItem("<b>Latency Configuration</b> (<i>Required if latency simulation enabled</i>),<br /><br/> <ul><li>By filling this range, <b>Jackett will make a random timed pause</b> <u>between requests</u> to tracker <u>to simulate a real browser</u>.</li><li>MilliSeconds <b>only</b></li></ul>") { Name = "Simulate Latency" };
+            LatencyStart = new StringItem { Name = "Minimum Latency (ms)", Value = "1589" };
+            LatencyEnd = new StringItem { Name = "Maximum Latency (ms)", Value = "3674" };
+            HeadersWarning = new DisplayItem("<b>Browser Headers Configuration</b> (<i>Required if browser simulation enabled</i>),<br /><br /> <ul><li>By filling these fields, <b>Jackett will inject headers</b> with your values <u>to simulate a real browser</u>.</li><li>You can get <b>your browser values</b> here: <a href='https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' target='blank'>www.whatismybrowser.com</a></li></ul><br /><i><b>Note that</b> some headers are not necessary because they are injected automatically by this provider such as Accept_Encoding, Connection, Host or X-Requested-With</i>") { Name = "Injecting headers" };
+            HeaderAccept = new StringItem { Name = "Accept", Value = "" };
+            HeaderAcceptLang = new StringItem { Name = "Accept-Language", Value = "" };
+            HeaderDNT = new BoolItem { Name = "DNT", Value = false };
+            HeaderUpgradeInsecure = new BoolItem { Name = "Upgrade-Insecure-Requests", Value = false };
+            HeaderUserAgent = new StringItem { Name = "User-Agent", Value = "" };
+            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
+            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
+            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
+            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
+            }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAnimeBytes.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAnimeBytes.cs
index 1c009acc2a6b8afa448408b5a7e1c8532d2f8c73..601974f026b60c76a8d1214425d4cb6ccc72fd01 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAnimeBytes.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataAnimeBytes.cs
@@ -1,24 +1,24 @@
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    class ConfigurationDataAnimeBytes : ConfigurationDataBasicLogin
-    {
-        public BoolItem IncludeRaw { get; private set; }
-        public DisplayItem DateWarning { get; private set; }
-        public BoolItem InsertSeason { get; private set; }
-
-        public ConfigurationDataAnimeBytes()
-            : base()
-        {
-            IncludeRaw = new BoolItem() { Name = "IncludeRaw", Value = false };
-            DateWarning = new DisplayItem("This tracker does not supply upload dates so they are based off year of release.") { Name = "DateWarning" };
-            InsertSeason = new BoolItem() { Name = "Prefix episode number with S01 for Sonarr Compatability", Value = false };
-        }
-    }
-}
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    class ConfigurationDataAnimeBytes : ConfigurationDataBasicLogin
+    {
+        public BoolItem IncludeRaw { get; private set; }
+        public DisplayItem DateWarning { get; private set; }
+        public BoolItem InsertSeason { get; private set; }
+
+        public ConfigurationDataAnimeBytes()
+            : base()
+        {
+            IncludeRaw = new BoolItem() { Name = "IncludeRaw", Value = false };
+            DateWarning = new DisplayItem("This tracker does not supply upload dates so they are based off year of release.") { Name = "DateWarning" };
+            InsertSeason = new BoolItem() { Name = "Prefix episode number with S01 for Sonarr Compatability", Value = false };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataFileList.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataFileList.cs
index 54c475ddc0d191b50dd5ba95eba351ba3390b6de..c3d01bb96dc401df4e0d3dce6a2a9f7c06172b38 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataFileList.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataFileList.cs
@@ -1,22 +1,22 @@
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    class ConfigurationDataFileList : ConfigurationDataBasicLogin
-    {
-        public BoolItem IncludeRomanianReleases { get; private set; }
-        public DisplayItem CatWarning { get; private set; }
-
-        public ConfigurationDataFileList()
-            : base()
-        {
-            IncludeRomanianReleases = new BoolItem() { Name = "IncludeRomanianReleases", Value = false };
-            CatWarning = new DisplayItem("When mapping TV ensure you add category 5000 in addition to 5030,5040.") { Name = "CatWarning" };
-        }
-    }
-}
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    class ConfigurationDataFileList : ConfigurationDataBasicLogin
+    {
+        public BoolItem IncludeRomanianReleases { get; private set; }
+        public DisplayItem CatWarning { get; private set; }
+
+        public ConfigurationDataFileList()
+            : base()
+        {
+            IncludeRomanianReleases = new BoolItem() { Name = "IncludeRomanianReleases", Value = false };
+            CatWarning = new DisplayItem("When mapping TV ensure you add category 5000 in addition to 5030,5040.") { Name = "CatWarning" };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataNCore.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataNCore.cs
index 067a312d812b814ebef64fb9ae46f52ef4bf896d..886ae4d02fa6984eaf0a6267c3c6cb18b784e871 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataNCore.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataNCore.cs
@@ -1,62 +1,62 @@
-using Newtonsoft.Json;
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    public class ConfigurationDataNCore : ConfigurationData
-    {
-        public StringItem Username { get; private set; }
-        public StringItem Password { get; private set; }
-        public BoolItem Hungarian { get; set; }
-        public BoolItem English { get; set; }
-
-        public ConfigurationDataNCore()
-        {
-            Username = new StringItem { Name = "Username", Value = "" };
-            Password = new StringItem { Name = "Password", Value = "" };
-            Hungarian = new BoolItem { Name = "Hungarian", Value = true };
-            English = new BoolItem { Name = "English", Value = true };
-        }
-
-        public ConfigurationDataNCore(JToken json)
-        {
-            ConfigurationDataNCore configData = new ConfigurationDataNCore();
-
-            dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
-            foreach (var config in configArray)
-            {
-                string propertyName = UppercaseFirst((string)config.id);
-                switch (propertyName)
-                {
-                    case "Username":
-                        Username = new StringItem { Name = propertyName, Value = config.value };
-                        break;
-                    case "Password":
-                        Password = new StringItem { Name = propertyName, Value = config.value };
-                        break;
-                    case "Hungarian":
-                        Hungarian = new BoolItem { Name = propertyName, Value = config.value };
-                        break;
-                    case "English":
-                        English = new BoolItem { Name = propertyName, Value = config.value };
-                        break;
-                    default:
-                        break;
-                }
-            }
-        }
-
-        static string UppercaseFirst(string s)
-        {
-            if (string.IsNullOrEmpty(s))
-                return string.Empty;
-            return char.ToUpper(s[0]) + s.Substring(1);
-        }
-    }
+using Newtonsoft.Json;
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    public class ConfigurationDataNCore : ConfigurationData
+    {
+        public StringItem Username { get; private set; }
+        public StringItem Password { get; private set; }
+        public BoolItem Hungarian { get; set; }
+        public BoolItem English { get; set; }
+
+        public ConfigurationDataNCore()
+        {
+            Username = new StringItem { Name = "Username", Value = "" };
+            Password = new StringItem { Name = "Password", Value = "" };
+            Hungarian = new BoolItem { Name = "Hungarian", Value = true };
+            English = new BoolItem { Name = "English", Value = true };
+        }
+
+        public ConfigurationDataNCore(JToken json)
+        {
+            ConfigurationDataNCore configData = new ConfigurationDataNCore();
+
+            dynamic configArray = JsonConvert.DeserializeObject(json.ToString());
+            foreach (var config in configArray)
+            {
+                string propertyName = UppercaseFirst((string)config.id);
+                switch (propertyName)
+                {
+                    case "Username":
+                        Username = new StringItem { Name = propertyName, Value = config.value };
+                        break;
+                    case "Password":
+                        Password = new StringItem { Name = propertyName, Value = config.value };
+                        break;
+                    case "Hungarian":
+                        Hungarian = new BoolItem { Name = propertyName, Value = config.value };
+                        break;
+                    case "English":
+                        English = new BoolItem { Name = propertyName, Value = config.value };
+                        break;
+                    default:
+                        break;
+                }
+            }
+        }
+
+        static string UppercaseFirst(string s)
+        {
+            if (string.IsNullOrEmpty(s))
+                return string.Empty;
+            return char.ToUpper(s[0]) + s.Substring(1);
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataPhxBit.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataPhxBit.cs
index 07b2c23975deef075330d1311f94f11b7335f935..00cadb309d20ce39b831eddc1d48372ed309aa75 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataPhxBit.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataPhxBit.cs
@@ -1,55 +1,55 @@
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    class ConfigurationDataPhxBit : ConfigurationData
-    {
-        public HiddenItem PassKey { get; set; }
-        public DisplayItem CredentialsWarning { get; private set; }
-        public StringItem Username { get; private set; }
-        public StringItem Password { get; private set; }
-        public DisplayItem PagesWarning { get; private set; }
-        public StringItem Pages { get; private set; }
-        public DisplayItem SecurityWarning { get; private set; }
-        public BoolItem Latency { get; private set; }
-        public BoolItem Browser { get; private set; }
-        public DisplayItem LatencyWarning { get; private set; }
-        public StringItem LatencyStart { get; private set; }
-        public StringItem LatencyEnd { get; private set; }
-        public DisplayItem HeadersWarning { get; private set; }
-        public StringItem HeaderAccept { get; private set; }
-        public StringItem HeaderAcceptLang { get; private set; }
-        public BoolItem HeaderDNT { get; private set; }
-        public BoolItem HeaderUpgradeInsecure { get; private set; }
-        public StringItem HeaderUserAgent { get; private set; }
-        public DisplayItem DevWarning { get; private set; }
-        public BoolItem DevMode { get; private set; }
-        public BoolItem HardDriveCache { get; private set; }
-        public StringItem HardDriveCacheKeepTime { get; private set; }
-
-        public ConfigurationDataPhxBit()
-            : base()
-        {
-            PassKey = new HiddenItem { Name = "PassKey", Value = "" };
-            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
-            Username = new StringItem { Name = "Username (Required)", Value = "" };
-            Password = new StringItem { Name = "Password (Required)", Value = "" };
-            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li></ul>") { Name  = "Preferences" };
-            Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
-            SecurityWarning = new DisplayItem("<b>Security Configuration</b> (<i>Read this area carefully !</i>),<br /><br /> <ul><li><b>Latency Simulation</b> will simulate human browsing with Jacket by pausing Jacket for an random time between each request, to fake a real content browsing.</li><li><b>Browser Simulation</b> will simulate a real human browser by injecting additionals headers when doing requests to tracker.</li></ul>") { Name = "Security" };
-            Latency = new BoolItem() { Name = "Latency Simulation (Optional)", Value = false };
-            Browser = new BoolItem() { Name = "Browser Simulation (Optional)", Value = true };
-            LatencyWarning = new DisplayItem("<b>Latency Configuration</b> (<i>Required if latency simulation enabled</i>),<br /><br/> <ul><li>By filling this range, <b>Jackett will make a random timed pause</b> <u>between requests</u> to tracker <u>to simulate a real browser</u>.</li><li>MilliSeconds <b>only</b></li></ul>") { Name = "Simulate Latency" };
-            LatencyStart = new StringItem { Name = "Minimum Latency (ms)", Value = "1589" };
-            LatencyEnd = new StringItem { Name = "Maximum Latency (ms)", Value = "3674" };
-            HeadersWarning = new DisplayItem("<b>Browser Headers Configuration</b> (<i>Required if browser simulation enabled</i>),<br /><br /> <ul><li>By filling these fields, <b>Jackett will inject headers</b> with your values <u>to simulate a real browser</u>.</li><li>You can get <b>your browser values</b> here: <a href='https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' target='blank'>www.whatismybrowser.com</a></li></ul><br /><i><b>Note that</b> some headers are not necessary because they are injected automatically by this provider such as Accept_Encoding, Connection, Host or X-Requested-With</i>") { Name = "Injecting headers" };
-            HeaderAccept = new StringItem { Name = "Accept", Value = "" };
-            HeaderAcceptLang = new StringItem { Name = "Accept-Language", Value = "" };
-            HeaderDNT = new BoolItem { Name = "DNT", Value = false };
-            HeaderUpgradeInsecure = new BoolItem { Name = "Upgrade-Insecure-Requests", Value = false };
-            HeaderUserAgent = new StringItem { Name = "User-Agent", Value = "" };
-            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
-            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
-            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
-            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
-            }
-    }
-}
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    class ConfigurationDataPhxBit : ConfigurationData
+    {
+        public HiddenItem PassKey { get; set; }
+        public DisplayItem CredentialsWarning { get; private set; }
+        public StringItem Username { get; private set; }
+        public StringItem Password { get; private set; }
+        public DisplayItem PagesWarning { get; private set; }
+        public StringItem Pages { get; private set; }
+        public DisplayItem SecurityWarning { get; private set; }
+        public BoolItem Latency { get; private set; }
+        public BoolItem Browser { get; private set; }
+        public DisplayItem LatencyWarning { get; private set; }
+        public StringItem LatencyStart { get; private set; }
+        public StringItem LatencyEnd { get; private set; }
+        public DisplayItem HeadersWarning { get; private set; }
+        public StringItem HeaderAccept { get; private set; }
+        public StringItem HeaderAcceptLang { get; private set; }
+        public BoolItem HeaderDNT { get; private set; }
+        public BoolItem HeaderUpgradeInsecure { get; private set; }
+        public StringItem HeaderUserAgent { get; private set; }
+        public DisplayItem DevWarning { get; private set; }
+        public BoolItem DevMode { get; private set; }
+        public BoolItem HardDriveCache { get; private set; }
+        public StringItem HardDriveCacheKeepTime { get; private set; }
+
+        public ConfigurationDataPhxBit()
+            : base()
+        {
+            PassKey = new HiddenItem { Name = "PassKey", Value = "" };
+            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>Username</b> is your account name on this tracker.</li><li><b>Password</b> is your password associated to your account name.</li></ul>") { Name = "Credentials" };
+            Username = new StringItem { Name = "Username (Required)", Value = "" };
+            Password = new StringItem { Name = "Password (Required)", Value = "" };
+            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Max Pages to Process</b> let you specify how many page (max) Jackett can process when doing a search. Setting a value <b>higher than 4 is dangerous</b> for you account ! (<b>Result of too many requests to tracker...that <u>will be suspect</u></b>).</li></ul>") { Name  = "Preferences" };
+            Pages = new StringItem { Name = "Max Pages to Process (Required)", Value = "4" };
+            SecurityWarning = new DisplayItem("<b>Security Configuration</b> (<i>Read this area carefully !</i>),<br /><br /> <ul><li><b>Latency Simulation</b> will simulate human browsing with Jacket by pausing Jacket for an random time between each request, to fake a real content browsing.</li><li><b>Browser Simulation</b> will simulate a real human browser by injecting additionals headers when doing requests to tracker.</li></ul>") { Name = "Security" };
+            Latency = new BoolItem() { Name = "Latency Simulation (Optional)", Value = false };
+            Browser = new BoolItem() { Name = "Browser Simulation (Optional)", Value = true };
+            LatencyWarning = new DisplayItem("<b>Latency Configuration</b> (<i>Required if latency simulation enabled</i>),<br /><br/> <ul><li>By filling this range, <b>Jackett will make a random timed pause</b> <u>between requests</u> to tracker <u>to simulate a real browser</u>.</li><li>MilliSeconds <b>only</b></li></ul>") { Name = "Simulate Latency" };
+            LatencyStart = new StringItem { Name = "Minimum Latency (ms)", Value = "1589" };
+            LatencyEnd = new StringItem { Name = "Maximum Latency (ms)", Value = "3674" };
+            HeadersWarning = new DisplayItem("<b>Browser Headers Configuration</b> (<i>Required if browser simulation enabled</i>),<br /><br /> <ul><li>By filling these fields, <b>Jackett will inject headers</b> with your values <u>to simulate a real browser</u>.</li><li>You can get <b>your browser values</b> here: <a href='https://www.whatismybrowser.com/detect/what-http-headers-is-my-browser-sending' target='blank'>www.whatismybrowser.com</a></li></ul><br /><i><b>Note that</b> some headers are not necessary because they are injected automatically by this provider such as Accept_Encoding, Connection, Host or X-Requested-With</i>") { Name = "Injecting headers" };
+            HeaderAccept = new StringItem { Name = "Accept", Value = "" };
+            HeaderAcceptLang = new StringItem { Name = "Accept-Language", Value = "" };
+            HeaderDNT = new BoolItem { Name = "DNT", Value = false };
+            HeaderUpgradeInsecure = new BoolItem { Name = "Upgrade-Insecure-Requests", Value = false };
+            HeaderUserAgent = new StringItem { Name = "User-Agent", Value = "" };
+            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
+            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
+            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
+            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
+            }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataRuTor.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataRuTor.cs
index aed0f1391fa35e18d51ed93ee92d565f8884fb3f..83db0b1687a5780992204b5ea425e6044767780a 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataRuTor.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataRuTor.cs
@@ -1,27 +1,27 @@
-using Newtonsoft.Json;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    public class ConfigurationDataRuTor : ConfigurationData
-    {
-        [JsonProperty]
-        public StringItem Url { get; private set; }
-        [JsonProperty]
-        public BoolItem StripRussian { get; private set; }
-
-        public ConfigurationDataRuTor()
-        {
-        }
-
-        public ConfigurationDataRuTor(string defaultUrl)
-        {
-            Url = new StringItem { Name = "Url", Value = defaultUrl };
-            StripRussian = new BoolItem() { Name = "StripRusNamePrefix", Value = true };
-        }
-    }
-}
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    public class ConfigurationDataRuTor : ConfigurationData
+    {
+        [JsonProperty]
+        public StringItem Url { get; private set; }
+        [JsonProperty]
+        public BoolItem StripRussian { get; private set; }
+
+        public ConfigurationDataRuTor()
+        {
+        }
+
+        public ConfigurationDataRuTor(string defaultUrl)
+        {
+            Url = new StringItem { Name = "Url", Value = defaultUrl };
+            StripRussian = new BoolItem() { Name = "StripRusNamePrefix", Value = true };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataStrike.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataStrike.cs
index ba39425b0d177f6ae8c10feab1126ae9ea7221ef..938ed4cea4cc476261f913a5d310d592fc875db1 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataStrike.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataStrike.cs
@@ -1,18 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    public class ConfigurationDataStrike : ConfigurationDataUrl
-    {
-        public DisplayItem StrikeWarning { get; private set; }
-
-        public ConfigurationDataStrike(string url) : base(url)
-        {
-            StrikeWarning = new DisplayItem("This indexer does not support RSS Sync, only Search") { Name = "Warning" };
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    public class ConfigurationDataStrike : ConfigurationDataUrl
+    {
+        public DisplayItem StrikeWarning { get; private set; }
+
+        public ConfigurationDataStrike(string url) : base(url)
+        {
+            StrikeWarning = new DisplayItem("This indexer does not support RSS Sync, only Search") { Name = "Warning" };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataXthor.cs b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataXthor.cs
index b0f8c9dc36d78936ac393dc8adef718c4482a801..d05c350ace4e25509c6cd2812b3c33c6f337055b 100644
--- a/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataXthor.cs
+++ b/src/Jackett/Models/IndexerConfig/Bespoke/ConfigurationDataXthor.cs
@@ -1,27 +1,27 @@
-namespace Jackett.Models.IndexerConfig.Bespoke
-{
-    class ConfigurationDataXthor : ConfigurationData
-    {
-        public DisplayItem CredentialsWarning { get; private set; }
-        public StringItem PassKey { get; set; }
-        public DisplayItem PagesWarning { get; private set; }
-        public BoolItem Freeleech { get; private set; }
-        public DisplayItem DevWarning { get; private set; }
-        public BoolItem DevMode { get; private set; }
-        public BoolItem HardDriveCache { get; private set; }
-        public StringItem HardDriveCacheKeepTime { get; private set; }
-
-        public ConfigurationDataXthor()
-            : base()
-        {
-            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>PassKey</b> is your private key on your account</li></ul>") { Name = "Credentials" };
-            PassKey = new StringItem { Name = "PassKey", Value = "" };
-            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li></ul>") { Name  = "Preferences" };
-            Freeleech = new BoolItem() { Name = "Freeleech Only (Optional)", Value = false };
-            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
-            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
-            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
-            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
-            }
-    }
-}
+namespace Jackett.Models.IndexerConfig.Bespoke
+{
+    class ConfigurationDataXthor : ConfigurationData
+    {
+        public DisplayItem CredentialsWarning { get; private set; }
+        public StringItem PassKey { get; set; }
+        public DisplayItem PagesWarning { get; private set; }
+        public BoolItem Freeleech { get; private set; }
+        public DisplayItem DevWarning { get; private set; }
+        public BoolItem DevMode { get; private set; }
+        public BoolItem HardDriveCache { get; private set; }
+        public StringItem HardDriveCacheKeepTime { get; private set; }
+
+        public ConfigurationDataXthor()
+            : base()
+        {
+            CredentialsWarning = new DisplayItem("<b>Credentials Configuration</b> (<i>Private Tracker</i>),<br /><br /> <ul><li><b>PassKey</b> is your private key on your account</li></ul>") { Name = "Credentials" };
+            PassKey = new StringItem { Name = "PassKey", Value = "" };
+            PagesWarning = new DisplayItem("<b>Preferences Configuration</b> (<i>Tweak your search settings</i>),<br /><br /> <ul><li><b>Freeleech Only</b> let you search <u>only</u> for torrents which are marked Freeleech.</li></ul>") { Name  = "Preferences" };
+            Freeleech = new BoolItem() { Name = "Freeleech Only (Optional)", Value = false };
+            DevWarning = new DisplayItem("<b>Development Facility</b> (<i>For Developers ONLY</i>),<br /><br /> <ul><li>By enabling development mode, <b>Jackett will bypass his cache</b> and will <u>output debug messages to console</u> instead of his log file.</li><li>By enabling Hard Drive Cache, <b>This provider</b> will <u>save each query answers from tracker</u> in temp directory, in fact this reduce drastically HTTP requests when building a provider at parsing step for example. So, <b> Jackett will search for a cached query answer on hard drive before executing query on tracker side !</b> <i>DEV MODE must be enabled to use it !</li></ul>") { Name = "Development" };
+            DevMode = new BoolItem { Name = "Enable DEV MODE (Developers ONLY)", Value = false };
+            HardDriveCache = new BoolItem { Name = "Enable HARD DRIVE CACHE (Developers ONLY)", Value = false };
+            HardDriveCacheKeepTime = new StringItem { Name = "Keep Cached files for (ms)", Value = "300000" };
+            }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/ConfigurationData.cs b/src/Jackett/Models/IndexerConfig/ConfigurationData.cs
index ba89535ca2cd0f5f4e6670b6f2b6e6be3c214bb1..ee67297f94a1eb6a73a7532cf303075ee3b33c05 100644
--- a/src/Jackett/Models/IndexerConfig/ConfigurationData.cs
+++ b/src/Jackett/Models/IndexerConfig/ConfigurationData.cs
@@ -48,9 +48,9 @@ namespace Jackett.Models.IndexerConfig
 
             // transistion from alternatelink to sitelink
             var alternatelinkItem = arr.FirstOrDefault(f => f.Value<string>("id") == "alternatelink");
-            if (alternatelinkItem != null && !string.IsNullOrEmpty(alternatelinkItem.Value<string>("value")))
-            {
-                //SiteLink.Value = alternatelinkItem.Value<string>("value");
+            if (alternatelinkItem != null && !string.IsNullOrEmpty(alternatelinkItem.Value<string>("value")))
+            {
+                //SiteLink.Value = alternatelinkItem.Value<string>("value");
             }
 
             foreach (var item in GetItems(forDisplay: false))
@@ -73,7 +73,7 @@ namespace Jackett.Models.IndexerConfig
                                 if (ps != null)
                                     sItem.Value = ps.UnProtect(newValue);
                             }
-                        }
+                        }
                         else
                         {
                             sItem.Value = newValue;
@@ -145,9 +145,9 @@ namespace Jackett.Models.IndexerConfig
                 .GetProperties()
                 .Where(p => p.CanRead)
                 .Where(p => p.PropertyType.IsSubclassOf(typeof(Item)))
-                .Select(p => (Item)p.GetValue(this)).ToList();
-
-            // remove/insert Site Link manualy to make sure it shows up first
+                .Select(p => (Item)p.GetValue(this)).ToList();
+
+            // remove/insert Site Link manualy to make sure it shows up first
             properties.Remove(SiteLink);
             properties.Insert(0, SiteLink);
 
@@ -163,21 +163,21 @@ namespace Jackett.Models.IndexerConfig
             return properties.ToArray();
         }
 
-        public void AddDynamic(string ID, Item item)
-        {
-            dynamics[ID] = item;
+        public void AddDynamic(string ID, Item item)
+        {
+            dynamics[ID] = item;
         }
 
-        public Item GetDynamic(string ID)
-        {
-            try
-            {
-                return dynamics[ID];
-            }
-            catch(KeyNotFoundException)
-            {
-                return null;
-            }
+        public Item GetDynamic(string ID)
+        {
+            try
+            {
+                return dynamics[ID];
+            }
+            catch(KeyNotFoundException)
+            {
+                return null;
+            }
         }
 
         public class Item
diff --git a/src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs b/src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs
index 30fd25ee5ea50766a45739342c03c22c2b159329..ace73475bf3cd08db1b1891d1a5b49f87857aa6e 100644
--- a/src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs
+++ b/src/Jackett/Models/IndexerConfig/ConfigurationDataAPIKey.cs
@@ -1,18 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig
-{
-    public class ConfigurationDataAPIKey : ConfigurationData
-    {
-        public ConfigurationData.StringItem Key { get; private set; }
-
-        public ConfigurationDataAPIKey()
-        {
-            Key = new ConfigurationData.StringItem { Name = "APIKey", Value = string.Empty };
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig
+{
+    public class ConfigurationDataAPIKey : ConfigurationData
+    {
+        public ConfigurationData.StringItem Key { get; private set; }
+
+        public ConfigurationDataAPIKey()
+        {
+            Key = new ConfigurationData.StringItem { Name = "APIKey", Value = string.Empty };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/ConfigurationDataBasicLoginWithRSSAndDisplay.cs b/src/Jackett/Models/IndexerConfig/ConfigurationDataBasicLoginWithRSSAndDisplay.cs
index 981d6117dbf9435f45d8cee9f0c6b83f7e42a7b0..74275f41934424f277f1140241b6e2507cc776db 100644
--- a/src/Jackett/Models/IndexerConfig/ConfigurationDataBasicLoginWithRSSAndDisplay.cs
+++ b/src/Jackett/Models/IndexerConfig/ConfigurationDataBasicLoginWithRSSAndDisplay.cs
@@ -1,25 +1,25 @@
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig
-{
-    public class ConfigurationDataBasicLoginWithRSSAndDisplay : ConfigurationData
-    {
-        public StringItem Username { get; private set; }
-        public StringItem Password { get; private set; }
-        public HiddenItem RSSKey { get; private set; }
-        public DisplayItem DisplayText { get; private set; }
-
-        public ConfigurationDataBasicLoginWithRSSAndDisplay()
-        {
-            Username = new StringItem { Name = "Username" };
-            Password = new StringItem { Name = "Password" };
-            RSSKey = new HiddenItem { Name = "RSSKey" };
-            DisplayText = new DisplayItem(""){ Name = "" };
-        }
-    }
-}
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig
+{
+    public class ConfigurationDataBasicLoginWithRSSAndDisplay : ConfigurationData
+    {
+        public StringItem Username { get; private set; }
+        public StringItem Password { get; private set; }
+        public HiddenItem RSSKey { get; private set; }
+        public DisplayItem DisplayText { get; private set; }
+
+        public ConfigurationDataBasicLoginWithRSSAndDisplay()
+        {
+            Username = new StringItem { Name = "Username" };
+            Password = new StringItem { Name = "Password" };
+            RSSKey = new HiddenItem { Name = "RSSKey" };
+            DisplayText = new DisplayItem(""){ Name = "" };
+        }
+    }
+}
diff --git a/src/Jackett/Models/IndexerConfig/ConfigurationDataLoginLink.cs b/src/Jackett/Models/IndexerConfig/ConfigurationDataLoginLink.cs
index c3f2434dc207119740ec39043902be2135bdcaed..030589f93ee5800fbf244cd0882b386954fcebc6 100644
--- a/src/Jackett/Models/IndexerConfig/ConfigurationDataLoginLink.cs
+++ b/src/Jackett/Models/IndexerConfig/ConfigurationDataLoginLink.cs
@@ -1,23 +1,23 @@
-using Newtonsoft.Json.Linq;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Models.IndexerConfig
-{
-    public class ConfigurationDataLoginLink : ConfigurationData
-    {
-        public StringItem LoginLink { get; private set; }
-        public HiddenItem RSSKey { get; private set; }
-        public DisplayItem DisplayText { get; private set; }
-
-        public ConfigurationDataLoginLink()
-        {
-            LoginLink = new StringItem { Name = "Login Link" };
-            RSSKey = new HiddenItem { Name = "RSSKey" };
-            DisplayText = new DisplayItem(""){ Name = "" };
-        }
-    }
-}
+using Newtonsoft.Json.Linq;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Models.IndexerConfig
+{
+    public class ConfigurationDataLoginLink : ConfigurationData
+    {
+        public StringItem LoginLink { get; private set; }
+        public HiddenItem RSSKey { get; private set; }
+        public DisplayItem DisplayText { get; private set; }
+
+        public ConfigurationDataLoginLink()
+        {
+            LoginLink = new StringItem { Name = "Login Link" };
+            RSSKey = new HiddenItem { Name = "RSSKey" };
+            DisplayText = new DisplayItem(""){ Name = "" };
+        }
+    }
+}
diff --git a/src/Jackett/Models/ReleaseInfo.cs b/src/Jackett/Models/ReleaseInfo.cs
index b6ca12cc7ceccb9f8325f19631e61ba8a2267c18..e93671b307ae90b79784af7d3ad1adc2915dacf6 100644
--- a/src/Jackett/Models/ReleaseInfo.cs
+++ b/src/Jackett/Models/ReleaseInfo.cs
@@ -18,8 +18,8 @@ namespace Jackett.Models
         public Uri Comments { get; set; }
         public DateTime PublishDate { get; set; }
         public ICollection<int> Category { get; set; }
-        public long? Size { get; set; }
-        public long? Files { get; set; }
+        public long? Size { get; set; }
+        public long? Files { get; set; }
         public long? Grabs { get; set; }
         public string Description { get; set; }
         public long? RageID { get; set; }
@@ -46,8 +46,8 @@ namespace Jackett.Models
                 Comments = Comments,
                 PublishDate = PublishDate,
                 Category = Category,
-                Size = Size,
-                Files = Files,
+                Size = Size,
+                Files = Files,
                 Grabs = Grabs,
                 Description = Description,
                 RageID = RageID,
diff --git a/src/Jackett/Models/TorznabCatType.cs b/src/Jackett/Models/TorznabCatType.cs
index 1542729211cbc7a2a877bb92b3c95b00ae3a14d8..9f1a7f3a67e8ffaa527c9b4261c5d9028f7d264a 100644
--- a/src/Jackett/Models/TorznabCatType.cs
+++ b/src/Jackett/Models/TorznabCatType.cs
@@ -1,4 +1,4 @@
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
 
 namespace Jackett.Models
@@ -14,7 +14,7 @@ namespace Jackett.Models
                 if (cat != null && queryCats != null)
                 {
                     return cat.SubCategories.Any(c => queryCats.Contains(c.ID));
-                }
+                }
             }
 
             return false;
@@ -31,9 +31,9 @@ namespace Jackett.Models
             return string.Empty;
         }
 
-        public static string NormalizeCatName(string name)
-        {
-            return name.Replace(" ", "").ToLower();
+        public static string NormalizeCatName(string name)
+        {
+            return name.Replace(" ", "").ToLower();
         }
 
         public static TorznabCategory GetCatByName(string name)
diff --git a/src/Jackett/Models/TorznabCategory.cs b/src/Jackett/Models/TorznabCategory.cs
index 5a068f0b4723a99091e0c411b54ca6291a91d007..adea3548883ceed7497528e6e460c72540f09f59 100644
--- a/src/Jackett/Models/TorznabCategory.cs
+++ b/src/Jackett/Models/TorznabCategory.cs
@@ -26,15 +26,15 @@ namespace Jackett.Models
             SubCategories = new List<TorznabCategory>();
         }
 
-        public bool Contains(TorznabCategory cat)
-        {
-            if (this == cat)
-                return true;
-
-            if (SubCategories.Contains(cat))
-                return true;
-
-            return false;
+        public bool Contains(TorznabCategory cat)
+        {
+            if (this == cat)
+                return true;
+
+            if (SubCategories.Contains(cat))
+                return true;
+
+            return false;
         }
 
         public JToken ToJson()
@@ -43,19 +43,19 @@ namespace Jackett.Models
             t["ID"] = ID;
             t["Name"] = Name;
             return t;
-        }
-
-        public override bool Equals(Object obj)
-        {
-            if (obj == null || GetType() != obj.GetType())
-                return false;
-
-            return ID == ((TorznabCategory)obj).ID;
-        }
-
-        public override int GetHashCode()
-        {
-            return ID;
+        }
+
+        public override bool Equals(Object obj)
+        {
+            if (obj == null || GetType() != obj.GetType())
+                return false;
+
+            return ID == ((TorznabCategory)obj).ID;
+        }
+
+        public override int GetHashCode()
+        {
+            return ID;
         }
     }
 }
diff --git a/src/Jackett/Models/TorznabQuery.cs b/src/Jackett/Models/TorznabQuery.cs
index b335be23c72c5794084b0465c0876281e7c21856..7bbec859ec4c63b0e636794a79467447b9397f8b 100644
--- a/src/Jackett/Models/TorznabQuery.cs
+++ b/src/Jackett/Models/TorznabQuery.cs
@@ -5,7 +5,7 @@ using System.Collections.Specialized;
 using System.Globalization;
 using System.Linq;
 using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 
 namespace Jackett.Models
@@ -71,33 +71,33 @@ namespace Jackett.Models
         // Some trackers don't support AND logic for search terms resulting in unwanted results.
         // Using this method we can AND filter it within jackett.
         // With limit we can limit the amount of characters which should be compared (use it if a tracker doesn't return the full title).
-        public bool MatchQueryStringAND(string title, int? limit = null, string queryStringOverride = null)
-        {
-            // We cache the regex split results so we have to do it only once for each query.
-            if (QueryStringParts == null)
-            {
-                var queryString = GetQueryString();
-                if (queryStringOverride != null)
-                    queryString = queryStringOverride;
-                if (limit != null && limit > 0)
-                {
-                    if (limit > queryString.Length)
-                        limit = queryString.Length;
-                    queryString = queryString.Substring(0, (int)limit);
-                }
-                Regex SplitRegex = new Regex("[^a-zA-Z0-9]+");
-                QueryStringParts = SplitRegex.Split(queryString);
-            }
-
-            // Check if each part of the query string is in the given title.
-            foreach (var QueryStringPart in QueryStringParts)
-            {
-                if (title.IndexOf(QueryStringPart, StringComparison.OrdinalIgnoreCase) < 0)
-                {
-                    return false;
-                }
-            }
-            return true;
+        public bool MatchQueryStringAND(string title, int? limit = null, string queryStringOverride = null)
+        {
+            // We cache the regex split results so we have to do it only once for each query.
+            if (QueryStringParts == null)
+            {
+                var queryString = GetQueryString();
+                if (queryStringOverride != null)
+                    queryString = queryStringOverride;
+                if (limit != null && limit > 0)
+                {
+                    if (limit > queryString.Length)
+                        limit = queryString.Length;
+                    queryString = queryString.Substring(0, (int)limit);
+                }
+                Regex SplitRegex = new Regex("[^a-zA-Z0-9]+");
+                QueryStringParts = SplitRegex.Split(queryString);
+            }
+
+            // Check if each part of the query string is in the given title.
+            foreach (var QueryStringPart in QueryStringParts)
+            {
+                if (title.IndexOf(QueryStringPart, StringComparison.OrdinalIgnoreCase) < 0)
+                {
+                    return false;
+                }
+            }
+            return true;
         }
 
         public string GetEpisodeSearchString()
diff --git a/src/Jackett/Properties/AssemblyInfo.cs b/src/Jackett/Properties/AssemblyInfo.cs
index f84ef367f0dac43dc6868298d1ef1e48d7689872..ba021bc719d9f53d331c379ce513f372645ff8d9 100644
--- a/src/Jackett/Properties/AssemblyInfo.cs
+++ b/src/Jackett/Properties/AssemblyInfo.cs
@@ -1,36 +1,36 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// General Information about an assembly is controlled through the following 
-// set of attributes. Change these attribute values to modify the information
-// associated with an assembly.
-[assembly: AssemblyTitle("Jackett")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("Jackett")]
-[assembly: AssemblyCopyright("Copyright ©  2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible 
-// to COM components.  If you need to access a type in this assembly from 
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("5881fb69-3cb2-42b7-a744-2c1e537176bd")]
-
-// Version information for an assembly consists of the following four values:
-//
-//      Major Version
-//      Minor Version 
-//      Build Number
-//      Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers 
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("0.0.0.0")]
-[assembly: AssemblyFileVersion("0.0.0.0")]
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Jackett")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Jackett")]
+[assembly: AssemblyCopyright("Copyright ©  2015")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5881fb69-3cb2-42b7-a744-2c1e537176bd")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.0.0.0")]
+[assembly: AssemblyFileVersion("0.0.0.0")]
diff --git a/src/Jackett/Services/ConfigurationService.cs b/src/Jackett/Services/ConfigurationService.cs
index b5ab6dcdd97b917a702bb0211ce2c44f6f4e3fb5..05ece220894b24a8b28330e9110cdc63130ebaad 100644
--- a/src/Jackett/Services/ConfigurationService.cs
+++ b/src/Jackett/Services/ConfigurationService.cs
@@ -196,8 +196,8 @@ namespace Jackett.Services
             }
 #endif
             return dir;
-        }
-
+        }
+
         public List<string> GetCardigannDefinitionsFolders()
         {
             List<string> dirs = new List<string>();
diff --git a/src/Jackett/Services/IndexerManagerService.cs b/src/Jackett/Services/IndexerManagerService.cs
index ce4781bab1f950ee8a9bf0f79c4ccd89d0d197c5..c3bebd156f709e8eba5a3290685b606121ac88f6 100644
--- a/src/Jackett/Services/IndexerManagerService.cs
+++ b/src/Jackett/Services/IndexerManagerService.cs
@@ -44,42 +44,42 @@ namespace Jackett.Services
             cacheService = cache;
         }
 
-        protected void LoadIndexerConfig(IIndexer idx)
-        {
-            var configFilePath = GetIndexerConfigFilePath(idx);
-            if (File.Exists(configFilePath))
-            {
-                try
-                {
-                    var fileStr = File.ReadAllText(configFilePath);
-                    var jsonString = JToken.Parse(fileStr);
-                    idx.LoadFromSavedConfiguration(jsonString);
-                }
-                catch (Exception ex)
-                {
-                    logger.Error(ex, "Failed loading configuration for {0}, trying backup", idx.DisplayName);
-                    var configFilePathBak = configFilePath + ".bak";
-                    if (File.Exists(configFilePathBak))
-                    {
-                        try
-                        {
-                            var fileStrBak = File.ReadAllText(configFilePathBak);
-                            var jsonStringBak = JToken.Parse(fileStrBak);
-                            idx.LoadFromSavedConfiguration(jsonStringBak);
-                            logger.Info("Successfully loaded backup config for {0}", idx.DisplayName);
-                            idx.SaveConfig();
-                        }
-                        catch (Exception exbak)
-                        {
-                            logger.Error(exbak, "Failed loading backup configuration for {0}, you must reconfigure this indexer", idx.DisplayName);
-                        }
-                    }
-                    else
-                    {
-                        logger.Error(ex, "Failed loading backup configuration for {0} (no backup available), you must reconfigure this indexer", idx.DisplayName);
-                    }
-                }
-            }
+        protected void LoadIndexerConfig(IIndexer idx)
+        {
+            var configFilePath = GetIndexerConfigFilePath(idx);
+            if (File.Exists(configFilePath))
+            {
+                try
+                {
+                    var fileStr = File.ReadAllText(configFilePath);
+                    var jsonString = JToken.Parse(fileStr);
+                    idx.LoadFromSavedConfiguration(jsonString);
+                }
+                catch (Exception ex)
+                {
+                    logger.Error(ex, "Failed loading configuration for {0}, trying backup", idx.DisplayName);
+                    var configFilePathBak = configFilePath + ".bak";
+                    if (File.Exists(configFilePathBak))
+                    {
+                        try
+                        {
+                            var fileStrBak = File.ReadAllText(configFilePathBak);
+                            var jsonStringBak = JToken.Parse(fileStrBak);
+                            idx.LoadFromSavedConfiguration(jsonStringBak);
+                            logger.Info("Successfully loaded backup config for {0}", idx.DisplayName);
+                            idx.SaveConfig();
+                        }
+                        catch (Exception exbak)
+                        {
+                            logger.Error(exbak, "Failed loading backup configuration for {0}, you must reconfigure this indexer", idx.DisplayName);
+                        }
+                    }
+                    else
+                    {
+                        logger.Error(ex, "Failed loading backup configuration for {0} (no backup available), you must reconfigure this indexer", idx.DisplayName);
+                    }
+                }
+            }
         }
 
         public void InitIndexers()
@@ -97,32 +97,32 @@ namespace Jackett.Services
         {
             logger.Info("Loading Cardigann definitions from: " + path);
 
-            try
-            {
-                if (!Directory.Exists(path))
-                    return;
-
-                DirectoryInfo d = new DirectoryInfo(path);
-
-                foreach (var file in d.GetFiles("*.yml"))
-                {
-                    logger.Info("Loading Cardigann definition " + file.FullName);
-                    string DefinitionString = File.ReadAllText(file.FullName);
-                    CardigannIndexer idx = new CardigannIndexer(this, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>(), DefinitionString);
-                    if (indexers.ContainsKey(idx.ID))
-                    {
-                        logger.Debug(string.Format("Ignoring definition ID={0}, file={1}: Indexer already exists", idx.ID, file.FullName));
-                    }
-                    else
-                    {
-                        indexers.Add(idx.ID, idx);
-                        LoadIndexerConfig(idx);
-                    }
+            try
+            {
+                if (!Directory.Exists(path))
+                    return;
+
+                DirectoryInfo d = new DirectoryInfo(path);
+
+                foreach (var file in d.GetFiles("*.yml"))
+                {
+                    logger.Info("Loading Cardigann definition " + file.FullName);
+                    string DefinitionString = File.ReadAllText(file.FullName);
+                    CardigannIndexer idx = new CardigannIndexer(this, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>(), DefinitionString);
+                    if (indexers.ContainsKey(idx.ID))
+                    {
+                        logger.Debug(string.Format("Ignoring definition ID={0}, file={1}: Indexer already exists", idx.ID, file.FullName));
+                    }
+                    else
+                    {
+                        indexers.Add(idx.ID, idx);
+                        LoadIndexerConfig(idx);
+                    }
                 }
-            }
-            catch (Exception ex)
-            {
-                logger.Error(ex, "Error while loading Cardigann definitions: "+ ex.Message);
+            }
+            catch (Exception ex)
+            {
+                logger.Error(ex, "Error while loading Cardigann definitions: "+ ex.Message);
             }
         }
 
@@ -162,13 +162,13 @@ namespace Jackett.Services
             var indexer = GetIndexer(name);
             var configPath = GetIndexerConfigFilePath(indexer);
             File.Delete(configPath);
-            if (indexer.GetType() == typeof(CardigannIndexer))
-            {
-                indexers[name] = new CardigannIndexer(this, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>(), ((CardigannIndexer)indexer).DefinitionString);
-            }
-            else
-            {
-                indexers[name] = container.ResolveNamed<IIndexer>(indexer.ID);
+            if (indexer.GetType() == typeof(CardigannIndexer))
+            {
+                indexers[name] = new CardigannIndexer(this, container.Resolve<IWebClient>(), logger, container.Resolve<IProtectionService>(), ((CardigannIndexer)indexer).DefinitionString);
+            }
+            else
+            {
+                indexers[name] = container.ResolveNamed<IIndexer>(indexer.ID);
             }
         }
 
@@ -179,7 +179,7 @@ namespace Jackett.Services
 
         public void SaveConfig(IIndexer indexer, JToken obj)
         {
-            lock (configWriteLock)
+            lock (configWriteLock)
             { 
                 var uID = Guid.NewGuid().ToString("N");
                 var configFilePath = GetIndexerConfigFilePath(indexer);
@@ -189,63 +189,63 @@ namespace Jackett.Services
 
                 logger.Debug(string.Format("Saving new config file: {0}", configFilePathTmp));
 
-                if (string.IsNullOrWhiteSpace(content))
-                {
-                    throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
-                }
-
-                if (content.Contains("\x00"))
-                {
-                    throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
-                }
-
-                // make sure the config directory exists
+                if (string.IsNullOrWhiteSpace(content))
+                {
+                    throw new Exception(string.Format("New config content for {0} is empty, please report this bug.", indexer.ID));
+                }
+
+                if (content.Contains("\x00"))
+                {
+                    throw new Exception(string.Format("New config content for {0} contains 0x00, please report this bug. Content: {1}", indexer.ID, content));
+                }
+
+                // make sure the config directory exists
                 if (!Directory.Exists(configService.GetIndexerConfigDir()))
                     Directory.CreateDirectory(configService.GetIndexerConfigDir());
 
                 // create new temporary config file
                 File.WriteAllText(configFilePathTmp, content);
                 var fileInfo = new FileInfo(configFilePathTmp);
-                if (fileInfo.Length == 0)
-                {
-                    throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
+                if (fileInfo.Length == 0)
+                {
+                    throw new Exception(string.Format("New config file {0} is empty, please report this bug.", configFilePathTmp));
                 }
 
                 // create backup file
                 File.Delete(configFilePathBak);
-                if (File.Exists(configFilePath))
-                {
-                    try
-                    {
-                        File.Move(configFilePath, configFilePathBak);
-                    }
+                if (File.Exists(configFilePath))
+                {
+                    try
+                    {
+                        File.Move(configFilePath, configFilePathBak);
+                    }
                     catch (IOException ex)
-                    {
-                        logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
-                    }
+                    {
+                        logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePath, configFilePathBak, ex.ToString()));
+                    }
                 }
 
                 // replace the actual config file
                 File.Delete(configFilePath);
-                try
-                {
-                    File.Move(configFilePathTmp, configFilePath);
-                }
+                try
+                {
+                    File.Move(configFilePathTmp, configFilePath);
+                }
                 catch (IOException ex)
-                {
-                    logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
-                }
-            }
-        }
-
-        public void SortIndexers()
-        {
-            // Apparently Dictionary are ordered but can't be sorted again
-            // This will recreate the indexers Dictionary to workaround this limitation
-            Dictionary<string, IIndexer> newIndexers = new Dictionary<string, IIndexer>();
-            foreach (var indexer in indexers.OrderBy(_ => _.Value.DisplayName))
-                newIndexers.Add(indexer.Key, indexer.Value);
-            indexers = newIndexers;
-        }
+                {
+                    logger.Error(string.Format("Error while moving {0} to {1}: {2}", configFilePathTmp, configFilePath, ex.ToString()));
+                }
+            }
+        }
+
+        public void SortIndexers()
+        {
+            // Apparently Dictionary are ordered but can't be sorted again
+            // This will recreate the indexers Dictionary to workaround this limitation
+            Dictionary<string, IIndexer> newIndexers = new Dictionary<string, IIndexer>();
+            foreach (var indexer in indexers.OrderBy(_ => _.Value.DisplayName))
+                newIndexers.Add(indexer.Key, indexer.Value);
+            indexers = newIndexers;
+        }
     }
 }
diff --git a/src/Jackett/Services/ProtectionService.cs b/src/Jackett/Services/ProtectionService.cs
index 58f0bfd7d55e668429a0c568bbcd40ec7855dfd9..a97e084817b24d9d7318fc89482e5f8ba9a86b00 100644
--- a/src/Jackett/Services/ProtectionService.cs
+++ b/src/Jackett/Services/ProtectionService.cs
@@ -19,7 +19,7 @@ namespace Jackett.Services
     public class ProtectionService : IProtectionService
     {
         DataProtectionScope PROTECTION_SCOPE = DataProtectionScope.LocalMachine;
-        private const string JACKETT_KEY = "JACKETT_KEY";
+        private const string JACKETT_KEY = "JACKETT_KEY";
         const string APPLICATION_KEY = "Dvz66r3n8vhTGip2/quiw5ISyM37f7L2iOdupzdKmzkvXGhAgQiWK+6F+4qpxjPVNks1qO7LdWuVqRlzgLzeW8mChC6JnBMUS1Fin4N2nS9lh4XPuCZ1che75xO92Nk2vyXUo9KSFG1hvEszAuLfG2Mcg1r0sVyVXd2gQDU/TbY=";
 
         IServerService serverService;
@@ -54,8 +54,8 @@ namespace Jackett.Services
             var jackettKey = Environment.GetEnvironmentVariable(JACKETT_KEY);
 
             if (jackettKey == null)
-            {
-                return UnProtectDefaultMethod(plainText);
+            {
+                return UnProtectDefaultMethod(plainText);
             }
             else
             {
diff --git a/src/Jackett/Services/ServerService.cs b/src/Jackett/Services/ServerService.cs
index b2cf707f983d299d81e1b45ca6965955f0a03ef6..590555ce528d08a18fd84daa58814ecdde774455 100644
--- a/src/Jackett/Services/ServerService.cs
+++ b/src/Jackett/Services/ServerService.cs
@@ -17,13 +17,13 @@ using System.IO;
 using System.Linq;
 using System.Net;
 using System.Net.NetworkInformation;
-using System.Net.Sockets;
-using System.Reflection;
-using System.Runtime.InteropServices;
+using System.Net.Sockets;
+using System.Reflection;
+using System.Runtime.InteropServices;
 using System.Security.Cryptography;
 using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
+using System.Text.RegularExpressions;
+using System.Threading;
 using System.Threading.Tasks;
 using System.Web;
 
@@ -37,9 +37,9 @@ namespace Jackett.Services
         void ReserveUrls(bool doInstall = true);
         ServerConfig Config { get; }
         void SaveConfig();
-        Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
-        string BasePath();
-        List<string> notices { get; }
+        Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent");
+        string BasePath();
+        List<string> notices { get; }
     }
 
     public class ServerService : IServerService
@@ -73,16 +73,16 @@ namespace Jackett.Services
         public ServerConfig Config
         {
             get { return config; }
-        }
-
-        public List<string> notices
-        {
-            get
-            {
-                return _notices;
-            }
-        }
-
+        }
+
+        public List<string> notices
+        {
+            get
+            {
+                return _notices;
+            }
+        }
+
         public Uri ConvertToProxyLink(Uri link, string serverUrl, string indexerId, string action = "dl", string file = "t.torrent")
         {
             if (link == null || (link.IsAbsoluteUri && link.Scheme == "magnet"))
@@ -94,19 +94,19 @@ namespace Jackett.Services
             return new Uri(proxyLink);
         }
 
-        public string BasePath()
-        {
-            if (config.BasePathOverride == null || config.BasePathOverride == "") {
-                return "/";
+        public string BasePath()
+        {
+            if (config.BasePathOverride == null || config.BasePathOverride == "") {
+                return "/";
             }
             var path = config.BasePathOverride;
-            if (!path.EndsWith("/"))
-            {
-                path = path + "/";
+            if (!path.EndsWith("/"))
+            {
+                path = path + "/";
             }
-            if (!path.StartsWith("/"))
-            {
-                path = "/" + path;
+            if (!path.StartsWith("/"))
+            {
+                path = "/" + path;
             }
             return path;
         }
@@ -161,131 +161,131 @@ namespace Jackett.Services
         public void Initalize()
         {
             logger.Info("Starting Jackett " + configService.GetVersion());
-            try
-            {
-                var x = Environment.OSVersion;
-                var runtimedir = RuntimeEnvironment.GetRuntimeDirectory();
+            try
+            {
+                var x = Environment.OSVersion;
+                var runtimedir = RuntimeEnvironment.GetRuntimeDirectory();
                 logger.Info("Environment version: " + Environment.Version.ToString() + " (" + runtimedir + ")");
-                logger.Info("OS version: " + Environment.OSVersion.ToString() + (Environment.Is64BitOperatingSystem ? " (64bit OS)" : "") + (Environment.Is64BitProcess ? " (64bit process)" : ""));
-
-                try
-                {
-                    int workerThreads;
-                    int completionPortThreads;
-                    ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
-                    logger.Info("ThreadPool MaxThreads: " + workerThreads + " workerThreads, " + completionPortThreads + " completionPortThreads");
-                }
-                catch (Exception e)
-                {
-                    logger.Error("Error while getting MaxThreads details: " + e);
-                }
-
-                try
-                {
-                    var issuefile = "/etc/issue";
-                    if (File.Exists(issuefile))
-                    {
-                        using (StreamReader reader = new StreamReader(issuefile))
-                        {
-                            string firstLine;
-                            firstLine = reader.ReadLine();
-                            if (firstLine != null)
-                                logger.Info("issue: " + firstLine);
-                        }
-                    }
-                }
-                catch (Exception e)
-                {
-                    logger.Error(e, "Error while reading the issue file");
+                logger.Info("OS version: " + Environment.OSVersion.ToString() + (Environment.Is64BitOperatingSystem ? " (64bit OS)" : "") + (Environment.Is64BitProcess ? " (64bit process)" : ""));
+
+                try
+                {
+                    int workerThreads;
+                    int completionPortThreads;
+                    ThreadPool.GetMaxThreads(out workerThreads, out completionPortThreads);
+                    logger.Info("ThreadPool MaxThreads: " + workerThreads + " workerThreads, " + completionPortThreads + " completionPortThreads");
+                }
+                catch (Exception e)
+                {
+                    logger.Error("Error while getting MaxThreads details: " + e);
                 }
 
-                Type monotype = Type.GetType("Mono.Runtime");
-                if (monotype != null)
-                {
-                    MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
-                    var monoVersion = "unknown";
-                    if (displayName != null)
-                        monoVersion = displayName.Invoke(null, null).ToString();
-                    logger.Info("mono version: " + monoVersion);
-
-                    var monoVersionO = new Version(monoVersion.Split(' ')[0]);
-
-                    if (monoVersionO.Major < 4)
-                    {
-                        logger.Error("Your mono version is to old (mono 3 is no longer supported). Please update to the latest version from http://www.mono-project.com/download/");
-                        Environment.Exit(2);
-                    }
-                    else if (monoVersionO.Major == 4 && monoVersionO.Minor == 2)
-                    {
-                        var notice = "mono version 4.2.* is known to cause problems with Jackett. If you experience any problems please try updating to the latest mono version from http://www.mono-project.com/download/ first.";
-                        _notices.Add(notice);
-                        logger.Error(notice);
-                    }
-
-                    try
-                    {
-                        // Check for mono-devel
-                        // Is there any better way which doesn't involve a hard cashes?
-                        var mono_devel_file = Path.Combine(runtimedir, "mono-api-info.exe"); 
-                        if (!File.Exists(mono_devel_file))
-                        {
-                            var notice = "It looks like the mono-devel package is not installed, please make sure it's installed to avoid crashes.";
-                            _notices.Add(notice);
-                            logger.Error(notice);
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        logger.Error(e, "Error while checking for mono-devel");
-                    }
-
-                    try
-                    {
-                        // Check for ca-certificates-mono
-                        var mono_cert_file = Path.Combine(runtimedir, "cert-sync.exe");
-                        if (!File.Exists(mono_cert_file))
-                        {
-                            if (monoVersionO.Major >= 4 && monoVersionO.Minor >= 8)
-                            {
-                                var notice = "The ca-certificates-mono package is not installed, HTTPS trackers won't work. Please install it.";
-                                _notices.Add(notice);
-                                logger.Error(notice);
-                            } 
-                            else
-                            {
-                                logger.Info("The ca-certificates-mono package is not installed, it will become mandatory once mono >= 4.8 is used.");
-                            }
-                            
-                        }
-                    }
-                    catch (Exception e)
-                    {
-                        logger.Error(e, "Error while checking for ca-certificates-mono");
-                    }
-
-                    try
-                    {
-                        Encoding.GetEncoding("windows-1255");
-                    }
-                    catch (NotSupportedException e)
-                    {
-                        logger.Debug(e);
-                        logger.Error(e.Message + " Most likely the mono-locale-extras package is not installed.");
-                        Environment.Exit(2);
-                    }
-                }
+                try
+                {
+                    var issuefile = "/etc/issue";
+                    if (File.Exists(issuefile))
+                    {
+                        using (StreamReader reader = new StreamReader(issuefile))
+                        {
+                            string firstLine;
+                            firstLine = reader.ReadLine();
+                            if (firstLine != null)
+                                logger.Info("issue: " + firstLine);
+                        }
+                    }
+                }
+                catch (Exception e)
+                {
+                    logger.Error(e, "Error while reading the issue file");
+                }
+
+                Type monotype = Type.GetType("Mono.Runtime");
+                if (monotype != null)
+                {
+                    MethodInfo displayName = monotype.GetMethod("GetDisplayName", BindingFlags.NonPublic | BindingFlags.Static);
+                    var monoVersion = "unknown";
+                    if (displayName != null)
+                        monoVersion = displayName.Invoke(null, null).ToString();
+                    logger.Info("mono version: " + monoVersion);
+
+                    var monoVersionO = new Version(monoVersion.Split(' ')[0]);
+
+                    if (monoVersionO.Major < 4)
+                    {
+                        logger.Error("Your mono version is to old (mono 3 is no longer supported). Please update to the latest version from http://www.mono-project.com/download/");
+                        Environment.Exit(2);
+                    }
+                    else if (monoVersionO.Major == 4 && monoVersionO.Minor == 2)
+                    {
+                        var notice = "mono version 4.2.* is known to cause problems with Jackett. If you experience any problems please try updating to the latest mono version from http://www.mono-project.com/download/ first.";
+                        _notices.Add(notice);
+                        logger.Error(notice);
+                    }
+
+                    try
+                    {
+                        // Check for mono-devel
+                        // Is there any better way which doesn't involve a hard cashes?
+                        var mono_devel_file = Path.Combine(runtimedir, "mono-api-info.exe"); 
+                        if (!File.Exists(mono_devel_file))
+                        {
+                            var notice = "It looks like the mono-devel package is not installed, please make sure it's installed to avoid crashes.";
+                            _notices.Add(notice);
+                            logger.Error(notice);
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        logger.Error(e, "Error while checking for mono-devel");
+                    }
+
+                    try
+                    {
+                        // Check for ca-certificates-mono
+                        var mono_cert_file = Path.Combine(runtimedir, "cert-sync.exe");
+                        if (!File.Exists(mono_cert_file))
+                        {
+                            if (monoVersionO.Major >= 4 && monoVersionO.Minor >= 8)
+                            {
+                                var notice = "The ca-certificates-mono package is not installed, HTTPS trackers won't work. Please install it.";
+                                _notices.Add(notice);
+                                logger.Error(notice);
+                            } 
+                            else
+                            {
+                                logger.Info("The ca-certificates-mono package is not installed, it will become mandatory once mono >= 4.8 is used.");
+                            }
+                            
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        logger.Error(e, "Error while checking for ca-certificates-mono");
+                    }
+
+                    try
+                    {
+                        Encoding.GetEncoding("windows-1255");
+                    }
+                    catch (NotSupportedException e)
+                    {
+                        logger.Debug(e);
+                        logger.Error(e.Message + " Most likely the mono-locale-extras package is not installed.");
+                        Environment.Exit(2);
+                    }
+                }
             }
             catch (Exception e)
-            {
-                logger.Error("Error while getting environment details: " + e);
+            {
+                logger.Error("Error while getting environment details: " + e);
             }
 
             CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
             // Load indexers
             indexerService.InitIndexers();
-            foreach(string dir in configService.GetCardigannDefinitionsFolders())
-            {
-                indexerService.InitCardigannIndexers(dir);
+            foreach(string dir in configService.GetCardigannDefinitionsFolders())
+            {
+                indexerService.InitCardigannIndexers(dir);
             }
             indexerService.SortIndexers();
             client.Init();
@@ -299,24 +299,24 @@ namespace Jackett.Services
             var startOptions = new StartOptions();
             config.GetListenAddresses().ToList().ForEach(u => startOptions.Urls.Add(u));
             Startup.BasePath = BasePath();
-            try
-            {
-                _server = WebApp.Start<Startup>(startOptions);
+            try
+            {
+                _server = WebApp.Start<Startup>(startOptions);
             }
-            catch (TargetInvocationException e)
-            {
-                var inner = e.InnerException;
-                if (inner is SocketException && ((SocketException)inner).SocketErrorCode == SocketError.AddressAlreadyInUse) // Linux (mono)
-                {
-                    logger.Error("Address already in use: Most likely Jackett is already running.");
-                    Environment.Exit(1);
-                }
-                else if (inner is HttpListenerException && ((HttpListenerException)inner).ErrorCode == 183) // Windows
-                {
-                    logger.Error(inner.Message + " Most likely Jackett is already running.");
-                    Environment.Exit(1);
-                }
-                throw e;
+            catch (TargetInvocationException e)
+            {
+                var inner = e.InnerException;
+                if (inner is SocketException && ((SocketException)inner).SocketErrorCode == SocketError.AddressAlreadyInUse) // Linux (mono)
+                {
+                    logger.Error("Address already in use: Most likely Jackett is already running.");
+                    Environment.Exit(1);
+                }
+                else if (inner is HttpListenerException && ((HttpListenerException)inner).ErrorCode == 183) // Windows
+                {
+                    logger.Error(inner.Message + " Most likely Jackett is already running.");
+                    Environment.Exit(1);
+                }
+                throw e;
             }
             logger.Debug("Web server started");
             updater.StartUpdateChecker();
diff --git a/src/Jackett/Services/ServiceConfigService.cs b/src/Jackett/Services/ServiceConfigService.cs
index e54269199d1a33b4235270030ff1088c94813d11..30497a6914cfd834911970b43622f1f5f7d45d36 100644
--- a/src/Jackett/Services/ServiceConfigService.cs
+++ b/src/Jackett/Services/ServiceConfigService.cs
@@ -119,10 +119,10 @@ namespace Jackett.Services
         public void RemoveService()
         {
             var service = GetService(NAME);
-            if(service == null)
-            {
-                logger.Warn("The service is already uninstalled");
-                return;
+            if(service == null)
+            {
+                logger.Warn("The service is already uninstalled");
+                return;
             }
             if (service.Status != ServiceControllerStatus.Stopped)
             {
diff --git a/src/Jackett/Services/UpdateService.cs b/src/Jackett/Services/UpdateService.cs
index ac05bbe6c29c19ccfb4af3564f880c57573a0d31..2cde3f727e9586b7a9e42dba99f79eb6925cad85 100644
--- a/src/Jackett/Services/UpdateService.cs
+++ b/src/Jackett/Services/UpdateService.cs
@@ -1,309 +1,309 @@
-using ICSharpCode.SharpZipLib.GZip;
-using ICSharpCode.SharpZipLib.Tar;
-using ICSharpCode.SharpZipLib.Zip;
-using Jackett.Models.Config;
-using Jackett.Models.GitHub;
-using Jackett.Utils.Clients;
-using Newtonsoft.Json;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Net.Security;
-using System.Reflection;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-
-namespace Jackett.Services
-{
-    public interface IUpdateService
-    {
-        void StartUpdateChecker();
-        void CheckForUpdatesNow();
-        void CleanupTempDir();
-    }
-
-    public class UpdateService: IUpdateService
-    {
-        Logger logger;
-        IWebClient client;
-        IConfigurationService configService;
-        ManualResetEvent locker = new ManualResetEvent(false);
-        ITrayLockService lockService;
-        bool forceupdatecheck = false;
-
-        public UpdateService(Logger l, IWebClient c, IConfigurationService cfg, ITrayLockService ls)
-        {
-            logger = l;
-            client = c;
-            configService = cfg;
-            lockService = ls;
-        }
-
-        private string ExePath()
-        {
-            var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
-            return new FileInfo(location.AbsolutePath).FullName;
-        }
-
-        public void StartUpdateChecker()
-        {
-            Task.Factory.StartNew(UpdateWorkerThread);
-        }
-
-        public void CheckForUpdatesNow()
-        {
-            forceupdatecheck = true;
-            locker.Set();
-        }
-
-        private async void UpdateWorkerThread()
-        {
-            while (true)
-            {
-                locker.WaitOne((int)new TimeSpan(24, 0, 0).TotalMilliseconds);
-                locker.Reset();
-                await CheckForUpdates();
-            }
-        }
-
-        private bool AcceptCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
-        {
-            return true;
-        }
-
-        private async Task CheckForUpdates()
-        {
-            var config = configService.GetConfig<ServerConfig>();
-            if (config.UpdateDisabled && !forceupdatecheck)
-            {
-                logger.Info($"Skipping update check as it is disabled.");
-                return;
-            }
-
-            forceupdatecheck = true;
-
-            var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
-            if (Debugger.IsAttached)
-            {
-                logger.Info($"Skipping checking for new releases as the debugger is attached.");
-                return;
-            }
-
-            try
-            {
-
-                var response = await client.GetString(new WebRequest()
-                {
-                    Url = "https://api.github.com/repos/Jackett/Jackett/releases",
-                    Encoding = Encoding.UTF8,
-                    EmulateBrowser = false
-                });
-
-                if(response.Status != System.Net.HttpStatusCode.OK)
-                {
-                    logger.Error("Failed to get the release list: " + response.Status);
-                }
-
-                var releases = JsonConvert.DeserializeObject<List<Release>>(response.Content);
-
-                if (!config.UpdatePrerelease)
-                {
-                    releases = releases.Where(r => !r.Prerelease).ToList();
-                }
-
-                if (releases.Count > 0)
-                {
-                    var latestRelease = releases.OrderByDescending(o => o.Created_at).First();
-                    var currentVersion = $"v{GetCurrentVersion()}";
-
-                    if (latestRelease.Name != currentVersion && currentVersion != "v0.0.0.0")
-                    {
-                        logger.Info($"New release found.  Current: {currentVersion} New: {latestRelease.Name}");
-                        try
-                        {
-                            var tempDir = await DownloadRelease(latestRelease.Assets, isWindows,  latestRelease.Name);
-                            // Copy updater
-                            var installDir = Path.GetDirectoryName(ExePath());
-                            var updaterPath = Path.Combine(tempDir, "Jackett", "JackettUpdater.exe");
-                            if (updaterPath != null)
-                                StartUpdate(updaterPath, installDir, isWindows, Startup.NoRestart);
-                        }
-                        catch (Exception e)
-                        {
-                            logger.Error(e, "Error performing update.");
-                        }
-                    }
-                    else
-                    {
-                        logger.Info($"Checked for a updated release but none was found.");
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                logger.Error(e, "Error checking for updates.");
-            }
-            finally
-            {
-                if (!isWindows)
-                {
-                    System.Net.ServicePointManager.ServerCertificateValidationCallback -= AcceptCert;
-                }
-            }
-        }
-
-        private string GetCurrentVersion()
-        {
-            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
-            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
-            return fvi.FileVersion;
-        }
-
-        private WebRequest SetDownloadHeaders(WebRequest req)
-        {
-            req.Headers = new Dictionary<string, string>()
-            {
-                { "Accept", "application/octet-stream" }
-            };
-
-            return req;
-        }
-
-        public void CleanupTempDir()
-        {
-            var tempDir = Path.GetTempPath();
-
-            if (!Directory.Exists(tempDir))
-            {
-                logger.Error("Temp dir doesn't exist: " + tempDir.ToString());
-                return;
-            }
-            
-            try { 
-                DirectoryInfo d = new DirectoryInfo(tempDir);
-                foreach (var dir in d.GetDirectories("JackettUpdate-*"))
-                {
-                    try {
-                        logger.Info("Deleting JackettUpdate temp files from " + dir.FullName);
-                        dir.Delete(true);
-                    }
-                    catch (Exception e)
-                    {
-                        logger.Error("Error while deleting temp files from " + dir.FullName);
-                        logger.Error(e);
-                    }
-                }
-            }
-            catch (Exception e)
-            {
-                logger.Error("Unexpected error while deleting temp files from " + tempDir.ToString());
-                logger.Error(e);
-            }
-        }
-
-        private async Task<string> DownloadRelease(List<Asset> assets, bool isWindows, string version)
-        {
-            var targetAsset = assets.Where(a => isWindows ? a.Browser_download_url.ToLowerInvariant().EndsWith(".zip") : a.Browser_download_url.ToLowerInvariant().EndsWith(".gz")).FirstOrDefault();
-
-            if (targetAsset == null)
-            {
-                logger.Error("Failed to find asset to download!");
-                return null;
-            }
-
-            var url = targetAsset.Browser_download_url;
-
-            var data = await client.GetBytes(SetDownloadHeaders(new WebRequest() { Url = url, EmulateBrowser = true, Type = RequestType.GET }));
-
-            while (data.IsRedirect)
-            {
-                data = await client.GetBytes(new WebRequest() { Url = data.RedirectingTo, EmulateBrowser = true, Type = RequestType.GET });
-            }
-
-            var tempDir = Path.Combine(Path.GetTempPath(), "JackettUpdate-" + version + "-" + DateTime.Now.Ticks);
-
-            if (Directory.Exists(tempDir))
-            {
-                Directory.Delete(tempDir, true);
-            }
-
-            Directory.CreateDirectory(tempDir);
-
-            if (isWindows)
-            {
-                var zipPath = Path.Combine(tempDir, "Update.zip");
-                File.WriteAllBytes(zipPath, data.Content);
-                var fastZip = new FastZip();
-                fastZip.ExtractZip(zipPath, tempDir, null);
-            }
-            else
-            {
-                var gzPath = Path.Combine(tempDir, "Update.tar.gz");
-                File.WriteAllBytes(gzPath, data.Content);
-                Stream inStream = File.OpenRead(gzPath);
-                Stream gzipStream = new GZipInputStream(inStream);
-
-                TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
-                tarArchive.ExtractContents(tempDir);
-                tarArchive.Close();
-                gzipStream.Close();
-                inStream.Close();
-            }
-
-            return tempDir;
-        }
-
-        private void StartUpdate(string updaterExePath, string installLocation, bool isWindows, bool NoRestart)
-        {
-            var exe = Path.GetFileName(ExePath()).ToLowerInvariant();
-            var args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1));
-
-            var startInfo = new ProcessStartInfo();
-
-            // Note: add a leading space to the --Args argument to avoid parsing as arguments
-            if (isWindows)
-            {
-                startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\"";
-                startInfo.FileName = Path.Combine(updaterExePath);
-            }
-            else
-            {
-                // Wrap mono
-                args = exe + " " + args;
-                exe = "mono";
-
-                startInfo.Arguments = $"{Path.Combine(updaterExePath)} --Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\"";
-                startInfo.FileName = "mono";
-                startInfo.UseShellExecute = false;
-                startInfo.CreateNoWindow = true;
-            }
-
-            try { 
-                var pid = Process.GetCurrentProcess().Id;
-                startInfo.Arguments += $" --KillPids \"{pid}\"";
-            }
-            catch (Exception e)
-            {
-                logger.Error("Unexpected error while retriving the PID");
-                logger.Error(e);
-            }
-
-            if (NoRestart)
-                startInfo.Arguments += " --NoRestart";
-
-            var procInfo = Process.Start(startInfo);
-            logger.Info($"Updater started process id: {procInfo.Id}");
-            if (NoRestart == false)
-            { 
-                logger.Info("Exiting Jackett..");
-                lockService.Signal();
-                Environment.Exit(0);
-            }
-        }
-    }
-}
+using ICSharpCode.SharpZipLib.GZip;
+using ICSharpCode.SharpZipLib.Tar;
+using ICSharpCode.SharpZipLib.Zip;
+using Jackett.Models.Config;
+using Jackett.Models.GitHub;
+using Jackett.Utils.Clients;
+using Newtonsoft.Json;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Reflection;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace Jackett.Services
+{
+    public interface IUpdateService
+    {
+        void StartUpdateChecker();
+        void CheckForUpdatesNow();
+        void CleanupTempDir();
+    }
+
+    public class UpdateService: IUpdateService
+    {
+        Logger logger;
+        IWebClient client;
+        IConfigurationService configService;
+        ManualResetEvent locker = new ManualResetEvent(false);
+        ITrayLockService lockService;
+        bool forceupdatecheck = false;
+
+        public UpdateService(Logger l, IWebClient c, IConfigurationService cfg, ITrayLockService ls)
+        {
+            logger = l;
+            client = c;
+            configService = cfg;
+            lockService = ls;
+        }
+
+        private string ExePath()
+        {
+            var location = new Uri(Assembly.GetEntryAssembly().GetName().CodeBase);
+            return new FileInfo(location.AbsolutePath).FullName;
+        }
+
+        public void StartUpdateChecker()
+        {
+            Task.Factory.StartNew(UpdateWorkerThread);
+        }
+
+        public void CheckForUpdatesNow()
+        {
+            forceupdatecheck = true;
+            locker.Set();
+        }
+
+        private async void UpdateWorkerThread()
+        {
+            while (true)
+            {
+                locker.WaitOne((int)new TimeSpan(24, 0, 0).TotalMilliseconds);
+                locker.Reset();
+                await CheckForUpdates();
+            }
+        }
+
+        private bool AcceptCert(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+        {
+            return true;
+        }
+
+        private async Task CheckForUpdates()
+        {
+            var config = configService.GetConfig<ServerConfig>();
+            if (config.UpdateDisabled && !forceupdatecheck)
+            {
+                logger.Info($"Skipping update check as it is disabled.");
+                return;
+            }
+
+            forceupdatecheck = true;
+
+            var isWindows = System.Environment.OSVersion.Platform != PlatformID.Unix;
+            if (Debugger.IsAttached)
+            {
+                logger.Info($"Skipping checking for new releases as the debugger is attached.");
+                return;
+            }
+
+            try
+            {
+
+                var response = await client.GetString(new WebRequest()
+                {
+                    Url = "https://api.github.com/repos/Jackett/Jackett/releases",
+                    Encoding = Encoding.UTF8,
+                    EmulateBrowser = false
+                });
+
+                if(response.Status != System.Net.HttpStatusCode.OK)
+                {
+                    logger.Error("Failed to get the release list: " + response.Status);
+                }
+
+                var releases = JsonConvert.DeserializeObject<List<Release>>(response.Content);
+
+                if (!config.UpdatePrerelease)
+                {
+                    releases = releases.Where(r => !r.Prerelease).ToList();
+                }
+
+                if (releases.Count > 0)
+                {
+                    var latestRelease = releases.OrderByDescending(o => o.Created_at).First();
+                    var currentVersion = $"v{GetCurrentVersion()}";
+
+                    if (latestRelease.Name != currentVersion && currentVersion != "v0.0.0.0")
+                    {
+                        logger.Info($"New release found.  Current: {currentVersion} New: {latestRelease.Name}");
+                        try
+                        {
+                            var tempDir = await DownloadRelease(latestRelease.Assets, isWindows,  latestRelease.Name);
+                            // Copy updater
+                            var installDir = Path.GetDirectoryName(ExePath());
+                            var updaterPath = Path.Combine(tempDir, "Jackett", "JackettUpdater.exe");
+                            if (updaterPath != null)
+                                StartUpdate(updaterPath, installDir, isWindows, Startup.NoRestart);
+                        }
+                        catch (Exception e)
+                        {
+                            logger.Error(e, "Error performing update.");
+                        }
+                    }
+                    else
+                    {
+                        logger.Info($"Checked for a updated release but none was found.");
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                logger.Error(e, "Error checking for updates.");
+            }
+            finally
+            {
+                if (!isWindows)
+                {
+                    System.Net.ServicePointManager.ServerCertificateValidationCallback -= AcceptCert;
+                }
+            }
+        }
+
+        private string GetCurrentVersion()
+        {
+            var assembly = System.Reflection.Assembly.GetExecutingAssembly();
+            var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
+            return fvi.FileVersion;
+        }
+
+        private WebRequest SetDownloadHeaders(WebRequest req)
+        {
+            req.Headers = new Dictionary<string, string>()
+            {
+                { "Accept", "application/octet-stream" }
+            };
+
+            return req;
+        }
+
+        public void CleanupTempDir()
+        {
+            var tempDir = Path.GetTempPath();
+
+            if (!Directory.Exists(tempDir))
+            {
+                logger.Error("Temp dir doesn't exist: " + tempDir.ToString());
+                return;
+            }
+            
+            try { 
+                DirectoryInfo d = new DirectoryInfo(tempDir);
+                foreach (var dir in d.GetDirectories("JackettUpdate-*"))
+                {
+                    try {
+                        logger.Info("Deleting JackettUpdate temp files from " + dir.FullName);
+                        dir.Delete(true);
+                    }
+                    catch (Exception e)
+                    {
+                        logger.Error("Error while deleting temp files from " + dir.FullName);
+                        logger.Error(e);
+                    }
+                }
+            }
+            catch (Exception e)
+            {
+                logger.Error("Unexpected error while deleting temp files from " + tempDir.ToString());
+                logger.Error(e);
+            }
+        }
+
+        private async Task<string> DownloadRelease(List<Asset> assets, bool isWindows, string version)
+        {
+            var targetAsset = assets.Where(a => isWindows ? a.Browser_download_url.ToLowerInvariant().EndsWith(".zip") : a.Browser_download_url.ToLowerInvariant().EndsWith(".gz")).FirstOrDefault();
+
+            if (targetAsset == null)
+            {
+                logger.Error("Failed to find asset to download!");
+                return null;
+            }
+
+            var url = targetAsset.Browser_download_url;
+
+            var data = await client.GetBytes(SetDownloadHeaders(new WebRequest() { Url = url, EmulateBrowser = true, Type = RequestType.GET }));
+
+            while (data.IsRedirect)
+            {
+                data = await client.GetBytes(new WebRequest() { Url = data.RedirectingTo, EmulateBrowser = true, Type = RequestType.GET });
+            }
+
+            var tempDir = Path.Combine(Path.GetTempPath(), "JackettUpdate-" + version + "-" + DateTime.Now.Ticks);
+
+            if (Directory.Exists(tempDir))
+            {
+                Directory.Delete(tempDir, true);
+            }
+
+            Directory.CreateDirectory(tempDir);
+
+            if (isWindows)
+            {
+                var zipPath = Path.Combine(tempDir, "Update.zip");
+                File.WriteAllBytes(zipPath, data.Content);
+                var fastZip = new FastZip();
+                fastZip.ExtractZip(zipPath, tempDir, null);
+            }
+            else
+            {
+                var gzPath = Path.Combine(tempDir, "Update.tar.gz");
+                File.WriteAllBytes(gzPath, data.Content);
+                Stream inStream = File.OpenRead(gzPath);
+                Stream gzipStream = new GZipInputStream(inStream);
+
+                TarArchive tarArchive = TarArchive.CreateInputTarArchive(gzipStream);
+                tarArchive.ExtractContents(tempDir);
+                tarArchive.Close();
+                gzipStream.Close();
+                inStream.Close();
+            }
+
+            return tempDir;
+        }
+
+        private void StartUpdate(string updaterExePath, string installLocation, bool isWindows, bool NoRestart)
+        {
+            var exe = Path.GetFileName(ExePath()).ToLowerInvariant();
+            var args = string.Join(" ", Environment.GetCommandLineArgs().Skip(1));
+
+            var startInfo = new ProcessStartInfo();
+
+            // Note: add a leading space to the --Args argument to avoid parsing as arguments
+            if (isWindows)
+            {
+                startInfo.Arguments = $"--Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\"";
+                startInfo.FileName = Path.Combine(updaterExePath);
+            }
+            else
+            {
+                // Wrap mono
+                args = exe + " " + args;
+                exe = "mono";
+
+                startInfo.Arguments = $"{Path.Combine(updaterExePath)} --Path \"{installLocation}\" --Type \"{exe}\" --Args \" {args}\"";
+                startInfo.FileName = "mono";
+                startInfo.UseShellExecute = false;
+                startInfo.CreateNoWindow = true;
+            }
+
+            try { 
+                var pid = Process.GetCurrentProcess().Id;
+                startInfo.Arguments += $" --KillPids \"{pid}\"";
+            }
+            catch (Exception e)
+            {
+                logger.Error("Unexpected error while retriving the PID");
+                logger.Error(e);
+            }
+
+            if (NoRestart)
+                startInfo.Arguments += " --NoRestart";
+
+            var procInfo = Process.Start(startInfo);
+            logger.Info($"Updater started process id: {procInfo.Id}");
+            if (NoRestart == false)
+            { 
+                logger.Info("Exiting Jackett..");
+                lockService.Signal();
+                Environment.Exit(0);
+            }
+        }
+    }
+}
diff --git a/src/Jackett/Startup.cs b/src/Jackett/Startup.cs
index c8ba85a19cdeb11e8b723036c747add69e73cc23..1a88eeaaf7b5d5a7fe7e9acbdda0fb79d1c27ea2 100644
--- a/src/Jackett/Startup.cs
+++ b/src/Jackett/Startup.cs
@@ -1,189 +1,189 @@
-using Owin;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Threading.Tasks;
-using System.Web.Http;
-using Autofac.Integration.WebApi;
-using Microsoft.Owin;
-using Jackett;
-using Microsoft.Owin.StaticFiles;
-using Microsoft.Owin.FileSystems;
-using Autofac;
-using Jackett.Services;
-using System.Web.Http.Tracing;
-using Jackett.Utils;
-using Microsoft.AspNet.Identity;
-using System.Web.Http.ExceptionHandling;
-using System.Net;
-
-[assembly: OwinStartup(typeof(Startup))]
-namespace Jackett
-{
-    public class Startup
-    {
-        public static bool TracingEnabled
-        {
-            get;
-            set;
-        }
-
-        public static bool LogRequests
-        {
-            get;
-            set;
-        }
-
-        public static string ClientOverride
-        {
-            get;
-            set;
-        }
-
-        public static string ProxyConnection
-        {
-            get;
-            set;
-        }
-
-        public static bool? DoSSLFix
-        {
-            get;
-            set;
-        }
-
-        public static bool? IgnoreSslErrors
-        {
-            get;
-            set;
-        }
-
-        public static string CustomDataFolder
-        {
-            get;
-            set;
-        }
-
-        public static string BasePath
-        {
-            get;
-            set;
-        }
-
-        public static bool NoRestart
-        {
-            get;
-            set;
-        }
-
-        public void Configuration(IAppBuilder appBuilder)
-        {
-            // Configure Web API for self-host. 
-            var config = new HttpConfiguration();
-
-            // try to fix SocketException crashes
-            // based on http://stackoverflow.com/questions/23368885/signalr-owin-self-host-on-linux-mono-socketexception-when-clients-lose-connectio/30583109#30583109
-            try
-            {
-                object httpListener;
-                if (appBuilder.Properties.TryGetValue(typeof(HttpListener).FullName, out httpListener) && httpListener is HttpListener)
-                {
-                    // HttpListener should not return exceptions that occur when sending the response to the client
-                    ((HttpListener)httpListener).IgnoreWriteExceptions = true;
-                    //Engine.Logger.Info("set HttpListener.IgnoreWriteExceptions = true");
-                }
-            }
-            catch (Exception e)
-            {
-                Engine.Logger.Error(e, "Error while setting HttpListener.IgnoreWriteExceptions = true");
-            }
-
-            appBuilder.Use<WebApiRootRedirectMiddleware>();
-
-            // register exception handler
-            config.Services.Replace(typeof(IExceptionHandler), new WebAPIExceptionHandler());
-
-            // Setup tracing if enabled
-            if (TracingEnabled)
-            {
-                config.EnableSystemDiagnosticsTracing();
-                config.Services.Replace(typeof(ITraceWriter), new WebAPIToNLogTracer());
-            }
-            // Add request logging if enabled
-            if (LogRequests)
-            {
-                config.MessageHandlers.Add(new WebAPIRequestLogger());
-            }
-            config.DependencyResolver = new AutofacWebApiDependencyResolver(Engine.GetContainer());
-            config.MapHttpAttributeRoutes();
-
-            config.Routes.MapHttpRoute(
-                name: "Admin",
-                routeTemplate: "admin/{action}",
-                defaults: new { controller = "Admin" }
-            );
-
-            config.Routes.MapHttpRoute(
-                name: "apiDefault",
-                routeTemplate: "api/{indexerID}",
-                defaults: new { controller = "Torznab", action = "Call" }
-            );
-
-            config.Routes.MapHttpRoute(
-               name: "api",
-               routeTemplate: "api/{indexerID}/api",
-               defaults: new { controller = "Torznab", action = "Call" }
-           );
-
-            config.Routes.MapHttpRoute(
-               name: "torznabDefault",
-               routeTemplate: "torznab/{indexerID}",
-               defaults: new { controller = "Torznab", action = "Call" }
-           );
-
-            config.Routes.MapHttpRoute(
-               name: "torznab",
-               routeTemplate: "torznab/{indexerID}/api",
-               defaults: new { controller = "Torznab", action = "Call" }
-           );
-
-            config.Routes.MapHttpRoute(
-              name: "potatoDefault",
-              routeTemplate: "potato/{indexerID}",
-              defaults: new { controller = "Potato", action = "Call" }
-          );
-
-            config.Routes.MapHttpRoute(
-               name: "potato",
-               routeTemplate: "potato/{indexerID}/api",
-               defaults: new { controller = "Potato", action = "Call" }
-           );
-
-            config.Routes.MapHttpRoute(
-                name: "download",
-                routeTemplate: "dl/{indexerID}/{apiKey}",
-                defaults: new { controller = "Download", action = "Download" }
-            );
-
-            config.Routes.MapHttpRoute(
-              name: "blackhole",
-              routeTemplate: "bh/{indexerID}/{apikey}",
-              defaults: new { controller = "Blackhole", action = "Blackhole" }
-          );
-
-            appBuilder.UseWebApi(config);
-
-
-            appBuilder.UseFileServer(new FileServerOptions
-            {
-                RequestPath = new PathString(string.Empty),
-                FileSystem = new PhysicalFileSystem(Engine.ConfigService.GetContentFolder()),
-                EnableDirectoryBrowsing = false,
-
-            });
-
-        }
-    }
-}
+using Owin;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web.Http;
+using Autofac.Integration.WebApi;
+using Microsoft.Owin;
+using Jackett;
+using Microsoft.Owin.StaticFiles;
+using Microsoft.Owin.FileSystems;
+using Autofac;
+using Jackett.Services;
+using System.Web.Http.Tracing;
+using Jackett.Utils;
+using Microsoft.AspNet.Identity;
+using System.Web.Http.ExceptionHandling;
+using System.Net;
+
+[assembly: OwinStartup(typeof(Startup))]
+namespace Jackett
+{
+    public class Startup
+    {
+        public static bool TracingEnabled
+        {
+            get;
+            set;
+        }
+
+        public static bool LogRequests
+        {
+            get;
+            set;
+        }
+
+        public static string ClientOverride
+        {
+            get;
+            set;
+        }
+
+        public static string ProxyConnection
+        {
+            get;
+            set;
+        }
+
+        public static bool? DoSSLFix
+        {
+            get;
+            set;
+        }
+
+        public static bool? IgnoreSslErrors
+        {
+            get;
+            set;
+        }
+
+        public static string CustomDataFolder
+        {
+            get;
+            set;
+        }
+
+        public static string BasePath
+        {
+            get;
+            set;
+        }
+
+        public static bool NoRestart
+        {
+            get;
+            set;
+        }
+
+        public void Configuration(IAppBuilder appBuilder)
+        {
+            // Configure Web API for self-host. 
+            var config = new HttpConfiguration();
+
+            // try to fix SocketException crashes
+            // based on http://stackoverflow.com/questions/23368885/signalr-owin-self-host-on-linux-mono-socketexception-when-clients-lose-connectio/30583109#30583109
+            try
+            {
+                object httpListener;
+                if (appBuilder.Properties.TryGetValue(typeof(HttpListener).FullName, out httpListener) && httpListener is HttpListener)
+                {
+                    // HttpListener should not return exceptions that occur when sending the response to the client
+                    ((HttpListener)httpListener).IgnoreWriteExceptions = true;
+                    //Engine.Logger.Info("set HttpListener.IgnoreWriteExceptions = true");
+                }
+            }
+            catch (Exception e)
+            {
+                Engine.Logger.Error(e, "Error while setting HttpListener.IgnoreWriteExceptions = true");
+            }
+
+            appBuilder.Use<WebApiRootRedirectMiddleware>();
+
+            // register exception handler
+            config.Services.Replace(typeof(IExceptionHandler), new WebAPIExceptionHandler());
+
+            // Setup tracing if enabled
+            if (TracingEnabled)
+            {
+                config.EnableSystemDiagnosticsTracing();
+                config.Services.Replace(typeof(ITraceWriter), new WebAPIToNLogTracer());
+            }
+            // Add request logging if enabled
+            if (LogRequests)
+            {
+                config.MessageHandlers.Add(new WebAPIRequestLogger());
+            }
+            config.DependencyResolver = new AutofacWebApiDependencyResolver(Engine.GetContainer());
+            config.MapHttpAttributeRoutes();
+
+            config.Routes.MapHttpRoute(
+                name: "Admin",
+                routeTemplate: "admin/{action}",
+                defaults: new { controller = "Admin" }
+            );
+
+            config.Routes.MapHttpRoute(
+                name: "apiDefault",
+                routeTemplate: "api/{indexerID}",
+                defaults: new { controller = "Torznab", action = "Call" }
+            );
+
+            config.Routes.MapHttpRoute(
+               name: "api",
+               routeTemplate: "api/{indexerID}/api",
+               defaults: new { controller = "Torznab", action = "Call" }
+           );
+
+            config.Routes.MapHttpRoute(
+               name: "torznabDefault",
+               routeTemplate: "torznab/{indexerID}",
+               defaults: new { controller = "Torznab", action = "Call" }
+           );
+
+            config.Routes.MapHttpRoute(
+               name: "torznab",
+               routeTemplate: "torznab/{indexerID}/api",
+               defaults: new { controller = "Torznab", action = "Call" }
+           );
+
+            config.Routes.MapHttpRoute(
+              name: "potatoDefault",
+              routeTemplate: "potato/{indexerID}",
+              defaults: new { controller = "Potato", action = "Call" }
+          );
+
+            config.Routes.MapHttpRoute(
+               name: "potato",
+               routeTemplate: "potato/{indexerID}/api",
+               defaults: new { controller = "Potato", action = "Call" }
+           );
+
+            config.Routes.MapHttpRoute(
+                name: "download",
+                routeTemplate: "dl/{indexerID}/{apiKey}",
+                defaults: new { controller = "Download", action = "Download" }
+            );
+
+            config.Routes.MapHttpRoute(
+              name: "blackhole",
+              routeTemplate: "bh/{indexerID}/{apikey}",
+              defaults: new { controller = "Blackhole", action = "Blackhole" }
+          );
+
+            appBuilder.UseWebApi(config);
+
+
+            appBuilder.UseFileServer(new FileServerOptions
+            {
+                RequestPath = new PathString(string.Empty),
+                FileSystem = new PhysicalFileSystem(Engine.ConfigService.GetContentFolder()),
+                EnableDirectoryBrowsing = false,
+
+            });
+
+        }
+    }
+}
diff --git a/src/Jackett/Utils/BrowserUtil.cs b/src/Jackett/Utils/BrowserUtil.cs
index 9d1fd1e6616003150fbca3059478bbc592c51d2b..8c8885170f3ebb9cfa476c5fd4008c5ae9ecd6f0 100644
--- a/src/Jackett/Utils/BrowserUtil.cs
+++ b/src/Jackett/Utils/BrowserUtil.cs
@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 
 namespace Jackett.Utils
@@ -23,36 +23,36 @@ namespace Jackett.Utils
             }
         }
 
-        // This can be used to decode e-mail addresses protected by cloudflare
-        public static string DecodeCloudFlareProtectedEmail(string input)
-        {
-            var key = Convert.ToInt32(input.Substring(0, 2), 16);
-            string result = "";
-            for (var i = 2; i < input.Length - 1; i += 2)
-            {
-                var hexChar = input.Substring(i, 2);
-                var intChar = Convert.ToInt32(hexChar, 16) ^ key;
-                var strChar = Convert.ToChar(intChar);
-                result += strChar;
-            }
-            return result;
-        }
-
-        // decode cloudflare protected emails in a HTML document
-        public static string DecodeCloudFlareProtectedEmailFromHTML(string html)
-        {
-            Regex CFEMailRegex = new Regex("<span class=\"__cf_email__\" data-cfemail=\"(\\w+)\">\\[email&#160;protected\\]<\\/span><script data-cfhash='[\\w]+' type=\"text\\/javascript\">.*?<\\/script>", RegexOptions.Compiled);
-            var CFEMailRegexMatches = CFEMailRegex.Match(html);
-
-            while (CFEMailRegexMatches.Success)
-            {
-                string all = CFEMailRegexMatches.Groups[0].Value;
-                string cfemail = CFEMailRegexMatches.Groups[1].Value;
-                var decoded = DecodeCloudFlareProtectedEmail(cfemail);
-                html = html.Replace(all, decoded);
-                CFEMailRegexMatches = CFEMailRegexMatches.NextMatch();
-            }
-            return html;
+        // This can be used to decode e-mail addresses protected by cloudflare
+        public static string DecodeCloudFlareProtectedEmail(string input)
+        {
+            var key = Convert.ToInt32(input.Substring(0, 2), 16);
+            string result = "";
+            for (var i = 2; i < input.Length - 1; i += 2)
+            {
+                var hexChar = input.Substring(i, 2);
+                var intChar = Convert.ToInt32(hexChar, 16) ^ key;
+                var strChar = Convert.ToChar(intChar);
+                result += strChar;
+            }
+            return result;
+        }
+
+        // decode cloudflare protected emails in a HTML document
+        public static string DecodeCloudFlareProtectedEmailFromHTML(string html)
+        {
+            Regex CFEMailRegex = new Regex("<span class=\"__cf_email__\" data-cfemail=\"(\\w+)\">\\[email&#160;protected\\]<\\/span><script data-cfhash='[\\w]+' type=\"text\\/javascript\">.*?<\\/script>", RegexOptions.Compiled);
+            var CFEMailRegexMatches = CFEMailRegex.Match(html);
+
+            while (CFEMailRegexMatches.Success)
+            {
+                string all = CFEMailRegexMatches.Groups[0].Value;
+                string cfemail = CFEMailRegexMatches.Groups[1].Value;
+                var decoded = DecodeCloudFlareProtectedEmail(cfemail);
+                html = html.Replace(all, decoded);
+                CFEMailRegexMatches = CFEMailRegexMatches.NextMatch();
+            }
+            return html;
         }
     }
 }
diff --git a/src/Jackett/Utils/Clients/HttpWebClient.cs b/src/Jackett/Utils/Clients/HttpWebClient.cs
index 6d9fa3a514777289433265f1567e487998d98d81..83a6c5a9193a430a52bdb914426a359369fb00b9 100644
--- a/src/Jackett/Utils/Clients/HttpWebClient.cs
+++ b/src/Jackett/Utils/Clients/HttpWebClient.cs
@@ -1,247 +1,247 @@
-using AutoMapper;
-using CloudFlareUtilities;
-using Jackett.Models;
-using Jackett.Services;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Security;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils.Clients
-{
-    public class HttpWebClient : IWebClient
-    {
-        static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
-
-        public HttpWebClient(IProcessService p, Logger l, IConfigurationService c)
-            : base(p: p,
-                   l: l,
-                   c: c)
-        {
-        }
-
-        override public void Init()
-        {
-            ServicePointManager.DefaultConnectionLimit = 1000;
-
-            if (Startup.IgnoreSslErrors == true)
-            {
-                logger.Info(string.Format("HttpWebClient: Disabling certificate validation"));
-                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
-            }
-
-            // custom handler for our own internal certificates
-            ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
-            {
-                if (sender.GetType() != typeof(HttpWebRequest))
-                    return sslPolicyErrors == SslPolicyErrors.None;
-
-                var request = (HttpWebRequest)sender;
-                var hash = certificate.GetCertHashString();
-
-                ICollection<string> hosts;
-                
-                trustedCertificates.TryGetValue(hash, out hosts);
-                if (hosts != null)
-                {
-                    if (hosts.Contains(request.Host))
-                        return true;
-                }
-                return sslPolicyErrors == SslPolicyErrors.None;
-            };
-        }
-
-        override protected async Task<WebClientByteResult> Run(WebRequest webRequest)
-        {
-            ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
-
-            var cookies = new CookieContainer();
-            if (!string.IsNullOrEmpty(webRequest.Cookies))
-            {
-                var uri = new Uri(webRequest.Url);
-                var cookieUrl = new Uri(uri.Scheme + "://" + uri.Host); // don't include the path, Scheme is needed for mono compatibility
-                foreach (var c in webRequest.Cookies.Split(';'))
-                {
-                    try
-                    {
-                        cookies.SetCookies(cookieUrl, c.Trim());
-                    }
-                    catch (CookieException ex)
-                    {
-                        logger.Info("(Non-critical) Problem loading cookie {0}, {1}, {2}", uri, c, ex.Message);
-                    }
-                }
-            }
-            var useProxy = false;
-            WebProxy proxyServer = null;
-            if (Startup.ProxyConnection != null)
-            {
-                proxyServer = new WebProxy(Startup.ProxyConnection, false);
-                useProxy = true;
-            }
-
-            using (ClearanceHandler clearanceHandlr = new ClearanceHandler())
-            {
-                using (HttpClientHandler clientHandlr = new HttpClientHandler
-                {
-                    CookieContainer = cookies,
-                    AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
-                    UseCookies = true,
-                    Proxy = proxyServer,
-                    UseProxy = useProxy,
-                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
-                })
-                {
-
-                    clearanceHandlr.InnerHandler = clientHandlr;
-                    using (var client = new HttpClient(clearanceHandlr))
-                    {
-                        if (webRequest.EmulateBrowser)
-                            client.DefaultRequestHeaders.Add("User-Agent", BrowserUtil.ChromeUserAgent);
-                        else
-                            client.DefaultRequestHeaders.Add("User-Agent", "Jackett/" + configService.GetVersion());
-
-                        HttpResponseMessage response = null;
-                        using (var request = new HttpRequestMessage())
-                        {
-                            request.Headers.ExpectContinue = false;
-                            request.RequestUri = new Uri(webRequest.Url);
-
-                            if (webRequest.Headers != null)
-                            {
-                                foreach (var header in webRequest.Headers)
-                                {
-                                    if (header.Key != "Content-Type")
-                                    {
-                                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
-                                    }
-                                }
-                            }
-
-                            if (!string.IsNullOrEmpty(webRequest.Referer))
-                                request.Headers.Referrer = new Uri(webRequest.Referer);
-
-                            if (!string.IsNullOrEmpty(webRequest.RawBody))
-                            {
-                                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast<KeyValuePair<string, string>?>().FirstOrDefault();
-                                if (type.HasValue)
-                                {
-                                    var str = new StringContent(webRequest.RawBody);
-                                    str.Headers.Remove("Content-Type");
-                                    str.Headers.Add("Content-Type", type.Value.Value);
-                                    request.Content = str;
-                                }
-                                else
-                                    request.Content = new StringContent(webRequest.RawBody);
-                                request.Method = HttpMethod.Post;
-                            }
-                            else if (webRequest.Type == RequestType.POST)
-                            {
-                                if (webRequest.PostData != null)
-                                    request.Content = new FormUrlEncodedContent(webRequest.PostData);
-                                request.Method = HttpMethod.Post;
-                            }
-                            else
-                            {
-                                request.Method = HttpMethod.Get;
-                            }
-
-                            using (response = await client.SendAsync(request))
-                            {
-                                var result = new WebClientByteResult();
-                                result.Content = await response.Content.ReadAsByteArrayAsync();
-
-                                foreach (var header in response.Headers)
-                                {
-                                    IEnumerable<string> value = header.Value;
-                                    result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
-                                }
-
-                                // some cloudflare clients are using a refresh header
-                                // Pull it out manually 
-                                if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
-                                {
-                                    var refreshHeaders = response.Headers.GetValues("Refresh");
-                                    var redirval = "";
-                                    var redirtime = 0;
-                                    if (refreshHeaders != null)
-                                    {
-                                        foreach (var value in refreshHeaders)
-                                        {
-                                            var start = value.IndexOf("=");
-                                            var end = value.IndexOf(";");
-                                            var len = value.Length;
-                                            if (start > -1)
-                                            {
-                                                redirval = value.Substring(start + 1);
-                                                result.RedirectingTo = redirval;
-                                                // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
-                                                // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
-                                                // it shoudln't include service unavailable..only if we have this redirect header.
-                                                response.StatusCode = System.Net.HttpStatusCode.Redirect;
-                                                redirtime = Int32.Parse(value.Substring(0, end));
-                                                System.Threading.Thread.Sleep(redirtime * 1000);
-                                            }
-                                        }
-                                    }
-                                }
-                                if (response.Headers.Location != null)
-                                {
-                                    result.RedirectingTo = response.Headers.Location.ToString();
-                                }
-                                result.Status = response.StatusCode;
-
-                                // Compatiblity issue between the cookie format and httpclient
-                                // Pull it out manually ignoring the expiry date then set it manually
-                                // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
-                                IEnumerable<string> cookieHeaders;
-                                var responseCookies = new List<Tuple<string, string>>();
-
-                                if (response.Headers.TryGetValues("set-cookie", out cookieHeaders))
-                                {
-                                    foreach (var value in cookieHeaders)
-                                    {
-                                        var nameSplit = value.IndexOf('=');
-                                        if (nameSplit > -1)
-                                        {
-                                            responseCookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';'))) + ";"));
-                                        }
-                                    }
-
-                                    var cookieBuilder = new StringBuilder();
-                                    foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
-                                    {
-                                        cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
-                                    }
-                                    result.Cookies = cookieBuilder.ToString().Trim();
-                                }
-                                ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
-                                return result;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        override public void AddTrustedCertificate(string host, string hash)
-        {
-            hash = hash.ToUpper();
-            ICollection<string> hosts;
-            trustedCertificates.TryGetValue(hash.ToUpper(), out hosts);
-            if (hosts == null)
-            {
-                hosts = new HashSet<string>();
-                trustedCertificates[hash] = hosts;
-            }
-            hosts.Add(host);
-        }
-    }
-}
+using AutoMapper;
+using CloudFlareUtilities;
+using Jackett.Models;
+using Jackett.Services;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils.Clients
+{
+    public class HttpWebClient : IWebClient
+    {
+        static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
+
+        public HttpWebClient(IProcessService p, Logger l, IConfigurationService c)
+            : base(p: p,
+                   l: l,
+                   c: c)
+        {
+        }
+
+        override public void Init()
+        {
+            ServicePointManager.DefaultConnectionLimit = 1000;
+
+            if (Startup.IgnoreSslErrors == true)
+            {
+                logger.Info(string.Format("HttpWebClient: Disabling certificate validation"));
+                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
+            }
+
+            // custom handler for our own internal certificates
+            ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+            {
+                if (sender.GetType() != typeof(HttpWebRequest))
+                    return sslPolicyErrors == SslPolicyErrors.None;
+
+                var request = (HttpWebRequest)sender;
+                var hash = certificate.GetCertHashString();
+
+                ICollection<string> hosts;
+                
+                trustedCertificates.TryGetValue(hash, out hosts);
+                if (hosts != null)
+                {
+                    if (hosts.Contains(request.Host))
+                        return true;
+                }
+                return sslPolicyErrors == SslPolicyErrors.None;
+            };
+        }
+
+        override protected async Task<WebClientByteResult> Run(WebRequest webRequest)
+        {
+            ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
+
+            var cookies = new CookieContainer();
+            if (!string.IsNullOrEmpty(webRequest.Cookies))
+            {
+                var uri = new Uri(webRequest.Url);
+                var cookieUrl = new Uri(uri.Scheme + "://" + uri.Host); // don't include the path, Scheme is needed for mono compatibility
+                foreach (var c in webRequest.Cookies.Split(';'))
+                {
+                    try
+                    {
+                        cookies.SetCookies(cookieUrl, c.Trim());
+                    }
+                    catch (CookieException ex)
+                    {
+                        logger.Info("(Non-critical) Problem loading cookie {0}, {1}, {2}", uri, c, ex.Message);
+                    }
+                }
+            }
+            var useProxy = false;
+            WebProxy proxyServer = null;
+            if (Startup.ProxyConnection != null)
+            {
+                proxyServer = new WebProxy(Startup.ProxyConnection, false);
+                useProxy = true;
+            }
+
+            using (ClearanceHandler clearanceHandlr = new ClearanceHandler())
+            {
+                using (HttpClientHandler clientHandlr = new HttpClientHandler
+                {
+                    CookieContainer = cookies,
+                    AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
+                    UseCookies = true,
+                    Proxy = proxyServer,
+                    UseProxy = useProxy,
+                    AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
+                })
+                {
+
+                    clearanceHandlr.InnerHandler = clientHandlr;
+                    using (var client = new HttpClient(clearanceHandlr))
+                    {
+                        if (webRequest.EmulateBrowser)
+                            client.DefaultRequestHeaders.Add("User-Agent", BrowserUtil.ChromeUserAgent);
+                        else
+                            client.DefaultRequestHeaders.Add("User-Agent", "Jackett/" + configService.GetVersion());
+
+                        HttpResponseMessage response = null;
+                        using (var request = new HttpRequestMessage())
+                        {
+                            request.Headers.ExpectContinue = false;
+                            request.RequestUri = new Uri(webRequest.Url);
+
+                            if (webRequest.Headers != null)
+                            {
+                                foreach (var header in webRequest.Headers)
+                                {
+                                    if (header.Key != "Content-Type")
+                                    {
+                                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
+                                    }
+                                }
+                            }
+
+                            if (!string.IsNullOrEmpty(webRequest.Referer))
+                                request.Headers.Referrer = new Uri(webRequest.Referer);
+
+                            if (!string.IsNullOrEmpty(webRequest.RawBody))
+                            {
+                                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast<KeyValuePair<string, string>?>().FirstOrDefault();
+                                if (type.HasValue)
+                                {
+                                    var str = new StringContent(webRequest.RawBody);
+                                    str.Headers.Remove("Content-Type");
+                                    str.Headers.Add("Content-Type", type.Value.Value);
+                                    request.Content = str;
+                                }
+                                else
+                                    request.Content = new StringContent(webRequest.RawBody);
+                                request.Method = HttpMethod.Post;
+                            }
+                            else if (webRequest.Type == RequestType.POST)
+                            {
+                                if (webRequest.PostData != null)
+                                    request.Content = new FormUrlEncodedContent(webRequest.PostData);
+                                request.Method = HttpMethod.Post;
+                            }
+                            else
+                            {
+                                request.Method = HttpMethod.Get;
+                            }
+
+                            using (response = await client.SendAsync(request))
+                            {
+                                var result = new WebClientByteResult();
+                                result.Content = await response.Content.ReadAsByteArrayAsync();
+
+                                foreach (var header in response.Headers)
+                                {
+                                    IEnumerable<string> value = header.Value;
+                                    result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
+                                }
+
+                                // some cloudflare clients are using a refresh header
+                                // Pull it out manually 
+                                if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
+                                {
+                                    var refreshHeaders = response.Headers.GetValues("Refresh");
+                                    var redirval = "";
+                                    var redirtime = 0;
+                                    if (refreshHeaders != null)
+                                    {
+                                        foreach (var value in refreshHeaders)
+                                        {
+                                            var start = value.IndexOf("=");
+                                            var end = value.IndexOf(";");
+                                            var len = value.Length;
+                                            if (start > -1)
+                                            {
+                                                redirval = value.Substring(start + 1);
+                                                result.RedirectingTo = redirval;
+                                                // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
+                                                // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
+                                                // it shoudln't include service unavailable..only if we have this redirect header.
+                                                response.StatusCode = System.Net.HttpStatusCode.Redirect;
+                                                redirtime = Int32.Parse(value.Substring(0, end));
+                                                System.Threading.Thread.Sleep(redirtime * 1000);
+                                            }
+                                        }
+                                    }
+                                }
+                                if (response.Headers.Location != null)
+                                {
+                                    result.RedirectingTo = response.Headers.Location.ToString();
+                                }
+                                result.Status = response.StatusCode;
+
+                                // Compatiblity issue between the cookie format and httpclient
+                                // Pull it out manually ignoring the expiry date then set it manually
+                                // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
+                                IEnumerable<string> cookieHeaders;
+                                var responseCookies = new List<Tuple<string, string>>();
+
+                                if (response.Headers.TryGetValues("set-cookie", out cookieHeaders))
+                                {
+                                    foreach (var value in cookieHeaders)
+                                    {
+                                        var nameSplit = value.IndexOf('=');
+                                        if (nameSplit > -1)
+                                        {
+                                            responseCookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';'))) + ";"));
+                                        }
+                                    }
+
+                                    var cookieBuilder = new StringBuilder();
+                                    foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
+                                    {
+                                        cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
+                                    }
+                                    result.Cookies = cookieBuilder.ToString().Trim();
+                                }
+                                ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
+                                return result;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        override public void AddTrustedCertificate(string host, string hash)
+        {
+            hash = hash.ToUpper();
+            ICollection<string> hosts;
+            trustedCertificates.TryGetValue(hash.ToUpper(), out hosts);
+            if (hosts == null)
+            {
+                hosts = new HashSet<string>();
+                trustedCertificates[hash] = hosts;
+            }
+            hosts.Add(host);
+        }
+    }
+}
diff --git a/src/Jackett/Utils/Clients/HttpWebClient2.cs b/src/Jackett/Utils/Clients/HttpWebClient2.cs
index 6102551df65ef8c25c6d39940d6ef1155769e11b..1c978bd6ba8f7483b7d6e53c915ae3ad3b126417 100644
--- a/src/Jackett/Utils/Clients/HttpWebClient2.cs
+++ b/src/Jackett/Utils/Clients/HttpWebClient2.cs
@@ -1,241 +1,241 @@
-using AutoMapper;
-using CloudFlareUtilities;
-using Jackett.Models;
-using Jackett.Services;
-using NLog;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net;
-using System.Net.Http;
-using System.Net.Http.Headers;
-using System.Net.Security;
-using System.Security.Cryptography.X509Certificates;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils.Clients
-{
-    // Compared to HttpWebClient this implementation will reuse the HttpClient instance (one per indexer).
-    // This should improve performance and avoid problems with too man open file handles.
-    public class HttpWebClient2 : IWebClient
-    {
-        CookieContainer cookies;
-        ClearanceHandler clearanceHandlr;
-        HttpClientHandler clientHandlr;
-        HttpClient client;
-
-        static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
-
-        public HttpWebClient2(IProcessService p, Logger l, IConfigurationService c)
-            : base(p: p,
-                   l: l,
-                   c: c)
-        {
-            cookies = new CookieContainer();
-            var useProxy = false;
-            WebProxy proxyServer = null;
-            if (Startup.ProxyConnection != null)
-            {
-                proxyServer = new WebProxy(Startup.ProxyConnection, false);
-                useProxy = true;
-            }
-
-            clearanceHandlr = new ClearanceHandler();
-            clientHandlr = new HttpClientHandler
-            {
-                CookieContainer = cookies,
-                AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
-                UseCookies = true,
-                Proxy = proxyServer,
-                UseProxy = useProxy,
-                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
-            };
-
-            clearanceHandlr.InnerHandler = clientHandlr;
-            client = new HttpClient(clearanceHandlr);
-        }
-
-        override public void Init()
-        {
-            if (Startup.IgnoreSslErrors == true)
-            {
-                logger.Info(string.Format("HttpWebClient2: Disabling certificate validation"));
-                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
-            }
-
-            ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
-
-            // custom handler for our own internal certificates
-            ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
-            {
-                if (sender.GetType() != typeof(HttpWebRequest))
-                    return sslPolicyErrors == SslPolicyErrors.None;
-
-                var request = (HttpWebRequest)sender;
-                var hash = certificate.GetCertHashString();
-
-                ICollection<string> hosts;
-
-                trustedCertificates.TryGetValue(hash, out hosts);
-                if (hosts != null)
-                {
-                    if (hosts.Contains(request.Host))
-                        return true;
-                }
-                return sslPolicyErrors == SslPolicyErrors.None;
-            };
-        }
-
-        override protected async Task<WebClientByteResult> Run(WebRequest webRequest)
-        {
-            HttpResponseMessage response = null;
-            var request = new HttpRequestMessage();
-            request.Headers.ExpectContinue = false;
-            request.RequestUri = new Uri(webRequest.Url);
-
-            if (webRequest.EmulateBrowser)
-                request.Headers.UserAgent.ParseAdd(BrowserUtil.ChromeUserAgent);
-            else
-                request.Headers.UserAgent.ParseAdd("Jackett/" + configService.GetVersion());
-
-            // clear cookies from cookiecontainer
-            var oldCookies = cookies.GetCookies(request.RequestUri);
-            foreach (Cookie oldCookie in oldCookies)
-            {
-                oldCookie.Expired = true;
-            }
-
-            if (!string.IsNullOrEmpty(webRequest.Cookies))
-            {
-                // add cookies to cookiecontainer
-                var cookieUrl = new Uri(request.RequestUri.Scheme + "://" + request.RequestUri.Host); // don't include the path, Scheme is needed for mono compatibility
-                foreach (var ccookiestr in webRequest.Cookies.Split(';'))
-                {
-                    var cookiestrparts = ccookiestr.Split('=');
-                    var name = cookiestrparts[0].Trim();
-                    if (string.IsNullOrWhiteSpace(name))
-                        continue;
-                    var value = "";
-                    if (cookiestrparts.Length >= 2)
-                        value = cookiestrparts[1].Trim();
-                    var cookie = new Cookie(name, value);
-                    cookies.Add(cookieUrl, cookie);
-                }
-            }
-
-            if (webRequest.Headers != null)
-            {
-                foreach (var header in webRequest.Headers)
-                {
-                    if (header.Key != "Content-Type")
-                    {
-                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
-                    }
-                }
-            }
-
-            if (!string.IsNullOrEmpty(webRequest.Referer))
-                request.Headers.Referrer = new Uri(webRequest.Referer);
-
-            if (!string.IsNullOrEmpty(webRequest.RawBody))
-            {
-                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast<KeyValuePair<string,string>?>().FirstOrDefault();
-                if (type.HasValue)
-                {
-                    var str = new StringContent(webRequest.RawBody);
-                    str.Headers.Remove("Content-Type");
-                    str.Headers.Add("Content-Type", type.Value.Value);
-                    request.Content = str;
-                }
-                else
-                    request.Content = new StringContent(webRequest.RawBody);
-                request.Method = HttpMethod.Post;
-            }
-            else if (webRequest.Type == RequestType.POST)
-            {
-                if (webRequest.PostData != null)
-                    request.Content = new FormUrlEncodedContent(webRequest.PostData);
-                request.Method = HttpMethod.Post;
-            }
-            else
-            {
-                request.Method = HttpMethod.Get;
-            }
-
-            response = await client.SendAsync(request);
-
-            var result = new WebClientByteResult();
-            result.Content = await response.Content.ReadAsByteArrayAsync();
-
-            foreach (var header in response.Headers)
-            {
-                IEnumerable<string> value = header.Value;
-                result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
-            }
-
-            // some cloudflare clients are using a refresh header
-            // Pull it out manually 
-            if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
-            {
-                var refreshHeaders = response.Headers.GetValues("Refresh");
-                var redirval = "";
-                var redirtime = 0;
-                if (refreshHeaders != null)
-                {
-                    foreach (var value in refreshHeaders)
-                    {
-                        var start = value.IndexOf("=");
-                        var end = value.IndexOf(";");
-                        var len = value.Length;
-                        if (start > -1)
-                        {
-                            redirval = value.Substring(start + 1);
-                            result.RedirectingTo = redirval;
-                            // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
-                            // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
-                            // it shoudln't include service unavailable..only if we have this redirect header.
-                            response.StatusCode = System.Net.HttpStatusCode.Redirect;
-                            redirtime = Int32.Parse(value.Substring(0, end));
-                            System.Threading.Thread.Sleep(redirtime * 1000);
-                        }
-                    }
-                }
-            }
-            if (response.Headers.Location != null)
-            {
-                result.RedirectingTo = response.Headers.Location.ToString();
-            }
-            result.Status = response.StatusCode;
-
-            // Compatiblity issue between the cookie format and httpclient
-            // Pull it out manually ignoring the expiry date then set it manually
-            // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
-            IEnumerable<string> cookieHeaders;
-            var responseCookies = new List<Tuple<string, string>>();
-
-            if (response.Headers.TryGetValues("set-cookie", out cookieHeaders))
-            {
-                foreach (var value in cookieHeaders)
-                {
-                    logger.Debug(value);
-                    var nameSplit = value.IndexOf('=');
-                    if (nameSplit > -1)
-                    {
-                        responseCookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';')))+";"));
-                    }
-                }
-
-                var cookieBuilder = new StringBuilder();
-                foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
-                {
-                    cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
-                }
-                result.Cookies = cookieBuilder.ToString().Trim();
-            }
-            ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
-            return result;
-        }
-    }
-}
+using AutoMapper;
+using CloudFlareUtilities;
+using Jackett.Models;
+using Jackett.Services;
+using NLog;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Http;
+using System.Net.Http.Headers;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils.Clients
+{
+    // Compared to HttpWebClient this implementation will reuse the HttpClient instance (one per indexer).
+    // This should improve performance and avoid problems with too man open file handles.
+    public class HttpWebClient2 : IWebClient
+    {
+        CookieContainer cookies;
+        ClearanceHandler clearanceHandlr;
+        HttpClientHandler clientHandlr;
+        HttpClient client;
+
+        static protected Dictionary<string, ICollection<string>> trustedCertificates = new Dictionary<string, ICollection<string>>();
+
+        public HttpWebClient2(IProcessService p, Logger l, IConfigurationService c)
+            : base(p: p,
+                   l: l,
+                   c: c)
+        {
+            cookies = new CookieContainer();
+            var useProxy = false;
+            WebProxy proxyServer = null;
+            if (Startup.ProxyConnection != null)
+            {
+                proxyServer = new WebProxy(Startup.ProxyConnection, false);
+                useProxy = true;
+            }
+
+            clearanceHandlr = new ClearanceHandler();
+            clientHandlr = new HttpClientHandler
+            {
+                CookieContainer = cookies,
+                AllowAutoRedirect = false, // Do not use this - Bugs ahoy! Lost cookies and more.
+                UseCookies = true,
+                Proxy = proxyServer,
+                UseProxy = useProxy,
+                AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate
+            };
+
+            clearanceHandlr.InnerHandler = clientHandlr;
+            client = new HttpClient(clearanceHandlr);
+        }
+
+        override public void Init()
+        {
+            if (Startup.IgnoreSslErrors == true)
+            {
+                logger.Info(string.Format("HttpWebClient2: Disabling certificate validation"));
+                ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => { return true; };
+            }
+
+            ServicePointManager.SecurityProtocol = (SecurityProtocolType)192 | (SecurityProtocolType)768 | (SecurityProtocolType)3072;
+
+            // custom handler for our own internal certificates
+            ServicePointManager.ServerCertificateValidationCallback += delegate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
+            {
+                if (sender.GetType() != typeof(HttpWebRequest))
+                    return sslPolicyErrors == SslPolicyErrors.None;
+
+                var request = (HttpWebRequest)sender;
+                var hash = certificate.GetCertHashString();
+
+                ICollection<string> hosts;
+
+                trustedCertificates.TryGetValue(hash, out hosts);
+                if (hosts != null)
+                {
+                    if (hosts.Contains(request.Host))
+                        return true;
+                }
+                return sslPolicyErrors == SslPolicyErrors.None;
+            };
+        }
+
+        override protected async Task<WebClientByteResult> Run(WebRequest webRequest)
+        {
+            HttpResponseMessage response = null;
+            var request = new HttpRequestMessage();
+            request.Headers.ExpectContinue = false;
+            request.RequestUri = new Uri(webRequest.Url);
+
+            if (webRequest.EmulateBrowser)
+                request.Headers.UserAgent.ParseAdd(BrowserUtil.ChromeUserAgent);
+            else
+                request.Headers.UserAgent.ParseAdd("Jackett/" + configService.GetVersion());
+
+            // clear cookies from cookiecontainer
+            var oldCookies = cookies.GetCookies(request.RequestUri);
+            foreach (Cookie oldCookie in oldCookies)
+            {
+                oldCookie.Expired = true;
+            }
+
+            if (!string.IsNullOrEmpty(webRequest.Cookies))
+            {
+                // add cookies to cookiecontainer
+                var cookieUrl = new Uri(request.RequestUri.Scheme + "://" + request.RequestUri.Host); // don't include the path, Scheme is needed for mono compatibility
+                foreach (var ccookiestr in webRequest.Cookies.Split(';'))
+                {
+                    var cookiestrparts = ccookiestr.Split('=');
+                    var name = cookiestrparts[0].Trim();
+                    if (string.IsNullOrWhiteSpace(name))
+                        continue;
+                    var value = "";
+                    if (cookiestrparts.Length >= 2)
+                        value = cookiestrparts[1].Trim();
+                    var cookie = new Cookie(name, value);
+                    cookies.Add(cookieUrl, cookie);
+                }
+            }
+
+            if (webRequest.Headers != null)
+            {
+                foreach (var header in webRequest.Headers)
+                {
+                    if (header.Key != "Content-Type")
+                    {
+                        request.Headers.TryAddWithoutValidation(header.Key, header.Value);
+                    }
+                }
+            }
+
+            if (!string.IsNullOrEmpty(webRequest.Referer))
+                request.Headers.Referrer = new Uri(webRequest.Referer);
+
+            if (!string.IsNullOrEmpty(webRequest.RawBody))
+            {
+                var type = webRequest.Headers.Where(h => h.Key == "Content-Type").Cast<KeyValuePair<string,string>?>().FirstOrDefault();
+                if (type.HasValue)
+                {
+                    var str = new StringContent(webRequest.RawBody);
+                    str.Headers.Remove("Content-Type");
+                    str.Headers.Add("Content-Type", type.Value.Value);
+                    request.Content = str;
+                }
+                else
+                    request.Content = new StringContent(webRequest.RawBody);
+                request.Method = HttpMethod.Post;
+            }
+            else if (webRequest.Type == RequestType.POST)
+            {
+                if (webRequest.PostData != null)
+                    request.Content = new FormUrlEncodedContent(webRequest.PostData);
+                request.Method = HttpMethod.Post;
+            }
+            else
+            {
+                request.Method = HttpMethod.Get;
+            }
+
+            response = await client.SendAsync(request);
+
+            var result = new WebClientByteResult();
+            result.Content = await response.Content.ReadAsByteArrayAsync();
+
+            foreach (var header in response.Headers)
+            {
+                IEnumerable<string> value = header.Value;
+                result.Headers[header.Key.ToLowerInvariant()] = value.ToArray();
+            }
+
+            // some cloudflare clients are using a refresh header
+            // Pull it out manually 
+            if (response.StatusCode == System.Net.HttpStatusCode.ServiceUnavailable && response.Headers.Contains("Refresh"))
+            {
+                var refreshHeaders = response.Headers.GetValues("Refresh");
+                var redirval = "";
+                var redirtime = 0;
+                if (refreshHeaders != null)
+                {
+                    foreach (var value in refreshHeaders)
+                    {
+                        var start = value.IndexOf("=");
+                        var end = value.IndexOf(";");
+                        var len = value.Length;
+                        if (start > -1)
+                        {
+                            redirval = value.Substring(start + 1);
+                            result.RedirectingTo = redirval;
+                            // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
+                            // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
+                            // it shoudln't include service unavailable..only if we have this redirect header.
+                            response.StatusCode = System.Net.HttpStatusCode.Redirect;
+                            redirtime = Int32.Parse(value.Substring(0, end));
+                            System.Threading.Thread.Sleep(redirtime * 1000);
+                        }
+                    }
+                }
+            }
+            if (response.Headers.Location != null)
+            {
+                result.RedirectingTo = response.Headers.Location.ToString();
+            }
+            result.Status = response.StatusCode;
+
+            // Compatiblity issue between the cookie format and httpclient
+            // Pull it out manually ignoring the expiry date then set it manually
+            // http://stackoverflow.com/questions/14681144/httpclient-not-storing-cookies-in-cookiecontainer
+            IEnumerable<string> cookieHeaders;
+            var responseCookies = new List<Tuple<string, string>>();
+
+            if (response.Headers.TryGetValues("set-cookie", out cookieHeaders))
+            {
+                foreach (var value in cookieHeaders)
+                {
+                    logger.Debug(value);
+                    var nameSplit = value.IndexOf('=');
+                    if (nameSplit > -1)
+                    {
+                        responseCookies.Add(new Tuple<string, string>(value.Substring(0, nameSplit), value.Substring(0, value.IndexOf(';') == -1 ? value.Length : (value.IndexOf(';')))+";"));
+                    }
+                }
+
+                var cookieBuilder = new StringBuilder();
+                foreach (var cookieGroup in responseCookies.GroupBy(c => c.Item1))
+                {
+                    cookieBuilder.AppendFormat("{0} ", cookieGroup.Last().Item2);
+                }
+                result.Cookies = cookieBuilder.ToString().Trim();
+            }
+            ServerUtil.ResureRedirectIsFullyQualified(webRequest, result);
+            return result;
+        }
+    }
+}
diff --git a/src/Jackett/Utils/Clients/IWebClient.cs b/src/Jackett/Utils/Clients/IWebClient.cs
index c452bb4a786c98a0160ae9323108abcf291bfde1..61b280de99e7d5d0d60673199077ba2831a4cdeb 100644
--- a/src/Jackett/Utils/Clients/IWebClient.cs
+++ b/src/Jackett/Utils/Clients/IWebClient.cs
@@ -1,150 +1,150 @@
-using AutoMapper;
+using AutoMapper;
 using Jackett.Models;
-using Jackett.Services;
-using NLog;
+using Jackett.Services;
+using NLog;
 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 
 namespace Jackett.Utils.Clients
 {
     public abstract class IWebClient
     {
-        protected Logger logger;
+        protected Logger logger;
         protected IConfigurationService configService;
         protected IProcessService processService;
         protected DateTime lastRequest = DateTime.MinValue;
         protected TimeSpan requestDelayTimeSpan;
-        public double requestDelay
-        {
-            get { return requestDelayTimeSpan.TotalSeconds; }
-            set
-            {
-                requestDelayTimeSpan = TimeSpan.FromSeconds(value);
-            }
+        public double requestDelay
+        {
+            get { return requestDelayTimeSpan.TotalSeconds; }
+            set
+            {
+                requestDelayTimeSpan = TimeSpan.FromSeconds(value);
+            }
         }
 
-        virtual public void AddTrustedCertificate(string host, string hash)
-        {
-            // not implemented by default
+        virtual public void AddTrustedCertificate(string host, string hash)
+        {
+            // not implemented by default
         }
 
-        public IWebClient(IProcessService p, Logger l, IConfigurationService c)
-        {
-            processService = p;
-            logger = l;
-            configService = c;
+        public IWebClient(IProcessService p, Logger l, IConfigurationService c)
+        {
+            processService = p;
+            logger = l;
+            configService = c;
         }
 
-        async protected void DelayRequest(WebRequest request)
-        {
-            if (requestDelay != 0)
-            {
-                var timeElapsed = DateTime.Now - lastRequest;
-                if (timeElapsed < requestDelayTimeSpan)
-                {
-                    var delay = requestDelayTimeSpan - timeElapsed;
-                    logger.Debug(string.Format("IWebClient: delaying request for {0} by {1} seconds", request.Url, delay.TotalSeconds.ToString()));
-                    await Task.Delay(delay);
-                }
-                lastRequest = DateTime.Now;
-            }
+        async protected void DelayRequest(WebRequest request)
+        {
+            if (requestDelay != 0)
+            {
+                var timeElapsed = DateTime.Now - lastRequest;
+                if (timeElapsed < requestDelayTimeSpan)
+                {
+                    var delay = requestDelayTimeSpan - timeElapsed;
+                    logger.Debug(string.Format("IWebClient: delaying request for {0} by {1} seconds", request.Url, delay.TotalSeconds.ToString()));
+                    await Task.Delay(delay);
+                }
+                lastRequest = DateTime.Now;
+            }
         }
 
-        virtual protected void PrepareRequest(WebRequest request)
-        {
-            // add accept header if not set
-            if (request.Headers == null)
-                request.Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
-            var hasAccept = false;
-            foreach (var header in request.Headers)
-            {
-                var key = header.Key.ToLower();
-                if (key == "accept")
-                {
-                    hasAccept = true;
-                }
-            }
-            if (!hasAccept)
-                request.Headers.Add("Accept", "*/*");
-            return;
+        virtual protected void PrepareRequest(WebRequest request)
+        {
+            // add accept header if not set
+            if (request.Headers == null)
+                request.Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+            var hasAccept = false;
+            foreach (var header in request.Headers)
+            {
+                var key = header.Key.ToLower();
+                if (key == "accept")
+                {
+                    hasAccept = true;
+                }
+            }
+            if (!hasAccept)
+                request.Headers.Add("Accept", "*/*");
+            return;
         }
 
-        virtual public async Task<WebClientByteResult> GetBytes(WebRequest request)
-        {
-            logger.Debug(string.Format("IWebClient.GetBytes(Url:{0})", request.Url));
-            PrepareRequest(request);
-            DelayRequest(request);
-            var result = await Run(request);
-            result.Request = request;
-            logger.Debug(string.Format("IWebClient: Returning {0} => {1} bytes", result.Status, (result.IsRedirect ? result.RedirectingTo + " " : "") + (result.Content == null ? "<NULL>" : result.Content.Length.ToString())));
-            return result;
-        }
-
-        virtual public async Task<WebClientStringResult> GetString(WebRequest request)
-        {
-            logger.Debug(string.Format("IWebClient.GetString(Url:{0})", request.Url));
-            PrepareRequest(request);
-            DelayRequest(request);
-            var result = await Run(request);
-            result.Request = request;
-            WebClientStringResult stringResult = Mapper.Map<WebClientStringResult>(result);
-            Encoding encoding = null;
-            if (request.Encoding != null)
-            {
-                encoding = request.Encoding;
-            }
-            else if (result.Headers.ContainsKey("content-type"))
-            {
-                Regex CharsetRegex = new Regex(@"charset=([\w-]+)", RegexOptions.Compiled);
-                var CharsetRegexMatch = CharsetRegex.Match(result.Headers["content-type"][0]);
-                if (CharsetRegexMatch.Success)
-                {
-                    var charset = CharsetRegexMatch.Groups[1].Value;
-                    try
-                    {
-                        encoding = Encoding.GetEncoding(charset);
-                    }
-                    catch (Exception ex)
-                    {
-                        logger.Error(string.Format("IWebClient.GetString(Url:{0}): Error loading encoding {0} based on header {1}: {2}", request.Url, charset, result.Headers["content-type"][0], ex));
-                    }
-                }
-                else
-                {
-                    logger.Error(string.Format("IWebClient.GetString(Url:{0}): Got header without charset: {0}", request.Url, result.Headers["content-type"][0]));
-                }
-            }
-
-            if (encoding == null)
-            {
-                logger.Error(string.Format("IWebClient.GetString(Url:{0}): No encoding detected, defaulting to UTF-8", request.Url));
-                encoding = Encoding.UTF8;
-            }
-
-            string decodedContent = null;
-            if (result.Content != null)
-                decodedContent = encoding.GetString(result.Content);
-
-            stringResult.Content = decodedContent;
-            logger.Debug(string.Format("IWebClient: Returning {0} => {1}", result.Status, (result.IsRedirect ? result.RedirectingTo + " " : "") + (decodedContent == null ? "<NULL>" : decodedContent)));
-
-            string[] server;
-            if (stringResult.Headers.TryGetValue("server", out server))
-            {
-                if (server[0] == "cloudflare-nginx")
-                    stringResult.Content = BrowserUtil.DecodeCloudFlareProtectedEmailFromHTML(stringResult.Content);
-            }
-            return stringResult;
-        }
-
-#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
-        virtual protected async Task<WebClientByteResult> Run(WebRequest webRequest) { throw new NotImplementedException(); }
-#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
-
+        virtual public async Task<WebClientByteResult> GetBytes(WebRequest request)
+        {
+            logger.Debug(string.Format("IWebClient.GetBytes(Url:{0})", request.Url));
+            PrepareRequest(request);
+            DelayRequest(request);
+            var result = await Run(request);
+            result.Request = request;
+            logger.Debug(string.Format("IWebClient: Returning {0} => {1} bytes", result.Status, (result.IsRedirect ? result.RedirectingTo + " " : "") + (result.Content == null ? "<NULL>" : result.Content.Length.ToString())));
+            return result;
+        }
+
+        virtual public async Task<WebClientStringResult> GetString(WebRequest request)
+        {
+            logger.Debug(string.Format("IWebClient.GetString(Url:{0})", request.Url));
+            PrepareRequest(request);
+            DelayRequest(request);
+            var result = await Run(request);
+            result.Request = request;
+            WebClientStringResult stringResult = Mapper.Map<WebClientStringResult>(result);
+            Encoding encoding = null;
+            if (request.Encoding != null)
+            {
+                encoding = request.Encoding;
+            }
+            else if (result.Headers.ContainsKey("content-type"))
+            {
+                Regex CharsetRegex = new Regex(@"charset=([\w-]+)", RegexOptions.Compiled);
+                var CharsetRegexMatch = CharsetRegex.Match(result.Headers["content-type"][0]);
+                if (CharsetRegexMatch.Success)
+                {
+                    var charset = CharsetRegexMatch.Groups[1].Value;
+                    try
+                    {
+                        encoding = Encoding.GetEncoding(charset);
+                    }
+                    catch (Exception ex)
+                    {
+                        logger.Error(string.Format("IWebClient.GetString(Url:{0}): Error loading encoding {0} based on header {1}: {2}", request.Url, charset, result.Headers["content-type"][0], ex));
+                    }
+                }
+                else
+                {
+                    logger.Error(string.Format("IWebClient.GetString(Url:{0}): Got header without charset: {0}", request.Url, result.Headers["content-type"][0]));
+                }
+            }
+
+            if (encoding == null)
+            {
+                logger.Error(string.Format("IWebClient.GetString(Url:{0}): No encoding detected, defaulting to UTF-8", request.Url));
+                encoding = Encoding.UTF8;
+            }
+
+            string decodedContent = null;
+            if (result.Content != null)
+                decodedContent = encoding.GetString(result.Content);
+
+            stringResult.Content = decodedContent;
+            logger.Debug(string.Format("IWebClient: Returning {0} => {1}", result.Status, (result.IsRedirect ? result.RedirectingTo + " " : "") + (decodedContent == null ? "<NULL>" : decodedContent)));
+
+            string[] server;
+            if (stringResult.Headers.TryGetValue("server", out server))
+            {
+                if (server[0] == "cloudflare-nginx")
+                    stringResult.Content = BrowserUtil.DecodeCloudFlareProtectedEmailFromHTML(stringResult.Content);
+            }
+            return stringResult;
+        }
+
+#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
+        virtual protected async Task<WebClientByteResult> Run(WebRequest webRequest) { throw new NotImplementedException(); }
+#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
+
         abstract public void Init();
     }
 }
diff --git a/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs b/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs
index c86f55700dda5584adf7b9f963d7ec5ce0019e0c..ceb20043d02ac8bbf5facdf61d67926bd75198b2 100644
--- a/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs
+++ b/src/Jackett/Utils/Clients/UnixLibCurlWebClient.cs
@@ -11,34 +11,34 @@ using System.Net;
 using System.Net.Http;
 using System.Text;
 using System.Threading.Tasks;
-using CloudFlareUtilities;
-
+using CloudFlareUtilities;
+
 namespace Jackett.Utils.Clients
 {
     public class UnixLibCurlWebClient : IWebClient
     {
-        public UnixLibCurlWebClient(IProcessService p, Logger l, IConfigurationService c)
+        public UnixLibCurlWebClient(IProcessService p, Logger l, IConfigurationService c)
             : base(p: p,
                    l: l,
-                   c: c)
+                   c: c)
         {
         }
 
-        private string CloudFlareChallengeSolverSolve(string challengePageContent, Uri uri)
-        {
-            var solution = ChallengeSolver.Solve(challengePageContent, uri.Host);
-            string clearanceUri = uri.Scheme + Uri.SchemeDelimiter + uri.Host + ":" + uri.Port + solution.ClearanceQuery;
-            return clearanceUri;
-        }
-
+        private string CloudFlareChallengeSolverSolve(string challengePageContent, Uri uri)
+        {
+            var solution = ChallengeSolver.Solve(challengePageContent, uri.Host);
+            string clearanceUri = uri.Scheme + Uri.SchemeDelimiter + uri.Host + ":" + uri.Port + solution.ClearanceQuery;
+            return clearanceUri;
+        }
+
         override public void Init()
         {
             try
             {
                 Engine.Logger.Info("LibCurl init " + Curl.GlobalInit(CurlInitFlag.All).ToString());
-                CurlHelper.OnErrorMessage += (msg) =>
-                {
-                    Engine.Logger.Error(msg);
+                CurlHelper.OnErrorMessage += (msg) =>
+                {
+                    Engine.Logger.Error(msg);
                 };
             }
             catch (Exception e)
@@ -61,38 +61,38 @@ namespace Jackett.Utils.Clients
 
         // Wrapper for Run which takes care of CloudFlare challenges, calls RunCurl
         override protected async Task<WebClientByteResult> Run(WebRequest request)
-        {
-            WebClientByteResult result = await RunCurl(request);
-
-            // check if we've received a CloudFlare challenge
-            string[] server;
-            if (result.Status == HttpStatusCode.ServiceUnavailable && result.Headers.TryGetValue("server", out server) && server[0] == "cloudflare-nginx")
-            {
-                logger.Info("UnixLibCurlWebClient: Received a new CloudFlare challenge");
-
-                // solve the challenge
-                string pageContent = Encoding.UTF8.GetString(result.Content);
-                Uri uri = new Uri(request.Url);
-                string clearanceUri = CloudFlareChallengeSolverSolve(pageContent, uri);
-                logger.Info(string.Format("UnixLibCurlWebClient: CloudFlare clearanceUri: {0}", clearanceUri));
-
-                // wait...
-                await Task.Delay(5000);
-
-                // request clearanceUri to get cf_clearance cookie
-                var response = await CurlHelper.GetAsync(clearanceUri, request.Cookies, request.Referer);
-                logger.Info(string.Format("UnixLibCurlWebClient: received CloudFlare clearance cookie: {0}", response.Cookies));
-
-                // add new cf_clearance cookies to the original request
-                request.Cookies = response.Cookies + request.Cookies;
-
-                // re-run the original request with updated cf_clearance cookie
-                result = await RunCurl(request);
-
-                // add cf_clearance cookie to the final result so we update the config for the next request
-                result.Cookies = response.Cookies + " " + result.Cookies;
-            }
-            return result;
+        {
+            WebClientByteResult result = await RunCurl(request);
+
+            // check if we've received a CloudFlare challenge
+            string[] server;
+            if (result.Status == HttpStatusCode.ServiceUnavailable && result.Headers.TryGetValue("server", out server) && server[0] == "cloudflare-nginx")
+            {
+                logger.Info("UnixLibCurlWebClient: Received a new CloudFlare challenge");
+
+                // solve the challenge
+                string pageContent = Encoding.UTF8.GetString(result.Content);
+                Uri uri = new Uri(request.Url);
+                string clearanceUri = CloudFlareChallengeSolverSolve(pageContent, uri);
+                logger.Info(string.Format("UnixLibCurlWebClient: CloudFlare clearanceUri: {0}", clearanceUri));
+
+                // wait...
+                await Task.Delay(5000);
+
+                // request clearanceUri to get cf_clearance cookie
+                var response = await CurlHelper.GetAsync(clearanceUri, request.Cookies, request.Referer);
+                logger.Info(string.Format("UnixLibCurlWebClient: received CloudFlare clearance cookie: {0}", response.Cookies));
+
+                // add new cf_clearance cookies to the original request
+                request.Cookies = response.Cookies + request.Cookies;
+
+                // re-run the original request with updated cf_clearance cookie
+                result = await RunCurl(request);
+
+                // add cf_clearance cookie to the final result so we update the config for the next request
+                result.Cookies = response.Cookies + " " + result.Cookies;
+            }
+            return result;
         }
 
         protected async Task<WebClientByteResult> RunCurl(WebRequest request)
@@ -113,7 +113,7 @@ namespace Jackett.Utils.Clients
                     logger.Debug("UnixLibCurlWebClient: Posting " + StringUtil.PostDataFromDict(request.PostData));
                 }
 
-                response = await CurlHelper.PostAsync(request.Url, request.PostData, request.Cookies, request.Referer, request.Headers, request.RawBody);
+                response = await CurlHelper.PostAsync(request.Url, request.PostData, request.Cookies, request.Referer, request.Headers, request.RawBody);
             }
 
             var result = new WebClientByteResult()
@@ -127,34 +127,34 @@ namespace Jackett.Utils.Clients
             {
                 foreach (var header in response.HeaderList)
                 {
-                    var key = header[0].ToLowerInvariant();
-                    
-                    result.Headers[key] = new string[] { header[1] }; // doesn't support multiple identical headers?
-
+                    var key = header[0].ToLowerInvariant();
+                    
+                    result.Headers[key] = new string[] { header[1] }; // doesn't support multiple identical headers?
+
                     switch (key)
                     {
                         case "location":
                             result.RedirectingTo = header[1];
                             break;
                         case "refresh":
-                            if (response.Status == System.Net.HttpStatusCode.ServiceUnavailable)
+                            if (response.Status == System.Net.HttpStatusCode.ServiceUnavailable)
                             {
                                 //"Refresh: 8;URL=/cdn-cgi/l/chk_jschl?pass=1451000679.092-1vJFUJLb9R"
                                 var redirval = "";
                                 var value = header[1];
-                                var start = value.IndexOf("=");
-                                var end = value.IndexOf(";");
-                                var len = value.Length;
-                                if (start > -1)
-                                {
-                                    redirval = value.Substring(start + 1);
-                                    result.RedirectingTo = redirval;
-                                    // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
-                                    // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
-                                    // it shoudln't include service unavailable..only if we have this redirect header.
-                                    result.Status = System.Net.HttpStatusCode.Redirect;
-                                    var redirtime = Int32.Parse(value.Substring(0, end));
-                                    System.Threading.Thread.Sleep(redirtime * 1000);
+                                var start = value.IndexOf("=");
+                                var end = value.IndexOf(";");
+                                var len = value.Length;
+                                if (start > -1)
+                                {
+                                    redirval = value.Substring(start + 1);
+                                    result.RedirectingTo = redirval;
+                                    // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
+                                    // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
+                                    // it shoudln't include service unavailable..only if we have this redirect header.
+                                    result.Status = System.Net.HttpStatusCode.Redirect;
+                                    var redirtime = Int32.Parse(value.Substring(0, end));
+                                    System.Threading.Thread.Sleep(redirtime * 1000);
                                 }
                             }
                             break;
diff --git a/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs b/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs
index 81192b3c7a482a97ef00fa1cdaf00d7ae9accc0b..c4ef8855213a569b0b7fb7f9e39ce4cb9e0a8dad 100644
--- a/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs
+++ b/src/Jackett/Utils/Clients/UnixSafeCurlWebClient.cs
@@ -19,7 +19,7 @@ namespace Jackett.Utils.Clients
         public UnixSafeCurlWebClient(IProcessService p, Logger l, IConfigurationService c)
             : base(p: p,
                    l: l,
-                   c: c)
+                   c: c)
         {
         }
 
@@ -30,10 +30,10 @@ namespace Jackett.Utils.Clients
         override protected async Task<WebClientByteResult> Run(WebRequest request)
         {
             var args = new StringBuilder();
-            if (Startup.ProxyConnection != null)
-            {
-                args.AppendFormat("-x " + Startup.ProxyConnection + " ");
-            }
+            if (Startup.ProxyConnection != null)
+            {
+                args.AppendFormat("-x " + Startup.ProxyConnection + " ");
+            }
             
             args.AppendFormat("--url \"{0}\" ", request.Url);
            
@@ -71,9 +71,9 @@ namespace Jackett.Utils.Clients
                 // https://git.fedorahosted.org/cgit/mod_nss.git/plain/docs/mod_nss.html
                 args.Append("--cipher " + SSLFix.CipherList);
             }
-            if (Startup.IgnoreSslErrors == true)
-            {
-                args.Append("-k ");
+            if (Startup.IgnoreSslErrors == true)
+            {
+                args.Append("-k ");
             }
             args.Append("-H \"Accept-Language: en-US,en\" ");
             args.Append("-H \"Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8\" ");
@@ -91,16 +91,16 @@ namespace Jackett.Utils.Clients
             if (headSplit < 0)
                 throw new Exception("Invalid response");
             var headers = stdout.Substring(0, headSplit);
-            if (Startup.ProxyConnection != null)
-            {
-                // the proxy provided headers too so we need to split headers again
-                var headSplit1 = stdout.IndexOf("\r\n\r\n",headSplit + 4);
-                if (headSplit1 > 0)
-                {
-                    headers = stdout.Substring(headSplit + 4,headSplit1 - (headSplit + 4));
-                    headSplit = headSplit1;
-                }
-            }
+            if (Startup.ProxyConnection != null)
+            {
+                // the proxy provided headers too so we need to split headers again
+                var headSplit1 = stdout.IndexOf("\r\n\r\n",headSplit + 4);
+                if (headSplit1 > 0)
+                {
+                    headers = stdout.Substring(headSplit + 4,headSplit1 - (headSplit + 4));
+                    headSplit = headSplit1;
+                }
+            }
             var headerCount = 0;
             var cookieBuilder = new StringBuilder();
             var cookies = new List<Tuple<string, string>>();
@@ -134,19 +134,19 @@ namespace Jackett.Utils.Clients
                             case "refresh":
                                 //"Refresh: 8;URL=/cdn-cgi/l/chk_jschl?pass=1451000679.092-1vJFUJLb9R"
                                 var redirval = "";
-                                var start = value.IndexOf("=");
-                                var end = value.IndexOf(";");
-                                var len = value.Length;
-                                if (start > -1)
-                                {
-                                    redirval = value.Substring(start + 1);
-                                    result.RedirectingTo = redirval;
-                                    // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
-                                    // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
-                                    // it shoudln't include service unavailable..only if we have this redirect header.
-                                    result.Status = System.Net.HttpStatusCode.Redirect;
-                                    var redirtime = Int32.Parse(value.Substring(0, end));
-                                    System.Threading.Thread.Sleep(redirtime * 1000);
+                                var start = value.IndexOf("=");
+                                var end = value.IndexOf(";");
+                                var len = value.Length;
+                                if (start > -1)
+                                {
+                                    redirval = value.Substring(start + 1);
+                                    result.RedirectingTo = redirval;
+                                    // normally we don't want a serviceunavailable (503) to be a redirect, but that's the nature
+                                    // of this cloudflare approach..don't want to alter BaseWebResult.IsRedirect because normally
+                                    // it shoudln't include service unavailable..only if we have this redirect header.
+                                    result.Status = System.Net.HttpStatusCode.Redirect;
+                                    var redirtime = Int32.Parse(value.Substring(0, end));
+                                    System.Threading.Thread.Sleep(redirtime * 1000);
                                 }
                                 break;
                         }
diff --git a/src/Jackett/Utils/Clients/WebRequest.cs b/src/Jackett/Utils/Clients/WebRequest.cs
index 5ef451e2dcb391071dc19a2884bbe0d887c496bf..252579406985e3ce72a31b826fbd81600acfbdbe 100644
--- a/src/Jackett/Utils/Clients/WebRequest.cs
+++ b/src/Jackett/Utils/Clients/WebRequest.cs
@@ -1,103 +1,103 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Net.Http;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils.Clients
-{
-    public class WebRequest
-    {
-        public WebRequest()
-        {
-            PostData = new List<KeyValuePair<string, string>>();
-            Type = RequestType.GET;
-            Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
-            EmulateBrowser = true;
-            Encoding Encoding;
-        }
-
-        public WebRequest(string url)
-        {
-            PostData = new List<KeyValuePair<string, string>>();
-            Type = RequestType.GET;
-            Url = url;
-            Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
-            EmulateBrowser = true;
-            Encoding Encoding;
-        }
-
-        public string Url { get; set; }
-        public IEnumerable<KeyValuePair<string, string>> PostData { get; set; }
-        public string Cookies { get; set; }
-        public string Referer { get; set; }
-        public RequestType Type { get; set; }
-        public string RawBody { get; set; }
-        public bool EmulateBrowser { get; set; }
-        public Encoding Encoding { get; set; }
-
-        /// <summary>
-        /// Warning this is only implemented on HTTPWebClient currently!
-        /// </summary>
-        public Dictionary<string, string> Headers { get; set; }
-
-        public override bool Equals(System.Object obj)
-        {
-            if (obj is WebRequest)
-            {
-                var other = obj as WebRequest;
-                var postDataSame = PostData == null && other.PostData == null;
-                if (!postDataSame)
-                {
-                    if (!(PostData == null || other.PostData == null))
-                    {
-                        var ok = PostData.Count() == other.PostData.Count();
-                        foreach (var i in PostData)
-                        {
-                            if (!other.PostData.Any(item => item.Key == i.Key))
-                            {
-                                ok = false;
-                                break;
-                            }
-
-                            if (PostData.FirstOrDefault(item => item.Key == i.Key).Value != other.PostData.FirstOrDefault(item => item.Key == i.Key).Value)
-                            {
-                                ok = false;
-                                break;
-                            }
-                        }
-
-                        if (ok)
-                        {
-                            postDataSame = true;
-                        }
-                    }
-                }
-
-                return other.Url == Url &&
-                       other.Referer == Referer &&
-                       other.Cookies == Cookies &&
-                       other.Type == Type &&
-                       other.Encoding == Encoding &&
-                       postDataSame;
-
-            }
-            else
-            {
-                return false;
-            }
-        }
-
-        public override int GetHashCode()
-        {
-            return base.GetHashCode();
-        }
-    }
-
-    public enum RequestType
-    {
-        GET,
-        POST
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils.Clients
+{
+    public class WebRequest
+    {
+        public WebRequest()
+        {
+            PostData = new List<KeyValuePair<string, string>>();
+            Type = RequestType.GET;
+            Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+            EmulateBrowser = true;
+            Encoding Encoding;
+        }
+
+        public WebRequest(string url)
+        {
+            PostData = new List<KeyValuePair<string, string>>();
+            Type = RequestType.GET;
+            Url = url;
+            Headers = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
+            EmulateBrowser = true;
+            Encoding Encoding;
+        }
+
+        public string Url { get; set; }
+        public IEnumerable<KeyValuePair<string, string>> PostData { get; set; }
+        public string Cookies { get; set; }
+        public string Referer { get; set; }
+        public RequestType Type { get; set; }
+        public string RawBody { get; set; }
+        public bool EmulateBrowser { get; set; }
+        public Encoding Encoding { get; set; }
+
+        /// <summary>
+        /// Warning this is only implemented on HTTPWebClient currently!
+        /// </summary>
+        public Dictionary<string, string> Headers { get; set; }
+
+        public override bool Equals(System.Object obj)
+        {
+            if (obj is WebRequest)
+            {
+                var other = obj as WebRequest;
+                var postDataSame = PostData == null && other.PostData == null;
+                if (!postDataSame)
+                {
+                    if (!(PostData == null || other.PostData == null))
+                    {
+                        var ok = PostData.Count() == other.PostData.Count();
+                        foreach (var i in PostData)
+                        {
+                            if (!other.PostData.Any(item => item.Key == i.Key))
+                            {
+                                ok = false;
+                                break;
+                            }
+
+                            if (PostData.FirstOrDefault(item => item.Key == i.Key).Value != other.PostData.FirstOrDefault(item => item.Key == i.Key).Value)
+                            {
+                                ok = false;
+                                break;
+                            }
+                        }
+
+                        if (ok)
+                        {
+                            postDataSame = true;
+                        }
+                    }
+                }
+
+                return other.Url == Url &&
+                       other.Referer == Referer &&
+                       other.Cookies == Cookies &&
+                       other.Type == Type &&
+                       other.Encoding == Encoding &&
+                       postDataSame;
+
+            }
+            else
+            {
+                return false;
+            }
+        }
+
+        public override int GetHashCode()
+        {
+            return base.GetHashCode();
+        }
+    }
+
+    public enum RequestType
+    {
+        GET,
+        POST
+    }
+}
diff --git a/src/Jackett/Utils/DateTimeUtil.cs b/src/Jackett/Utils/DateTimeUtil.cs
index f0a0d6dda158c5197b51c33c8bca9ebb85ecd1c6..46d629c25b41dba3b41f7c14658351b6f42945be 100644
--- a/src/Jackett/Utils/DateTimeUtil.cs
+++ b/src/Jackett/Utils/DateTimeUtil.cs
@@ -1,10 +1,10 @@
-using Cliver;
+using Cliver;
 using System;
 using System.Collections.Generic;
-using System.Globalization;
+using System.Globalization;
 using System.Linq;
 using System.Text;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 
 namespace Jackett.Utils
@@ -15,7 +15,7 @@ namespace Jackett.Utils
 
         public static DateTime UnixTimestampToDateTime(long unixTime)
         {
-            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
+            DateTime dt = new DateTime(1970, 1, 1, 0, 0, 0, 0, System.DateTimeKind.Utc);
             dt = dt.AddSeconds(unixTime).ToLocalTime();
             return dt;
         }
@@ -49,17 +49,17 @@ namespace Jackett.Utils
             str = str.Replace("and", "");
 
             TimeSpan timeAgo = TimeSpan.Zero;
-            Regex TimeagoRegex = new Regex(@"\s*?([\d\.]+)\s*?([^\d\s\.]+)\s*?");
-            var TimeagoMatches = TimeagoRegex.Match(str);
-
-            while (TimeagoMatches.Success)
-            {
-                string expanded = string.Empty;
-
-                var val = ParseUtil.CoerceFloat(TimeagoMatches.Groups[1].Value);
+            Regex TimeagoRegex = new Regex(@"\s*?([\d\.]+)\s*?([^\d\s\.]+)\s*?");
+            var TimeagoMatches = TimeagoRegex.Match(str);
+
+            while (TimeagoMatches.Success)
+            {
+                string expanded = string.Empty;
+
+                var val = ParseUtil.CoerceFloat(TimeagoMatches.Groups[1].Value);
                 var unit = TimeagoMatches.Groups[2].Value;
-                TimeagoMatches = TimeagoMatches.NextMatch();
-
+                TimeagoMatches = TimeagoMatches.NextMatch();
+
                 if (unit.Contains("sec") || unit == "s")
                     timeAgo += TimeSpan.FromSeconds(val);
                 else if (unit.Contains("min") || unit == "m")
@@ -75,56 +75,56 @@ namespace Jackett.Utils
                 else if (unit.Contains("year") || unit == "y")
                     timeAgo += TimeSpan.FromDays(val * 365);
                 else
-                {
-                    throw new Exception("TimeAgo parsing failed, unknown unit: "+unit);
+                {
+                    throw new Exception("TimeAgo parsing failed, unknown unit: "+unit);
                 }
             }
 
             return DateTime.SpecifyKind(DateTime.Now - timeAgo, DateTimeKind.Local);
         }
 
-        public static TimeSpan ParseTimeSpan(string time)
-        {
-            if (string.IsNullOrWhiteSpace(time))
-                return TimeSpan.Zero;
-
-            TimeSpan offset = TimeSpan.Zero;
-            if (time.EndsWith("AM"))
-            {
-                time = time.Substring(0, time.Length - 2);
-                if(time.StartsWith("12")) // 12:15 AM becomes 00:15
-                    time = "00" + time.Substring(2);
-            }
-            else if (time.EndsWith("PM"))
-            {
-                time = time.Substring(0, time.Length - 2);
-                offset = TimeSpan.FromHours(12);
-            }
-
-            var ts = TimeSpan.Parse(time);
-            ts += offset;
-            return ts;
+        public static TimeSpan ParseTimeSpan(string time)
+        {
+            if (string.IsNullOrWhiteSpace(time))
+                return TimeSpan.Zero;
+
+            TimeSpan offset = TimeSpan.Zero;
+            if (time.EndsWith("AM"))
+            {
+                time = time.Substring(0, time.Length - 2);
+                if(time.StartsWith("12")) // 12:15 AM becomes 00:15
+                    time = "00" + time.Substring(2);
+            }
+            else if (time.EndsWith("PM"))
+            {
+                time = time.Substring(0, time.Length - 2);
+                offset = TimeSpan.FromHours(12);
+            }
+
+            var ts = TimeSpan.Parse(time);
+            ts += offset;
+            return ts;
         }
 
         // Uses the DateTimeRoutines library to parse the date
         // http://www.codeproject.com/Articles/33298/C-Date-Time-Parser
         public static DateTime FromFuzzyTime(string str, string format = null)
-        {
-            DateTimeRoutines.DateTimeFormat dt_format = DateTimeRoutines.DateTimeFormat.USA_DATE;
-            if (format == "UK")
-            {
-                dt_format = DateTimeRoutines.DateTimeFormat.UK_DATE;
-            }
-
-            DateTimeRoutines.ParsedDateTime dt;
-            if (DateTimeRoutines.TryParseDateOrTime(str, dt_format, out dt))
-            {
-                return dt.DateTime;
-            }
-            throw new Exception("FromFuzzyTime parsing failed");
-        }
-
-        public static Regex timeAgoRegexp = new Regex(@"(?i)\bago", RegexOptions.Compiled);
+        {
+            DateTimeRoutines.DateTimeFormat dt_format = DateTimeRoutines.DateTimeFormat.USA_DATE;
+            if (format == "UK")
+            {
+                dt_format = DateTimeRoutines.DateTimeFormat.UK_DATE;
+            }
+
+            DateTimeRoutines.ParsedDateTime dt;
+            if (DateTimeRoutines.TryParseDateOrTime(str, dt_format, out dt))
+            {
+                return dt.DateTime;
+            }
+            throw new Exception("FromFuzzyTime parsing failed");
+        }
+
+        public static Regex timeAgoRegexp = new Regex(@"(?i)\bago", RegexOptions.Compiled);
         public static Regex todayRegexp = new Regex(@"(?i)\btoday([\s,]*|$)", RegexOptions.Compiled);
         public static Regex tomorrowRegexp = new Regex(@"(?i)\btomorrow([\s,]*|$)", RegexOptions.Compiled);
         public static Regex yesterdayRegexp = new Regex(@"(?i)\byesterday([\s,]*|$)", RegexOptions.Compiled);
@@ -132,168 +132,168 @@ namespace Jackett.Utils
         public static Regex missingYearRegexp2 = new Regex(@"^(\d{1,2}\s+\w{3})\s+(\d{1,2}\:\d{1,2}.*)$", RegexOptions.Compiled); // 1 Jan 10:30
 
         public static DateTime FromUnknown(string str, string format = null)
-        {
-            try {
-                str = ParseUtil.NormalizeSpace(str);
-                Match match;
-
-                if(str.ToLower().Contains("now"))
-                {
-                    return DateTime.UtcNow;
-                }
-
-                // ... ago
-                match = timeAgoRegexp.Match(str);
-                if (match.Success)
-                {
-                    var timeago = str;
-                    return FromTimeAgo(timeago);
-                }
-
-                // Today ...
-                match = todayRegexp.Match(str);
-                if (match.Success)
-                {
-                    var time = str.Replace(match.Groups[0].Value, "");
-                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
-                    dt += ParseTimeSpan(time);
-                    return dt;
-                }
-
-                // Yesterday ...
-                match = yesterdayRegexp.Match(str);
-                if (match.Success)
-                {
-                    var time = str.Replace(match.Groups[0].Value, "");
-                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
-                    dt += ParseTimeSpan(time);
-                    dt -= TimeSpan.FromDays(1);
-                    return dt;
-                }
-
-                // Tomorrow ...
-                match = tomorrowRegexp.Match(str);
-                if (match.Success)
-                {
-                    var time = str.Replace(match.Groups[0].Value, "");
-                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
-                    dt += ParseTimeSpan(time);
-                    dt += TimeSpan.FromDays(1);
-                    return dt;
-                }
-
-                try
-                {
-                    // try parsing the str as an unix timestamp
-                    var unixTimeStamp = long.Parse(str);
-                    return UnixTimestampToDateTime(unixTimeStamp);
-                }
-                catch (FormatException)
-                {
-                    // it wasn't a timestamp, continue....
-                }
-
-                // add missing year
-                match = missingYearRegexp.Match(str);
-                if (match.Success)
-                {
-                    var date = match.Groups[1].Value;
-                    string newDate = DateTime.Now.Year.ToString()+ "-"+date;
-                    str = str.Replace(date, newDate);
-                }
-
-                // add missing year 2
-                match = missingYearRegexp2.Match(str);
-                if (match.Success)
-                {
-                    var date = match.Groups[1].Value;
-                    var time = match.Groups[2].Value;
-                    str = date + " " + DateTime.Now.Year.ToString() + " " + time;
-                }
-
-                return FromFuzzyTime(str, format);
-            }
-            catch (Exception ex)
-            {
-                throw new Exception(string.Format("DateTime parsing failed for \"{0}\": {1}", str, ex.ToString()));
-            }
-        }
-
+        {
+            try {
+                str = ParseUtil.NormalizeSpace(str);
+                Match match;
+
+                if(str.ToLower().Contains("now"))
+                {
+                    return DateTime.UtcNow;
+                }
+
+                // ... ago
+                match = timeAgoRegexp.Match(str);
+                if (match.Success)
+                {
+                    var timeago = str;
+                    return FromTimeAgo(timeago);
+                }
+
+                // Today ...
+                match = todayRegexp.Match(str);
+                if (match.Success)
+                {
+                    var time = str.Replace(match.Groups[0].Value, "");
+                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
+                    dt += ParseTimeSpan(time);
+                    return dt;
+                }
+
+                // Yesterday ...
+                match = yesterdayRegexp.Match(str);
+                if (match.Success)
+                {
+                    var time = str.Replace(match.Groups[0].Value, "");
+                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
+                    dt += ParseTimeSpan(time);
+                    dt -= TimeSpan.FromDays(1);
+                    return dt;
+                }
+
+                // Tomorrow ...
+                match = tomorrowRegexp.Match(str);
+                if (match.Success)
+                {
+                    var time = str.Replace(match.Groups[0].Value, "");
+                    DateTime dt = DateTime.SpecifyKind(DateTime.UtcNow.Date, DateTimeKind.Unspecified);
+                    dt += ParseTimeSpan(time);
+                    dt += TimeSpan.FromDays(1);
+                    return dt;
+                }
+
+                try
+                {
+                    // try parsing the str as an unix timestamp
+                    var unixTimeStamp = long.Parse(str);
+                    return UnixTimestampToDateTime(unixTimeStamp);
+                }
+                catch (FormatException)
+                {
+                    // it wasn't a timestamp, continue....
+                }
+
+                // add missing year
+                match = missingYearRegexp.Match(str);
+                if (match.Success)
+                {
+                    var date = match.Groups[1].Value;
+                    string newDate = DateTime.Now.Year.ToString()+ "-"+date;
+                    str = str.Replace(date, newDate);
+                }
+
+                // add missing year 2
+                match = missingYearRegexp2.Match(str);
+                if (match.Success)
+                {
+                    var date = match.Groups[1].Value;
+                    var time = match.Groups[2].Value;
+                    str = date + " " + DateTime.Now.Year.ToString() + " " + time;
+                }
+
+                return FromFuzzyTime(str, format);
+            }
+            catch (Exception ex)
+            {
+                throw new Exception(string.Format("DateTime parsing failed for \"{0}\": {1}", str, ex.ToString()));
+            }
+        }
+
         // converts a date/time string to a DateTime object using a GoLang layout
-        public static DateTime ParseDateTimeGoLang(string date, string layout)
-        {
-            date = ParseUtil.NormalizeSpace(date);
-            var pattern = layout;
-
-            // year
-            pattern = pattern.Replace("2006", "yyyy");
-            pattern = pattern.Replace("06", "yy");
-
-            // month
-            pattern = pattern.Replace("January", "MMMM");
-            pattern = pattern.Replace("Jan", "MMM");
-            pattern = pattern.Replace("01", "MM");
-
-            // day
-            pattern = pattern.Replace("Monday", "dddd");
-            pattern = pattern.Replace("Mon", "ddd");
-            pattern = pattern.Replace("02", "dd");
-            //pattern = pattern.Replace("_2", ""); // space padding not supported nativly by C#?
-            pattern = pattern.Replace("2", "d");
-
-            // hours/minutes/seconds
-            pattern = pattern.Replace("05", "ss");
-
-            pattern = pattern.Replace("15", "HH");
-            pattern = pattern.Replace("03", "hh");
-            pattern = pattern.Replace("3", "h");
-
-            pattern = pattern.Replace("04", "mm");
-            pattern = pattern.Replace("4", "m");
-
-            pattern = pattern.Replace("5", "s");
-
-            // month again
-            pattern = pattern.Replace("1", "M");
-
-            // fractional seconds
-            pattern = pattern.Replace(".0000", "ffff");
-            pattern = pattern.Replace(".000", "fff");
-            pattern = pattern.Replace(".00", "ff");
-            pattern = pattern.Replace(".0", "f");
-
-            pattern = pattern.Replace(".9999", "FFFF");
-            pattern = pattern.Replace(".999", "FFF");
-            pattern = pattern.Replace(".99", "FF");
-            pattern = pattern.Replace(".9", "F");
-
-            // AM/PM
-            pattern = pattern.Replace("PM", "tt");
-            pattern = pattern.Replace("pm", "tt"); // not sure if this works
-
-            // timezones
-            // these might need further tuning
-            //pattern = pattern.Replace("MST", "");
-            //pattern = pattern.Replace("Z07:00:00", "");
-            pattern = pattern.Replace("Z07:00", "'Z'zzz");
-            pattern = pattern.Replace("Z07", "'Z'zz");
-            //pattern = pattern.Replace("Z070000", "");
-            //pattern = pattern.Replace("Z0700", "");
-            pattern = pattern.Replace("Z07:00", "'Z'zzz");
-            pattern = pattern.Replace("Z07", "'Z'zz");
-            //pattern = pattern.Replace("-07:00:00", "");
-            pattern = pattern.Replace("-07:00", "zzz");
-            //pattern = pattern.Replace("-0700", "zz");
-            pattern = pattern.Replace("-07", "zz");
-
-            try
-            {
-                return DateTime.ParseExact(date, pattern, CultureInfo.InvariantCulture);
-            }
-            catch (FormatException ex)
-            {
-                throw new FormatException(string.Format("Error while parsing DateTime \"{0}\", using layout \"{1}\" ({2}): {3}", date, layout, pattern, ex.Message));
-            }
-        }
+        public static DateTime ParseDateTimeGoLang(string date, string layout)
+        {
+            date = ParseUtil.NormalizeSpace(date);
+            var pattern = layout;
+
+            // year
+            pattern = pattern.Replace("2006", "yyyy");
+            pattern = pattern.Replace("06", "yy");
+
+            // month
+            pattern = pattern.Replace("January", "MMMM");
+            pattern = pattern.Replace("Jan", "MMM");
+            pattern = pattern.Replace("01", "MM");
+
+            // day
+            pattern = pattern.Replace("Monday", "dddd");
+            pattern = pattern.Replace("Mon", "ddd");
+            pattern = pattern.Replace("02", "dd");
+            //pattern = pattern.Replace("_2", ""); // space padding not supported nativly by C#?
+            pattern = pattern.Replace("2", "d");
+
+            // hours/minutes/seconds
+            pattern = pattern.Replace("05", "ss");
+
+            pattern = pattern.Replace("15", "HH");
+            pattern = pattern.Replace("03", "hh");
+            pattern = pattern.Replace("3", "h");
+
+            pattern = pattern.Replace("04", "mm");
+            pattern = pattern.Replace("4", "m");
+
+            pattern = pattern.Replace("5", "s");
+
+            // month again
+            pattern = pattern.Replace("1", "M");
+
+            // fractional seconds
+            pattern = pattern.Replace(".0000", "ffff");
+            pattern = pattern.Replace(".000", "fff");
+            pattern = pattern.Replace(".00", "ff");
+            pattern = pattern.Replace(".0", "f");
+
+            pattern = pattern.Replace(".9999", "FFFF");
+            pattern = pattern.Replace(".999", "FFF");
+            pattern = pattern.Replace(".99", "FF");
+            pattern = pattern.Replace(".9", "F");
+
+            // AM/PM
+            pattern = pattern.Replace("PM", "tt");
+            pattern = pattern.Replace("pm", "tt"); // not sure if this works
+
+            // timezones
+            // these might need further tuning
+            //pattern = pattern.Replace("MST", "");
+            //pattern = pattern.Replace("Z07:00:00", "");
+            pattern = pattern.Replace("Z07:00", "'Z'zzz");
+            pattern = pattern.Replace("Z07", "'Z'zz");
+            //pattern = pattern.Replace("Z070000", "");
+            //pattern = pattern.Replace("Z0700", "");
+            pattern = pattern.Replace("Z07:00", "'Z'zzz");
+            pattern = pattern.Replace("Z07", "'Z'zz");
+            //pattern = pattern.Replace("-07:00:00", "");
+            pattern = pattern.Replace("-07:00", "zzz");
+            //pattern = pattern.Replace("-0700", "zz");
+            pattern = pattern.Replace("-07", "zz");
+
+            try
+            {
+                return DateTime.ParseExact(date, pattern, CultureInfo.InvariantCulture);
+            }
+            catch (FormatException ex)
+            {
+                throw new FormatException(string.Format("Error while parsing DateTime \"{0}\", using layout \"{1}\" ({2}): {3}", date, layout, pattern, ex.Message));
+            }
+        }
     }
 }
diff --git a/src/Jackett/Utils/JsonContent.cs b/src/Jackett/Utils/JsonContent.cs
index b49245b47eaac51d1934e1290b3e36875e9ac46d..83bfe1873cd58da26af9c7870eef7c7f9ff0bb93 100644
--- a/src/Jackett/Utils/JsonContent.cs
+++ b/src/Jackett/Utils/JsonContent.cs
@@ -12,17 +12,17 @@ using System.Threading.Tasks;
 
 namespace Jackett.Utils
 {
-    public class JsonContent : StringContent
-    {
-        public JsonContent(object value)
-            : this(value, Encoding.UTF8)
-        {
-            Headers.ContentType.CharSet = "utf-8";
-        }
-
-        public JsonContent(object value, Encoding encoding)
-            : base(JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), encoding, "application/json")
-        {
-        }
+    public class JsonContent : StringContent
+    {
+        public JsonContent(object value)
+            : this(value, Encoding.UTF8)
+        {
+            Headers.ContentType.CharSet = "utf-8";
+        }
+
+        public JsonContent(object value, Encoding encoding)
+            : base(JsonConvert.SerializeObject(value, Formatting.Indented, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), encoding, "application/json")
+        {
+        }
     }
 }
diff --git a/src/Jackett/Utils/ParseUtil.cs b/src/Jackett/Utils/ParseUtil.cs
index 24f68d996b62a26bd9c09772227c5c7f3d05c932..af2774df73c8ae7f780350469d0097c65581f9f5 100644
--- a/src/Jackett/Utils/ParseUtil.cs
+++ b/src/Jackett/Utils/ParseUtil.cs
@@ -1,120 +1,120 @@
-using System.Globalization;
-using System.Text.RegularExpressions;
-using System.Web;
-
-namespace Jackett.Utils
-{
-    public static class ParseUtil
-    {
-        private static readonly Regex InvalidXmlChars =
-            new Regex(
-                @"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]",
-                RegexOptions.Compiled);
-        private static readonly Regex ImdbId = new Regex(@"^(?:tt)?(\d{1,7})$", RegexOptions.Compiled);
-
-        public static string NormalizeSpace(string s)
-        {
-            return s.Trim();
-        }
-
-        public static string NormalizeMultiSpaces(string s)
-        {
-            return new Regex(@"\s+").Replace(NormalizeSpace(s), " "); ;
-        }
-
-        public static string NormalizeNumber(string s)
-        {
-            var normalized = NormalizeSpace(s);
-            normalized = normalized.Replace("-", "0");
-            normalized = normalized.Replace(",", "");
-            return normalized;
-        }
-
-        public static string RemoveInvalidXmlChars(string text)
-        {
-            return string.IsNullOrEmpty(text) ? "" : InvalidXmlChars.Replace(text, "");
-        }
-
-        public static double CoerceDouble(string str)
-        {
-            return double.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
-        }
-
-        public static float CoerceFloat(string str)
-        {
-            return float.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
-        }
-
-        public static int CoerceInt(string str)
-        {
-            return int.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
-        }
-
-        public static long CoerceLong(string str)
-        {
-            return long.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
-        }
-
-        public static bool TryCoerceDouble(string str, out double result)
-        {
-            return double.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
-        }
-
-        public static bool TryCoerceFloat(string str, out float result)
-        {
-            return float.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
-        }
-
-        public static bool TryCoerceInt(string str, out int result)
-        {
-            return int.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
-        }
-
-        public static bool TryCoerceLong(string str, out long result)
-        {
-            return long.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
-        }
-
-        public static string GetArgumentFromQueryString(string url, string argument)
-        {
-            if (url == null || argument == null)
-                return null;
-            var qsStr = url.Split(new char[] { '?' }, 2)[1];
-            qsStr = qsStr.Split(new char[] { '#' }, 2)[0];
-            var qs = HttpUtility.ParseQueryString(qsStr);
-            return qs.Get(argument);
-        }
-
-        public static long? GetLongFromString(string str)
-        {
-            if (str == null)
-                return null;
-            Regex IdRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
-            var IdMatch = IdRegEx.Match(str);
-            if (!IdMatch.Success)
-                return null;
-            var Id = IdMatch.Groups[1].Value;
-            return CoerceLong(Id);
-        }
-
-        public static int? GetImdbID(string imdbstr)
-        {
-            if (imdbstr == null)
-                return null;
-            var match = ImdbId.Match(imdbstr);
-            if (!match.Success)
-                return null;
-
-            return int.Parse(match.Groups[1].Value, NumberStyles.Any, CultureInfo.InvariantCulture);
-        }
-
-        public static string GetFullImdbID(string imdbstr)
-        {
-            var imdbid = GetImdbID(imdbstr);
-            if (imdbid == null)
-                return null;
-         
-            return "tt" + ((int)imdbid).ToString("D7");
-        }
-    }
+using System.Globalization;
+using System.Text.RegularExpressions;
+using System.Web;
+
+namespace Jackett.Utils
+{
+    public static class ParseUtil
+    {
+        private static readonly Regex InvalidXmlChars =
+            new Regex(
+                @"(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF](?![\uDC00-\uDFFF])|[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F\uFEFF\uFFFE\uFFFF]",
+                RegexOptions.Compiled);
+        private static readonly Regex ImdbId = new Regex(@"^(?:tt)?(\d{1,7})$", RegexOptions.Compiled);
+
+        public static string NormalizeSpace(string s)
+        {
+            return s.Trim();
+        }
+
+        public static string NormalizeMultiSpaces(string s)
+        {
+            return new Regex(@"\s+").Replace(NormalizeSpace(s), " "); ;
+        }
+
+        public static string NormalizeNumber(string s)
+        {
+            var normalized = NormalizeSpace(s);
+            normalized = normalized.Replace("-", "0");
+            normalized = normalized.Replace(",", "");
+            return normalized;
+        }
+
+        public static string RemoveInvalidXmlChars(string text)
+        {
+            return string.IsNullOrEmpty(text) ? "" : InvalidXmlChars.Replace(text, "");
+        }
+
+        public static double CoerceDouble(string str)
+        {
+            return double.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
+        }
+
+        public static float CoerceFloat(string str)
+        {
+            return float.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
+        }
+
+        public static int CoerceInt(string str)
+        {
+            return int.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
+        }
+
+        public static long CoerceLong(string str)
+        {
+            return long.Parse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture);
+        }
+
+        public static bool TryCoerceDouble(string str, out double result)
+        {
+            return double.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+
+        public static bool TryCoerceFloat(string str, out float result)
+        {
+            return float.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+
+        public static bool TryCoerceInt(string str, out int result)
+        {
+            return int.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+
+        public static bool TryCoerceLong(string str, out long result)
+        {
+            return long.TryParse(NormalizeNumber(str), NumberStyles.Any, CultureInfo.InvariantCulture, out result);
+        }
+
+        public static string GetArgumentFromQueryString(string url, string argument)
+        {
+            if (url == null || argument == null)
+                return null;
+            var qsStr = url.Split(new char[] { '?' }, 2)[1];
+            qsStr = qsStr.Split(new char[] { '#' }, 2)[0];
+            var qs = HttpUtility.ParseQueryString(qsStr);
+            return qs.Get(argument);
+        }
+
+        public static long? GetLongFromString(string str)
+        {
+            if (str == null)
+                return null;
+            Regex IdRegEx = new Regex(@"(\d+)", RegexOptions.Compiled);
+            var IdMatch = IdRegEx.Match(str);
+            if (!IdMatch.Success)
+                return null;
+            var Id = IdMatch.Groups[1].Value;
+            return CoerceLong(Id);
+        }
+
+        public static int? GetImdbID(string imdbstr)
+        {
+            if (imdbstr == null)
+                return null;
+            var match = ImdbId.Match(imdbstr);
+            if (!match.Success)
+                return null;
+
+            return int.Parse(match.Groups[1].Value, NumberStyles.Any, CultureInfo.InvariantCulture);
+        }
+
+        public static string GetFullImdbID(string imdbstr)
+        {
+            var imdbid = GetImdbID(imdbstr);
+            if (imdbid == null)
+                return null;
+         
+            return "tt" + ((int)imdbid).ToString("D7");
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/Utils/StringCipher.cs b/src/Jackett/Utils/StringCipher.cs
index 17124f660f0c6c23ee5b102c9bd6f0551bce839e..ea4acd33f094d8a0db4646a1dc862f82b158f24e 100644
--- a/src/Jackett/Utils/StringCipher.cs
+++ b/src/Jackett/Utils/StringCipher.cs
@@ -1,106 +1,106 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Security.Cryptography;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils
-{
-    public static class StringCipher
-    {
-        // This constant is used to determine the keysize of the encryption algorithm in bits.
-        // We divide this by 8 within the code below to get the equivalent number of bytes.
-        private const int Keysize = 256;
-
-        // This constant determines the number of iterations for the password bytes generation function.
-        private const int DerivationIterations = 1000;
-
-        public static string Encrypt(string plainText, string passPhrase)
-        {
-            // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
-            // so that the same Salt and IV values can be used when decrypting.  
-            var saltStringBytes = Generate256BitsOfRandomEntropy();
-            var ivStringBytes = Generate256BitsOfRandomEntropy();
-            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
-            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
-            {
-                var keyBytes = password.GetBytes(Keysize / 8);
-                using (var symmetricKey = new RijndaelManaged())
-                {
-                    symmetricKey.BlockSize = 256;
-                    symmetricKey.Mode = CipherMode.CBC;
-                    symmetricKey.Padding = PaddingMode.PKCS7;
-                    using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
-                    {
-                        using (var memoryStream = new MemoryStream())
-                        {
-                            using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
-                            {
-                                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
-                                cryptoStream.FlushFinalBlock();
-                                // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
-                                var cipherTextBytes = saltStringBytes;
-                                cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
-                                cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
-                                memoryStream.Close();
-                                cryptoStream.Close();
-                                return Convert.ToBase64String(cipherTextBytes);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        public static string Decrypt(string cipherText, string passPhrase)
-        {
-            // Get the complete stream of bytes that represent:
-            // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
-            var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
-            // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
-            var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
-            // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
-            var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
-            // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
-            var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
-
-            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
-            {
-                var keyBytes = password.GetBytes(Keysize / 8);
-                using (var symmetricKey = new RijndaelManaged())
-                {
-                    symmetricKey.BlockSize = 256;
-                    symmetricKey.Mode = CipherMode.CBC;
-                    symmetricKey.Padding = PaddingMode.PKCS7;
-                    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
-                    {
-                        using (var memoryStream = new MemoryStream(cipherTextBytes))
-                        {
-                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
-                            {
-                                var plainTextBytes = new byte[cipherTextBytes.Length];
-                                var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
-                                memoryStream.Close();
-                                cryptoStream.Close();
-                                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-
-        private static byte[] Generate256BitsOfRandomEntropy()
-        {
-            var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
-            using (var rngCsp = new RNGCryptoServiceProvider())
-            {
-                // Fill the array with cryptographically secure random bytes.
-                rngCsp.GetBytes(randomBytes);
-            }
-            return randomBytes;
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Security.Cryptography;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils
+{
+    public static class StringCipher
+    {
+        // This constant is used to determine the keysize of the encryption algorithm in bits.
+        // We divide this by 8 within the code below to get the equivalent number of bytes.
+        private const int Keysize = 256;
+
+        // This constant determines the number of iterations for the password bytes generation function.
+        private const int DerivationIterations = 1000;
+
+        public static string Encrypt(string plainText, string passPhrase)
+        {
+            // Salt and IV is randomly generated each time, but is preprended to encrypted cipher text
+            // so that the same Salt and IV values can be used when decrypting.  
+            var saltStringBytes = Generate256BitsOfRandomEntropy();
+            var ivStringBytes = Generate256BitsOfRandomEntropy();
+            var plainTextBytes = Encoding.UTF8.GetBytes(plainText);
+            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+            {
+                var keyBytes = password.GetBytes(Keysize / 8);
+                using (var symmetricKey = new RijndaelManaged())
+                {
+                    symmetricKey.BlockSize = 256;
+                    symmetricKey.Mode = CipherMode.CBC;
+                    symmetricKey.Padding = PaddingMode.PKCS7;
+                    using (var encryptor = symmetricKey.CreateEncryptor(keyBytes, ivStringBytes))
+                    {
+                        using (var memoryStream = new MemoryStream())
+                        {
+                            using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
+                            {
+                                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
+                                cryptoStream.FlushFinalBlock();
+                                // Create the final bytes as a concatenation of the random salt bytes, the random iv bytes and the cipher bytes.
+                                var cipherTextBytes = saltStringBytes;
+                                cipherTextBytes = cipherTextBytes.Concat(ivStringBytes).ToArray();
+                                cipherTextBytes = cipherTextBytes.Concat(memoryStream.ToArray()).ToArray();
+                                memoryStream.Close();
+                                cryptoStream.Close();
+                                return Convert.ToBase64String(cipherTextBytes);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        public static string Decrypt(string cipherText, string passPhrase)
+        {
+            // Get the complete stream of bytes that represent:
+            // [32 bytes of Salt] + [32 bytes of IV] + [n bytes of CipherText]
+            var cipherTextBytesWithSaltAndIv = Convert.FromBase64String(cipherText);
+            // Get the saltbytes by extracting the first 32 bytes from the supplied cipherText bytes.
+            var saltStringBytes = cipherTextBytesWithSaltAndIv.Take(Keysize / 8).ToArray();
+            // Get the IV bytes by extracting the next 32 bytes from the supplied cipherText bytes.
+            var ivStringBytes = cipherTextBytesWithSaltAndIv.Skip(Keysize / 8).Take(Keysize / 8).ToArray();
+            // Get the actual cipher text bytes by removing the first 64 bytes from the cipherText string.
+            var cipherTextBytes = cipherTextBytesWithSaltAndIv.Skip((Keysize / 8) * 2).Take(cipherTextBytesWithSaltAndIv.Length - ((Keysize / 8) * 2)).ToArray();
+
+            using (var password = new Rfc2898DeriveBytes(passPhrase, saltStringBytes, DerivationIterations))
+            {
+                var keyBytes = password.GetBytes(Keysize / 8);
+                using (var symmetricKey = new RijndaelManaged())
+                {
+                    symmetricKey.BlockSize = 256;
+                    symmetricKey.Mode = CipherMode.CBC;
+                    symmetricKey.Padding = PaddingMode.PKCS7;
+                    using (var decryptor = symmetricKey.CreateDecryptor(keyBytes, ivStringBytes))
+                    {
+                        using (var memoryStream = new MemoryStream(cipherTextBytes))
+                        {
+                            using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
+                            {
+                                var plainTextBytes = new byte[cipherTextBytes.Length];
+                                var decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
+                                memoryStream.Close();
+                                cryptoStream.Close();
+                                return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        private static byte[] Generate256BitsOfRandomEntropy()
+        {
+            var randomBytes = new byte[32]; // 32 Bytes will give us 256 bits.
+            using (var rngCsp = new RNGCryptoServiceProvider())
+            {
+                // Fill the array with cryptographically secure random bytes.
+                rngCsp.GetBytes(randomBytes);
+            }
+            return randomBytes;
+        }
+    }
+}
diff --git a/src/Jackett/Utils/StringUtil.cs b/src/Jackett/Utils/StringUtil.cs
index bd51f24be001305facd8b0d5d947bc75904b218a..ff9d6e959369a870b0cfc3c3a413212f349fd415 100644
--- a/src/Jackett/Utils/StringUtil.cs
+++ b/src/Jackett/Utils/StringUtil.cs
@@ -1,10 +1,10 @@
-using AngleSharp.Dom;
-using AngleSharp.Html;
+using AngleSharp.Dom;
+using AngleSharp.Html;
 using System;
 using System.Collections.Generic;
 using System.Collections.Specialized;
-using System.Globalization;
-using System.IO;
+using System.Globalization;
+using System.IO;
 using System.Linq;
 using System.Net.Http;
 using System.Security.Cryptography;
@@ -30,19 +30,19 @@ namespace Jackett.Utils
         }
 
         // replaces culture specific characters with the corresponding base characters (e.g. è becomes e).
-        public static String RemoveDiacritics(String s)
-        {
-            String normalizedString = s.Normalize(NormalizationForm.FormD);
-            StringBuilder stringBuilder = new StringBuilder();
-
-            for (int i = 0; i < normalizedString.Length; i++)
-            {
-                Char c = normalizedString[i];
-                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
-                    stringBuilder.Append(c);
-            }
-
-            return stringBuilder.ToString();
+        public static String RemoveDiacritics(String s)
+        {
+            String normalizedString = s.Normalize(NormalizationForm.FormD);
+            StringBuilder stringBuilder = new StringBuilder();
+
+            for (int i = 0; i < normalizedString.Length; i++)
+            {
+                Char c = normalizedString[i];
+                if (CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
+                    stringBuilder.Append(c);
+            }
+
+            return stringBuilder.ToString();
         }
 
         public static string FromBase64(string str)
@@ -104,7 +104,7 @@ namespace Jackett.Utils
         }
 
         public static void Add(this ICollection<KeyValuePair<string, string>> collection, string key, string value)
-        {
+        {
             collection.Add(new KeyValuePair<string, string>(key, value));
         }
 
@@ -113,11 +113,11 @@ namespace Jackett.Utils
             if (element == null)
                 return "<NULL>";
 
-            StringBuilder sb = new StringBuilder();
-            StringWriter sw = new StringWriter(sb);
-            var formatter = new PrettyMarkupFormatter();
+            StringBuilder sb = new StringBuilder();
+            StringWriter sw = new StringWriter(sb);
+            var formatter = new PrettyMarkupFormatter();
             element.ToHtml(sw, formatter);
-            return sb.ToString();
+            return sb.ToString();
         }
 
         
diff --git a/src/Jackett/Utils/TorznabCapsUtil.cs b/src/Jackett/Utils/TorznabCapsUtil.cs
index a96dff3d812d30600b1e55894d9db4a9235e4dc0..8cae39fce2a3864abb34081febff7daff1194995 100644
--- a/src/Jackett/Utils/TorznabCapsUtil.cs
+++ b/src/Jackett/Utils/TorznabCapsUtil.cs
@@ -1,94 +1,94 @@
-using Jackett.Models;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils
-{
-    public class TorznabUtil
-    {
-        static Regex reduceSpacesRegex = new Regex("\\s{2,}", RegexOptions.Compiled);
-
-        static Regex findYearRegex = new Regex(@"(?<=\[|\(|\s)(\d{4})(?=\]|\)|\s)", RegexOptions.Compiled);
-
-        public static TorznabCapabilities CreateDefaultTorznabTVCaps()
-        {
-            var caps = new TorznabCapabilities();
-            caps.Categories.AddRange(new[] {
-                TorznabCatType.TV,
-                TorznabCatType.TVSD,
-                TorznabCatType.TVHD
-            });
-            return caps;
-        }
-
-        private static int GetYearFromTitle(string title)
-        {
-            var match = findYearRegex.Match(title);
-            if (match.Success)
-            {
-                var year = ParseUtil.CoerceInt(match.Value);
-                if(year>1850 && year < 2100)
-                {
-                    return year;
-                }
-            }
-
-            return 0;
-        }
-
-        public static IEnumerable<ReleaseInfo> FilterResultsToTitle(IEnumerable<ReleaseInfo> results, string name, int imdbYear)
-        {
-            if (string.IsNullOrWhiteSpace(name))
-                return results;
-
-            name = CleanTitle(name);
-            var filteredResults = new List<ReleaseInfo>();
-            foreach (var result in results)
-            {
-                // don't filter results with IMDBID (will be filtered seperately)
-                if (result.Imdb != null)
-                {
-                    filteredResults.Add(result);
-                    continue;
-                }
-
-                if (result.Title == null)
-                    continue;
-
-                // Match on title
-                if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(CleanTitle(result.Title), name, CompareOptions.IgnoreNonSpace) >= 0)
-                {
-                    // Match on year
-                    var titleYear = GetYearFromTitle(result.Title);
-                    if (imdbYear == 0 || titleYear == 0 || titleYear == imdbYear)
-                    {
-                        filteredResults.Add(result);
-                    }
-                }
-            }
-
-            return filteredResults;
-        }
-
-        public static IEnumerable<ReleaseInfo> FilterResultsToImdb(IEnumerable<ReleaseInfo> results, string imdb)
-        {
-            if (string.IsNullOrWhiteSpace(imdb))
-                return results;
-            // Filter out releases that do have a valid imdb ID, that is not equal to the one we're searching for.
-            return
-                results.Where(
-                    result => !result.Imdb.HasValue || result.Imdb.Value == 0 || ("tt" + result.Imdb.Value.ToString("D7")).Equals(imdb));
-        } 
-
-        private static string CleanTitle(string title)
-        {
-            title = title.Replace(':', ' ').Replace('.', ' ').Replace('-', ' ').Replace('_', ' ').Replace('+', ' ').Replace("'", "").Replace("[", "").Replace("]", "").Replace("(", "").Replace(")", "");
-            return reduceSpacesRegex.Replace(title, " ").ToLowerInvariant();
-        }
-    }
-}
+using Jackett.Models;
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils
+{
+    public class TorznabUtil
+    {
+        static Regex reduceSpacesRegex = new Regex("\\s{2,}", RegexOptions.Compiled);
+
+        static Regex findYearRegex = new Regex(@"(?<=\[|\(|\s)(\d{4})(?=\]|\)|\s)", RegexOptions.Compiled);
+
+        public static TorznabCapabilities CreateDefaultTorznabTVCaps()
+        {
+            var caps = new TorznabCapabilities();
+            caps.Categories.AddRange(new[] {
+                TorznabCatType.TV,
+                TorznabCatType.TVSD,
+                TorznabCatType.TVHD
+            });
+            return caps;
+        }
+
+        private static int GetYearFromTitle(string title)
+        {
+            var match = findYearRegex.Match(title);
+            if (match.Success)
+            {
+                var year = ParseUtil.CoerceInt(match.Value);
+                if(year>1850 && year < 2100)
+                {
+                    return year;
+                }
+            }
+
+            return 0;
+        }
+
+        public static IEnumerable<ReleaseInfo> FilterResultsToTitle(IEnumerable<ReleaseInfo> results, string name, int imdbYear)
+        {
+            if (string.IsNullOrWhiteSpace(name))
+                return results;
+
+            name = CleanTitle(name);
+            var filteredResults = new List<ReleaseInfo>();
+            foreach (var result in results)
+            {
+                // don't filter results with IMDBID (will be filtered seperately)
+                if (result.Imdb != null)
+                {
+                    filteredResults.Add(result);
+                    continue;
+                }
+
+                if (result.Title == null)
+                    continue;
+
+                // Match on title
+                if (CultureInfo.InvariantCulture.CompareInfo.IndexOf(CleanTitle(result.Title), name, CompareOptions.IgnoreNonSpace) >= 0)
+                {
+                    // Match on year
+                    var titleYear = GetYearFromTitle(result.Title);
+                    if (imdbYear == 0 || titleYear == 0 || titleYear == imdbYear)
+                    {
+                        filteredResults.Add(result);
+                    }
+                }
+            }
+
+            return filteredResults;
+        }
+
+        public static IEnumerable<ReleaseInfo> FilterResultsToImdb(IEnumerable<ReleaseInfo> results, string imdb)
+        {
+            if (string.IsNullOrWhiteSpace(imdb))
+                return results;
+            // Filter out releases that do have a valid imdb ID, that is not equal to the one we're searching for.
+            return
+                results.Where(
+                    result => !result.Imdb.HasValue || result.Imdb.Value == 0 || ("tt" + result.Imdb.Value.ToString("D7")).Equals(imdb));
+        } 
+
+        private static string CleanTitle(string title)
+        {
+            title = title.Replace(':', ' ').Replace('.', ' ').Replace('-', ' ').Replace('_', ' ').Replace('+', ' ').Replace("'", "").Replace("[", "").Replace("]", "").Replace("(", "").Replace(")", "");
+            return reduceSpacesRegex.Replace(title, " ").ToLowerInvariant();
+        }
+    }
+}
diff --git a/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs b/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
index 5360a099ba8853e79baf73de7dade040929de81a..60fb557c517bffcf126587c058088f9ac139d6dc 100644
--- a/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
+++ b/src/Jackett/Utils/WebApiRootRedirectMiddleware.cs
@@ -1,42 +1,42 @@
-using Jackett.Services;
-using Microsoft.Owin;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Jackett.Utils
-{
-    public class WebApiRootRedirectMiddleware : OwinMiddleware
-    {
-        public WebApiRootRedirectMiddleware(OwinMiddleware next)
-            : base(next)
-        {
-        }
-
-        public async override Task Invoke(IOwinContext context)
-        {
-            var url = context.Request.Uri;
-            if(context.Request.Path != null && context.Request.Path.HasValue && context.Request.Path.Value.StartsWith(Startup.BasePath))
-            {
-                context.Request.Path = new PathString(context.Request.Path.Value.Substring(Startup.BasePath.Length-1));
-            }
-
-            if (context.Request.Path == null || string.IsNullOrWhiteSpace(context.Request.Path.ToString()) || context.Request.Path.ToString() == "/")
-            {
-                // 301 is the status code of permanent redirect
-                context.Response.StatusCode = 302;
-                var redir = Startup.BasePath + "Admin/Dashboard";
-                Engine.Logger.Info("redirecting to " + redir);
-                context.Response.Headers.Set("Location", redir);
-            }
-            else
-            {
-
-
-                await Next.Invoke(context);
-            }
-        }
-    }
+using Jackett.Services;
+using Microsoft.Owin;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Jackett.Utils
+{
+    public class WebApiRootRedirectMiddleware : OwinMiddleware
+    {
+        public WebApiRootRedirectMiddleware(OwinMiddleware next)
+            : base(next)
+        {
+        }
+
+        public async override Task Invoke(IOwinContext context)
+        {
+            var url = context.Request.Uri;
+            if(context.Request.Path != null && context.Request.Path.HasValue && context.Request.Path.Value.StartsWith(Startup.BasePath))
+            {
+                context.Request.Path = new PathString(context.Request.Path.Value.Substring(Startup.BasePath.Length-1));
+            }
+
+            if (context.Request.Path == null || string.IsNullOrWhiteSpace(context.Request.Path.ToString()) || context.Request.Path.ToString() == "/")
+            {
+                // 301 is the status code of permanent redirect
+                context.Response.StatusCode = 302;
+                var redir = Startup.BasePath + "Admin/Dashboard";
+                Engine.Logger.Info("redirecting to " + redir);
+                context.Response.Headers.Set("Location", redir);
+            }
+            else
+            {
+
+
+                await Next.Invoke(context);
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/Jackett/WebAPIExceptionHandler.cs b/src/Jackett/WebAPIExceptionHandler.cs
index 74c7d085b6da44b12726cac9c1dd9bebfa730b54..9ad6dc6fb5d6280068cbc984d07e69975a7972db 100644
--- a/src/Jackett/WebAPIExceptionHandler.cs
+++ b/src/Jackett/WebAPIExceptionHandler.cs
@@ -6,55 +6,55 @@ using System.Threading;
 using System.Threading.Tasks;
 using System.Web.Http.ExceptionHandling;
 using Jackett.Utils;
-using System.Net.Http;
-using System.Net;
-using System.Web.Http;
-using System.Net.Sockets;
-
+using System.Net.Http;
+using System.Net;
+using System.Web.Http;
+using System.Net.Sockets;
+
 namespace Jackett
 {
-    class WebAPIExceptionHandler : IExceptionHandler
-    {
-        public virtual Task HandleAsync(ExceptionHandlerContext context,
-                                   CancellationToken cancellationToken)
-        {
-            if (!ShouldHandle(context))
-            {
-                return Task.FromResult(0);
-            }
-
-            return HandleAsyncCore(context, cancellationToken);
-        }
-
-        public virtual Task HandleAsyncCore(ExceptionHandlerContext context,
-                                           CancellationToken cancellationToken)
-        {
-            HandleCore(context);
-            return Task.FromResult(0);
-        }
-
-        public virtual void HandleCore(ExceptionHandlerContext context)
-        {
-            // attempt to fix #930
-            if (context.Exception is SocketException)
-            {
-                Engine.Logger.Error("Ignoring unhandled SocketException: " + context.Exception.GetExceptionDetails());
-                return;
-            }
-
-            Engine.Logger.Error("HandleCore(): unhandled exception: " + context.Exception.GetExceptionDetails());
-
-            var resp = new HttpResponseMessage(HttpStatusCode.InternalServerError)
-            {
-                Content = new StringContent(context.Exception.Message),
-                ReasonPhrase = "Jackett_InternalServerError"
-            };
-            throw new HttpResponseException(resp);
-        }
-
-        public virtual bool ShouldHandle(ExceptionHandlerContext context)
-        {
-            return context.ExceptionContext.CatchBlock.IsTopLevel;
-        }
+    class WebAPIExceptionHandler : IExceptionHandler
+    {
+        public virtual Task HandleAsync(ExceptionHandlerContext context,
+                                   CancellationToken cancellationToken)
+        {
+            if (!ShouldHandle(context))
+            {
+                return Task.FromResult(0);
+            }
+
+            return HandleAsyncCore(context, cancellationToken);
+        }
+
+        public virtual Task HandleAsyncCore(ExceptionHandlerContext context,
+                                           CancellationToken cancellationToken)
+        {
+            HandleCore(context);
+            return Task.FromResult(0);
+        }
+
+        public virtual void HandleCore(ExceptionHandlerContext context)
+        {
+            // attempt to fix #930
+            if (context.Exception is SocketException)
+            {
+                Engine.Logger.Error("Ignoring unhandled SocketException: " + context.Exception.GetExceptionDetails());
+                return;
+            }
+
+            Engine.Logger.Error("HandleCore(): unhandled exception: " + context.Exception.GetExceptionDetails());
+
+            var resp = new HttpResponseMessage(HttpStatusCode.InternalServerError)
+            {
+                Content = new StringContent(context.Exception.Message),
+                ReasonPhrase = "Jackett_InternalServerError"
+            };
+            throw new HttpResponseException(resp);
+        }
+
+        public virtual bool ShouldHandle(ExceptionHandlerContext context)
+        {
+            return context.ExceptionContext.CatchBlock.IsTopLevel;
+        }
     }
 }